8

TL;DR how can I get this self-explanatory JSFiddle to work?

From the W3C:

The blur event occurs when an element loses focus either via the pointing device or by tabbing navigation. This event is valid for the following elements: LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.

The basic idea, HTML:

<form>
    <label>
        <input type="text" />
        <a href="#">after focusing in input, there should be no blur when clicking here</a>
    </label>
</form>
<a href="#">but blur should fire when clicking here</a>

And JS:

$("form, label").on("blur", function() {
    alert("you're not going to see this");
});

It doesn't work. A more illustrative example is in this JSFiddle.

I also tried focusout, with this JSFiddle, but (presumably because it bubbles up from the input), it always fires.

I could probably rig up what I need with a hack like this: https://stackoverflow.com/a/5049387/458614 but I'd rather not have to.


Edit: There are lots of related questions and I have read all that I could find, none of which help. Some talk about setting tabindex=0 on the form or label elements. I have tried this in various permutations but it doesn't help. JSFiddle here. If you put it on the form, blur events do fire when you click outside the form. However, it doesn't apply to any of it's children: it won't pick up anything if you click on the input and then outside the form.


Edit 2: I don't really understand some of the answers posted so far and none seem to really... work. Anyway, to clarify, here is what I am trying to accomplish:

In my app, you can add tags to documents. When you click the "add tag" button, a previously-hidden text input field pops up and is focused. And then...

  1. Clicking outside (on blur) should close the text input field again
  2. Pressing enter should add the tag and close the input field
  3. Clicking the "add tag" button should also add the tag and close the input field

The problem is that #1 and #3 are incompatible. The "add tag" button needs to perform a different action based on whether the text field is open or closed, but because I can only achieve #1 with an onblur event on the text field, the text field is closed by the time any action happens on the "add tag" button for #3.

Here is a JSFiddle with my best attempt so far.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
tobek
  • 4,349
  • 3
  • 32
  • 41
  • Have you been able to fire a label's `focus` event? I can't even seem to do that. Sidenote: That doesn't look like the right way of using a `label`. It's usually ` – tewathia Dec 29 '13 at 07:30
  • Yeah I can't get that to fire either. I'm pretty sure you can use `label` in one of two ways: either specifying what it's for with the `for` attribute, or wrapping the element around what it's the label for. – tobek Dec 29 '13 at 07:37
  • Well, it seems to work in this way too, but only if I remove the `a` tag. See http://jsfiddle.net/tewathia/D6kSE/4/ – tewathia Dec 29 '13 at 07:40

7 Answers7

1

The thing I think you are looking for is

e.stopPropagation();

This Fiddle here shows a little different way to handle it ... it put the hide on a window click (which would blur the input anyways) except on the label, which it would allow the click event to stop inside the label.

Happy coding!

Michael
  • 83
  • 4
  • Ugh haha how did I forget about `stopPropagation`. You totally got it, thanks! – tobek Aug 09 '14 at 05:34
  • I guess the key insight is not having the event fire on blur (which is hard to control) but instead having it fire on `window` click, which means you can stop propagation from wherever you need. – tobek Dec 08 '14 at 04:37
  • Unfortunately this doesn't work well when developing a solution with components. It causes a dependency on window. – jecxjo Mar 29 '23 at 15:52
0

use the below code to achieve the desired

  $(document).on("blur", "label",function() {
       $("div").append("form or label blurred<br>");
   });

Here is the demo Fiddle

Gourav
  • 1,765
  • 2
  • 15
  • 16
  • Cool, that does get the blur to fire from the label, but it also seems to fire erroneously. Try clicking on the input and then on the first link "how do I distinguish..." - it still fires even though we've clicked on the label, so it shouldn't have blurred. – tobek Dec 29 '13 at 07:36
0

Try this it should work

.focus {
border-color:red;
}


$(document).ready(function() {    

    $('input').blur(function(){
            $('input').removeClass("focus");
        })
             .focus(function() {        
                 $(this).addClass("focus")
        });

});
shiny
  • 124
  • 6
0

Add this piece of js in your Fiddle. you added listener for label but blur happens on anchor tag.

      $("form a").on("blur", function() {
              $("div").append("form or label blurred<br>");
       });
Gourav
  • 1,765
  • 2
  • 15
  • 16
venkat7668
  • 2,657
  • 1
  • 22
  • 26
0

according to your explanation i have create a demo

$("form > label >a").on("blur", function() {
      return false
});

    $("#outsideform > a").on("blur", function() {
    alert("but blur should fire when clicking here");
});

Check the Demo here

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
user2509485
  • 219
  • 2
  • 5
0

For a while, I am posting an intermediate development. But this definitely will help you where exactly you should look for. The jquery implementation but not your javascript. This is the real concern.

I have added 3 lines at different places. no big changes.

  1. Added an || $("input").css("visibility") == "visible" to the if condition
  2. Added $("input").css("visibility","hidden"); to the inner else condition
  3. $("input").css("visibility","visible"); to the outer (and last) else condition.

Please note this is intermediate, you need to click twice after a submit of non-empty text. If I get time, I would post the correct working thing. This is the fiddle.

Siva Tumma
  • 1,695
  • 12
  • 23
0

tobek, your JSFiddle with my best attempt so far is almost there. The problem is your selector at the bottom in this section of code:

$("input").on("blur", function(){
    $("input").hide();
});

You stated the problem correctly in your comments when you said: "THE PROBLEM: we never get in here because it's already been hidden because the input blurred".

Change the above section to this and I think you'll have what you're looking for.

$("input-blur label").on("blur", function(){
    $("input").hide();
});

Because the "Add tag" link is inside the label clicking it doesn't trigger your "blur" function.

runninbare
  • 34
  • 2