Trevor
Trevor

Reputation: 1137

Can you stop the jQuery focusout from firing when losing focus?

I've got an input box that I want to have save its value when it loses focus.

Pretty straightforward stuff and I'm able to get that done via jQuery's focusout event.

The problem however, is that I want to NOT fire the focusout event when the user clicks on an "X" icon next to the input box (example shown below)

enter image description here

So when the user tabs out of this input box, or clicks outside of the box or they click the green checkbox it should fire the focusout event... but if they click the red "X", it should NOT fire the focusout.

Is this possible to do with JavaScript / jQuery?

EDIT:

Some of you have recommended using event.relatedTarget, but it seems like that's returning null. I'll include my code in question for clarity:

  // This is the cancel button with the red X
  $("body").on("click", "span[id*='Cancel']", function(e)
  {
    showLabel($(this));
  });

  // this is the code to trigger the blur / focusout event
  // trouble is that the "e.relatedTarget" is null
  $("body").on("focusout", "input, textarea", function (e) {
    if($(e.relatedTarget).is("span[id*='Cancel']")){
      return false;
    }

    $(this).siblings("span[id*='OK']").trigger("click");
    return false;
  });

Here's a screen grab of me debugging this in JS (you'll see that the $(e.relatedTarget) selector returns nothing):

enter image description here

Upvotes: 4

Views: 8819

Answers (4)

Ehsan
Ehsan

Reputation: 12959

You must use relatedTarget like this :

$(document).ready(function(){

    $(".btn").on("focusout",function(e){

        if($(e.relatedTarget).hasClass("red")) {
             alert("You clicked on X button");
        }

        else {

            alert("Fire Focus out")
        }

    })
   })

Final code :

<!DOCTYPE html>
<html>
    <head>
        <style>
            .gr {
                color: green;
            }
            .red {
                color: red;
            }
        </style>
    </head>
    <body>
       <input type="text" class="btn"><button class="gr">Ok</button><button class="red">X</button>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>
    $(document).ready(function(){

        $(".btn").on("focusout",function(e){

            if($(e.relatedTarget).hasClass("red")) {
                 alert("You clicked on X button");
            }

            else {

                alert("Fire Focus out")
            }

        })
    })
    </script>
    </body>  
</html>
        

Upvotes: 2

Andrew Ice
Andrew Ice

Reputation: 841

Here, I did the thing.

https://jsfiddle.net/kowmLf2a/1/

In the blur event I target the related target. See if that related target is the item that I don't want to blur with. If it is then return false.

Code for reference:

$('#input').blur(function(event){
  if($(event.relatedTarget).is('#bt2')){
    return false;
  }

  alert($(this).val());
});

Upvotes: 0

Ricardo Pontual
Ricardo Pontual

Reputation: 3757

You can cancel de event returning the focus to previous element.

$('#inputText').focusout(function(event) {
  setTimeout(function(){
       if (document.activeElement.id == "btnCancel") {
            $(event.target).focus();
            return false;
       } 
    },1);
});

This jsFiddle shows how to do it: https://jsfiddle.net/mpervh3t/

Hope it helps

Upvotes: 2

mhodges
mhodges

Reputation: 11116

As per my comment:

"I have had to do a similar type of thing with a blur event. Basically what I had to do was call a setTimeout on the blur to execute my function to save the data, and then on the click event of the X, cancel the timeout. That way, unless the X is clicked, the save function will fire. The delay can be pretty negligable, too."

I found the relevant code

var sliderTimeout = null;
$(".slider-trigger").on("blur", function () {
      sliderTimeout = setTimeout(function () {
          $(".slider").hide();
      }, 100);
  });

$(".ui-slider-handle").on("focus", function () {
      clearTimeout(sliderTimeout);
});

Here is the full demo of the code in action. It does much more than demonstrate this, but if you examine the behavior of focusing/blur on the "margin" input, you will see that if you blur the margin input, the slider hides, but if you click on the slider, it cancels the hide and stays shown. It's the exact same concept, just a slightly different application.

Upvotes: 0

Related Questions