# Is there a better way to write this jQuery UI effect animation?

I'm writing some code to perform some simple form validation and I would like to display error messages inside the actual relevant textarea by means of a text fadeout/fadein effect.

To achieve this I am using jQquery UI to do the following:

• Step 1: Animate the color to match the background colour
• Step 2: Modify the text to show the error message then fade it in
• Step 3: Fade the error message out, change the text back to its previous content
• Step 4: Fade the text back in
• Step 5: Finally, Focus the textarea and put the cursor at the end

This works fine, however to do this I have had to nest a lot of anonymous function which is something I really don't like to do.

Is there a better way of achieving the same effect?

$textarea.prop("disabled", true).animate({ color: 'rgb(41, 41, 41)'},500, function(){$textarea.text('Please enter your reply here')
.animate({ color: 'white'},500, function(){
$textarea.delay('1000') .animate({ color: 'rgb(41, 41, 41)'},500, function(){$textarea.text(body)
.animate({ color: '#a7a7a7'},500)
.prop("disabled", false)
.focus()
.putCursorAtEnd();
});
});
});
return false;
}
-

## migrated from stackoverflow.comJan 19 '12 at 14:24

This question came from our site for professional and enthusiast programmers.

Pull it out to a function?

$.fn.textFadeSwap = function(newText, body, customColor) { var$this= $(this), transparentColor =$this.css('background-color') || 'transparent',
originalColor = $this.css('color') || '#000', customColor = customColor || '#000';$this.animate({ color: originalColor, 500, function(){
$this.text(newText) .animate({ color: transparentColor},500, function(){$this.delay('1000')
.animate({ color: originalColor},500, function(){
$(this).text(body) .animate({ color: customColor},500) .focus() .putCursorAtEnd(); }); }); }); } if (replyto == body) {$('textarea').textFadeSwap("Please enter your reply here", body, '#a7a7a7')
}
-
Thanks for the quick answer kyle, great answer and a good suggestion, i'll definately do just that. Is there any way to achieve the effect withou the serious nesting however? Or would you say it doesn't matter and is the only way to achieve the effect? – user6595 Jan 19 '12 at 14:31
For what you're working with, the nesting about right... You can kind of hybrid it with the other answer here, if you want. – Kyle Macey Jan 19 '12 at 14:46

You could create a function that will set up the animation of text or color and then just call it a few times to set up your animation:

$.fn.animateIt = function(color, text) { var that =$(this);
if (text) {
that.queue(function(next) {
that.text(text);
next();
});
}
if (color) {
that.animate({
color: color
}, 500);
}
return that;
};

$textarea.animateIt('rgb(41, 41, 41)') .animateIt('#FFF', 'Please enter your reply here') .delay('1000') .animateIt('rgb(41, 41, 41)') .animateIt('#a7a7a7', body) .queue(function(next) {$textarea.focus().putCursorAtEnd();
next();
});

Gets rid of the nested functions.

http://jsfiddle.net/petersendidit/LYsQM/1/

-
Thanks mate thats a great solution... I'm going to use a combination of both answers given. I'm going to leave Kyle with the 'answer' however as he beat you to it. Hope you're okay with that. – user6595 Jan 19 '12 at 14:48
+1 - nesting anonymous functions should be on the top list of antipatterns on the first page of any jQuery tutorial. – Lars-Erik Jan 19 '12 at 15:10