Reputation: 20592
Using jQuery 1.6.1, given I have the following HTML:
<div class="control">
<label>My Control</label>
<input type="text" />
<input type="text" />
</div>
When an <input>
in <div class="control">
(hereafter only control
) is focused, the <label>
(with position: relative;
) animates:
$('.control :input').bind('focus', function(e){
$(this).prevAll('label').animate({
'left': '-50px'
}, 250);
});
And when blurred, the <label>
returns:
.bind('blur', function(e){
$(this).prevAll('label').animate({
'left': '0px'
}, 250);
});
However, if one of the <input>
elements gains focus, and then blurs as focus is switched to another <input>
within the same control
(via Tab or mouse click) the events of course still fire, and the <label>
animates back and forth.
How can I force the blur event to trigger only when focus is lost from all inputs within a given control
?
Upvotes: 2
Views: 1127
Reputation: 4461
In blur
callback you can detect if any input element is focused now using this $("input:focus").length
. If length>0
than do not animation
Update
What about this code?
var control;
var inTheSameControl=false;
$('.control :input').bind('focus', function(e){
if(control)
{
if(control.find(this).length>0)
inTheSameControl=true;
else
inTheSameControl=false;
}
control=$(this).parent();
if(!inTheSameControl)
{
console.log('focus');
}
});
$('.control :input').bind('blur', function(e){
if(!inTheSameControl)
{
console.log('blur');
}
});
It works with multiple div.control
When you are switching focus to the input
in another .contor
, text 'focus' logs into console, if you are staying in the same .control
- doesn't.
Instead of console.log(...)
you may write what you want. I haven't written your code(animation) because it is not the subject.
I hope it will be helpfull.
Upvotes: 1
Reputation: 82893
Edit: Updated the answer based on more inputs provided by the OP.
If a slight delay of one second to hide the label is fine then you can use setTimeout/clearTimeout combination.. Something like:
<div class="control">
<label>My Control</label>
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<div class="control">
<label>My Control</label>
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<div class="control">
<label>My Control</label>
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<div class="control">
<label>My Control</label>
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<script type="text/javascript">
var timeoutIds = [];
$('.control').each(function(index, el){
$(':input', el).bind('focus', function(e){
clearTimeout(timeoutIds[index]);
$(this).prevAll('label').animate({
'left': '-50px'
});
});
$(':input', el).bind('blur', function(e){
var that = this;
timeoutIds[index] = setTimeout(function(){
$(that).prevAll('label').animate({
'left': '0px'
});
}, 500);
});
});
</script>
Working example: http://jsfiddle.net/Tn9sV/2/
Upvotes: 1
Reputation: 7297
Two options I can think of:
Option 1 (using current scheme):
blur: .delay your animation by a fraction of a second
focus: .stop your existing animation
Option 2 (change blur item):
Upvotes: 0
Reputation: 15390
I have achieved something similar in the past by binding a new focus to the document or to the form instead and having that trigger the label to come back, instead of binding a blur to the inputs.
Upvotes: 1
Reputation: 19315
In your blur callback I would look at something like the :focus
selector that was introduced in 1.6:
Using jQuery to test if an input has focus
If $('.control :focus).length > 0
then return
the function to stop it from running.
Upvotes: 1