Problem
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?
if (replyto == body) {
$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;
}
Solution
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')
}
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.