How can I detect when a select box is closed? - javascript

I am using jquery and both blur and focusout functions require an extra click after the select box is closed to fire. Is there another way to detect when the select box is immediately closed?

As #samsquanch and #bfavaretto point out in comments here, there seems to be no way to reliably detect, across the current browser generation, when a select list is closed. Which is mildly mind-boggling, but there you are.

I think you're looking for .change(). This will just after you choose any option.
$('select').on('change', function() {
// code
});
And if you want to trigger a change event on page load just try:
$('select').on('change', function() {
// code
}).change(); // trigger initial change

Related

how to run a jquery function on dropdown selection [duplicate]

This question already has answers here:
Fire event each time a DropDownList item is selected with jQuery
(10 answers)
Is there an onSelect event or equivalent for HTML <select>?
(37 answers)
Closed 8 years ago.
I have a simple dropdown named Filtername. I want to run a function when a value is selected from the list. I have already tried below
$('#FilterName').change(function() {
code1;
code2;
}
The problem is that it works only when selected value gets changed. I want to run the function even if the user selects the same value again from the dropdown. So I need to run the function when the value is selected. I tried .select/.submit functions but they didn't work. Please help.....
From my answer on Fire event each time a DropDownList item is selected with jQuery:
A lot of the current solutions will break in a lot of situations. Any solution that relies on checking the click count twice will be very fickle.
Some scenarios to consider:
If you click on, then off, then back on, it will count both clicks and fire.
In firefox, you can open the menu with a single mouse click and drag to the chosen option without ever lifting up your mouse.
If you use any combination of keyboard strokes you are likely to get the click counter out of sync or miss the change event altogether.
You can open the dropdown with Alt+↕ (or the Spacebar in Chrome and Opera).
When the dropdown has focus, any of the arrow keys will change the selection
When the dropdown menu is open, clicking Tab or Enter will make a selection
Here's a more comprehensive extension:
The most robust way to see if an option was selected is to use the change event, which you can handle with jQuery's .change() handler.
The only remaining thing to do is determine if the original element was selected again.
This has been asked a lot (one, two, three) without a great answer in any situation.
The simplest thing to do would be to check to see if there was a click or keyup event on the option:selected element BUT Chrome, IE, and safari don't seem to support events on option elements, even though they are in the w3c recommendation
Inside the Select element seems to be a black box. If you listen to events on it, you can't even tell on which element the event occurred or whether the list was open or not.
The next best thing then, seems to handle the blur event. This will indicate that the user has focused on the dropdown (perhaps seen the list, perhaps not) and made a decision that they would like to stick with the original value. To continue handling changes right away we'll still subscribe to the change event. And to ensure we don't double count, we'll set a flag if the change event was raised so we don't fire back twice:
Code:
(function ($) {
$.fn.selected = function (fn) {
return this.each(function () {
$(this).focus(function () {
this.dataChanged = false;
}).change(function () {
this.dataChanged = true;
fn(this);
}).blur(function (e) {
if (!this.dataChanged) {
fn(this);
}
});
});
};
})(jQuery);
Then call like this:
$("#dropdownid").selected(function (e) {
alert('You selected ' + $(e).val());
});
Updated example in jsFiddle

Keeping a text field in focus

I thought this would be easy enough to do without seeking help, but I guess not. Adding the autofocus="true" tag works when the page initially loads but the text field loses focus if anyone clicks anywhere or opens a link. How do I force the field to keep focus?
Someone ask why you want to do that .
the answer of-course is as a developers we need to deal we crazy demands by our clients :)
To the answer:
$(document).ready(function(){
$(document).click(function() { $("<THE-ELEMENT>").focus() });
});
In this case we add listener to all elements in the document :)
Attach a click event listener on the document that focus's on the input box on click.
$(document).on("click", function()
{
$("yourInputIdHERE").focus();
}
$("#textbox").focus().on('blur', function() {
$(this).focus();
});
Handling all cases incase where some of the events are prevented from propagating till the document. Also handle the case where user switches tab and comes back.
$("#element").blur(function ()
{
$("#element").focus();
});
$(document).bind('keydown mousedown mouseup click',function ()
{
$("#element").focus();
});
What you might want to try do, is attach an event handler to the blur event. Once you capture it, you can simply trigger a focus event on the same element that lost focus in the first place.
$("input").on('blur',function(){
$(this).focus();
});
You might want to incorporate this with some form of validation so that once the user has entered the desired value, they will be able to leave the text field.
$("input").on('blur',function(){
var $this = $(this);
if ($this.val() == ''){
$this.focus();
showErrorMessage("Please enter a value");
}
});
If you don't implement some form of flag to enable/disable this behavior, you'll be locking the user into one field forever. There will be no (easy) way for them to move to a different area of the page.
Here is a small demo,
you'll notice that once the text field has focus, it will keep it until a value has been entered.

Change style of jQuery Dialog title bar when got/lost focus

I'm trying to make a simple page with two jQuery Dialogs with the functionality of changing their titlebar colour when each gets or losts focus. In other words, focused window has a different titlebar colour which makes it easier to differ which has focus.
I have this code:
$(function () {
$(".window").dialog({
focus: function (event, ui) {
$(this).parents(".ui-dialog:first").find(".ui-dialog-titlebar").addClass("ui-state-error");
}
});
but I don't know how to detect in the focus event whether it it gets or losts focus.
Try this
http://jsfiddle.net/JqQA6/
I needed the same and this solution works.
Try focusin() and focusout()
The dialog focus event is only called on gaining focus. Stock jQuery UI dialog boxes have no concept of losing focus.
A simple solution is to simply remove your ui-state-error class from every dialog in the focus handler and then add it to the one that's just received focus.
I've actually written a full-featured jQuery UI plugin which adds a .blur event to dialog boxes, and handles re-ordering stacked boxes whenever the topmost box is closed. I'll check if I'm allowed to publish it.

Is there a DOM event that fires when an HTML select element is closed?

I'm looking for a DOM event that I can listen to with JavaScript for when a select element that has been opened (but no options changed) is then closed by clicking off the select element, somewhere (anywhere) else on the page.
It's not the blur event of the select, because the select retains focus. Likewise, it's not the focus event of some other element or the document, or a mousedown or click on the window, document or body.
It's not the change event of the select, since no option within the select has been changed.
I'm not concerned about legacy Internet Explorers - just something to work in standards compliant modern browsers. Proprietary hacks could be worth knowing though.
I've created a JSFiddle to demonstrate the problem: http://jsfiddle.net/premasagar/FpfnM/
Click on the selectbox in the "Result" panel
Click on the text marked "HERE" (or anywhere else) with a single click and see if any event is added to the log. There isn't an event in the latest Chrome or Firefox.
So the question is: What JavaScript could be added, to get an event logged when clicking off the selectbox?
(I've asked a similar, but different question here:
JavaScript on iOS: opening an HTML select element)
Unfortunately there's no standard event for knowing when a select box is closed or open, so your code is going to be pretty hairy with accommodations for different browsers. That said, I think it can be done, and I've gotten something working for you in Firefox using the mouseup event:
http://jsfiddle.net/FpfnM/50/
In Firefox (and I'm assuming Chrome), you're going to need to track the state of that select pretty carefully. When an escape key is pressed or blur event occurs, you need to update the state to identify it as closed. I haven't implemented that in my demo, and you can see what happens if you hit escape instead of clicking off the select.
Things were easier in Safari, where a mousedown event on the select signifies opening the select, and any close of the select is signified by a click event.
If you find a browser where none of these events fire, you can try one additional trick. Because form widgets like select and textarea are often rendered by the OS and not inside the browser it's possible that you could interact with them and certain messages might not get down to the browser's event handler. If you were to position a transparent textarea covering the screen at a lower z-index when the select box is open, you might be able to use it to track that close click. It may be able to capture events that a browser DOM element may miss.
Update:
Chrome sees a mousedown on the select when it opens and a mouseup on the document when the page is clicked with a select open. Here's a version that works with Chrome:
http://jsfiddle.net/FpfnM/51/
Again, you'll need to do some browser detection to handle the right behavior in each one. One catch with Chrome, in particular, is that no event is fired when you click on the select a second time to close it. You can detect the page click, however.
Quick Summary:
Chrome/Safari: select.mousedown on open, document.mouseup on close
Firefox: select.click on open, document.mouseup on close
IE8/IE7: select.click on open, document.mouseup on close
There are an awful lot of edge cases for other events that will signify a close (escape keypress, blur, etc.), but these are the minimum to handle the scenario where a user clicks the select box and then clicks off into the document area.
Hope this helps!
When you have more then 1 dropdown:
$("select").each(function () {
var initDropdown = $(this);
initDropdown.data("open", false);
console.log(this.name + " closed");
initDropdown.on("blur", function () {
var blurDdopdown = $(this);
blurDdopdown.data("open", false);
console.log(this.name + " closed");
});
});
$("select").bind("click", function () {
var clickedDropdown = $(this);
if (clickedDropdown.data('open') == false) {
clickedDropdown.data('open', true);
console.log(this.name + " open");
} else {
clickedDropdown.data('open', false);
console.log(this.name + " closed");
}
});
If we consider clicking outside the selection box can be a signal of the ending selection event.
The following jQuery can do this. Here is code in fiddle
$(function () {
let flag = 0;
$("#selectId").click(function (e) {
e.stopPropagation();
if (flag === 0) {
flag = 1;
$(document).one("click", function () {
flag = 0;
alert("select end");
});
}
});
});
Html code:
<select multiple id="selectId">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
I got the following events by following the directions on your JSFiddle to the letter:
BODY, mousedown, STRONG
#document, mousedown, STRONG
window, mousedown, STRONG
SELECT, blur, SELECT
BODY, click, STRONG
#document, click, STRONG
window, click, STRONG
These are all events that were triggered when I clicked "HERE" after the select menu was already in focus and expanded. This was in the latest version of Chrome.
Shouldn't any one of these suffice for your purposes?
Edit: If you want to make sure it's your Select element that's losing focus, set a global Javascript variable, 'selectFocused', and set it to False. Set it to True when your Select menu receives focus, and set it to False when any of the above events occurs. 'selectFocused' can now be used anywhere in your code to detect whether or not your Select element currently has focus, and when it changes values, you know your Select element has been selected or unselected.
My first instinct is a little roundabout in its way to achieve this, it would be to use the code you normally use for closing a (custom) dropdown menu on press outside:
function clickInBody(){
functionToCallOnBlur();
}
function clickInBodyStop(event){
event.stopPropagation();
}
Then on your body tag you add onClick="clickInBody()" and on your select item you add onClick="clickInBodyStop(event)". This should call the event every time you click on the page, but if you click on the select tag it will stop the propagation and not call functionToCallOnBlur()
precondition: using jQuery! This will probably only solve part of your problem, but if you are looking for an event to fire when you click off an element, you can use an overlay div.
When the user clicks on the select box:
$('#mySelectBox').click(function () {
var myOverlayDiv = $('<div id="overlayDiv" class="overlayDiv"></div>')
.click(function () {
// call your "select lost focus" function here
// which should include $('#overlayDiv').remove() somewhere!
})
.show()
.appendTo(document.body);
});
Style for the overlay div:
.overlayDiv {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
opacity:0;
z-index:1000;
}
You need to make sure that your select box menu is a higher Z-index so when the user clicks on the menu they get the menu and not the overlay div :)
The answer is "YES", there is such an event and that is called blur event. It's very general and depends on the html element.
In the case of an HTMLSelectElement, blur is called when you exit focused state on the element, meaning you've closed it.
And the same can be said with focus that it can be assumed as a substitute for an 'open' state of the HTMLSelectElement element.
Here's an example on doing something callback when you close the HTMLSelectElementelement:
var select= document.getElementById("mySelect");
function doSomethingOnBlur(event){
console.log("Yey! The select options were closed.");
}
select.addEventListener("blur", doSomethingOnBlur);
<select id="mySelect">
<option selected hidden></option>
<option>Some Item</option>
</select>
It's important to note that the options are rendered based on the state of the select. When you focus on it, it opens. And when you lose focus (blur) then it's closed. So technically, it's just a choice of words...

Browser detection - checkbox change events

I'm creating a form with some fancy interactivity which depends on the change event of radio buttons. As ie doesn't trigger this event until another element is focused I need to branch my code, but want to go down the feature detection rather than browser detection route.
Looking at a few resources (http://api.jquery.com/jQuery.support/, http://kangax.github.com/cft/) I can't find any implementation of detecting ie's buggy radio/checkbox change events.
Does anyone know how I might be able to detect it?
In my experience, click and keyup are the only event to trust in this case.
(function () {
$('#yourRadio').bind('click keyup', function () {
// check value with $(this).val()
});
}());

Categories