Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fire onblur event before onchange event

I have a large form that contains several text input fields. Essentially, I need to handle the onchange event for all fields and the onblur events for some fields. When a change is made to a field and the field loses focus, both events fire (which is the correct behavior). The only issue is that I would like to handle the onblur event before I handle the onchange event.

After some testing in ie and Firefox, it seems that the default behavior is to fire the onchange event before onblur. I have been using the following code as a test...

<html>

<body >
    <input type="text" value="here is a text field" onchange="console.log('Change Event!')" onblur="console.log('Blur Event!')" >

</body>
</html>

Which brings me to my questions:

  1. It seems that this behavior is consistent across browsers. Why does onchange fire first?

  2. Since I cannot handle the onblur event for every input element, is there a way I can get onblur to fire before handling the onchange event?

like image 482
Joel Avatar asked Aug 13 '13 17:08

Joel


People also ask

What is the difference between onBlur and Onchange?

onChange is when something within a field changes eg, you write something in a text input. onBlur is when you take focus away from a field eg, you were writing in a text input and you have clicked off it.

What can I use instead of Onchange?

All you need to do is use onInput instead of onChange . input. addEventListener('input', yourCallback);<Or>input.

Why is onBlur not fired?

You can add tabIndex={0} to outermost div in order to dismiss keyboard from input. If the element that has the onBlur effect and tabindex is created onClick of another element, it does not automatically gets focus when it appears. Thus, you may need to focus it using element. focus() after creating the element.

What is the difference between onInput and Onchange?

The difference is that the oninput event occurs immediately after the value of an element has changed, while onchange occurs when the element loses focus, after the content has been changed.


2 Answers

  1. The reason onchange fires first is that once the element loses focus (i.e. 'blurs') the change is usually complete (I say usually because a script can still change the element without user interaction).

  2. For those elements that need onblur handled first, you can disable the onchange handler and fire the onchange (or even a custom event) from the onblur handler. This will ensure the correct order even though it is more work. To detect change, you can use a state variable for that field.

As a general remark though, the need for such synchronicity is a sign that the approach you are using to solve whatever problem you are solving might need more work even though sometimes it cannot be avoided. If you are sure this is the only way, try one of these methods!

EDIT: Just to elaborate on the last point, you would have to follow some assumptions about your event model. Are you assuming that each change event is followed by a blur and goes unprocessed otherwise, or would you like to process each change but those that are followed by a blurget further processing after whatever onblur does with them? In any case if you want to enforce the order the handlers would need access to a common resource (global variable, property, etc.). Are there other event types you might want to use? (input?). Finally, this link has some details for the change event for Mozilla browsers: https://developer.mozilla.org/en-US/docs/Web/Reference/Events/change. The third 'bullet' addresses the issue of event order.

like image 199
alexsh Avatar answered Oct 16 '22 19:10

alexsh


This is a bit of hack, but it seems to do the trick on most browsers:

<input type="text" value="Text Input" onchange="setTimeout(function(){console.log('Change Event!')}, 0);" onblur="console.log('Blur Event!');" />

You can see a fiddle of it in action here: http://jsfiddle.net/XpPhE/

Here is a little background information on the setTimeout(function, 0) trick: http://javascript.info/tutorial/events-and-timing-depth

Hope that helps :)

like image 35
Andrew Odri Avatar answered Oct 16 '22 18:10

Andrew Odri