.focus() event behavior with Javascript - javascript

I have these three tabs:
When a user uses the mouse and clicks on one of the tabs, (Compliance Notes in this example), the proper element on the tabbed page gets focus and is highlighted appropriately.
However, if the user uses the keyboard and presses the Tab key to highlight the tab they want, and then presses the Enter key to select that tab, the tabbed page gets focus. Then, via JavaScript, I set focus to the proper element on that tabbed page (by using the .focus() method on that element), and the same asp:DropDownList in the example behaves like the user not only selected the element, but clicked on it:
If you then either hit Enter or Tab, manually, the dropdown list closes and the element looks like it did if the user clicked on the tab versus using the keyboard:
So, is there a "simple" way, after I use the .focus() method, to then simulate either an Enter or Tab keystroke so the element will have focus but not have the dropdown list triggered? Or is there another way, using the .focus() method or some other approach, to prevent the dropdown list from being triggered when using the keyboard to navigate the page?

The behavior you are mentioning seems to be related to the keydown event.
Here's an example - when you type in the text field it should set focus on the dropdown. When you press enter in the text field, notice that the first example (using keydown) behaves similarly to what you reported. The second example (using keypress) does not.
document.querySelector('#typeHere').addEventListener("keydown", (e) => {
document.querySelector('#focusMe').focus();
});
document.querySelector('#typeHere2').addEventListener("keypress", (e) => {
document.querySelector('#focusMe2').focus();
});
<select id='focusMe'>
<option>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>
<input id='typeHere' >
<br><br>
<select id='focusMe2'>
<option>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>
<input id='typeHere2'>

Related

Responding to Onclick in a <select> HTML Element

I have created a select element drop down list in HTML. The select tag has three options. An "onclick" JS event is attached to the select tag. In JavaScript, I have a matching function that alerts the user if and only if the first option has been selected. Here is a JSFiddle with my code.
https://jsfiddle.net/TempusF/rad11vgx/12/
The problem I am having is that, on Firefox for mac, this alert will only be displayed if you first select a different option. That is to say, if the page loads and "Zone 1" is displayed, clicking Zone 1 a second time will not trigger the alert. You must click to Zone 2 or Zone 3, and then click back to Zone 1 to get the alert.
However, on Firefox for Windows, any click on the Zone 1 option will display the alert.
This leads me to believe that I am incorrectly using the onclick event when a different event is more idiomatic. Perhaps the expectation is that I have a button below the select element that triggers the alert function, thus deferring execution. However, I would like to create an interface that reacts immediately when a select option has been chosen.
Here is the HTML:
<select id="zoneSelect" onclick="updateChar();">
<option value="zone1">Zone 1</option>
<option value="zone2">Zone 2</option>
<option value="zone3">Zone 3</option>
</select>
Here is the ecmascript.
function updateChar() {
var zone = document.getElementById("zoneSelect");
if (zone.value == "zone1"){
alert("You clicked Zone 1.");
}
}
You shouldn’t use onclick in modern html, but you might try the following:
onchange="updateChar();"
Better still, you should set the event handler in the startup code. In any case, it’s still the change event.
Also, I recommend that a drop-down menu begin with a harmless null value, so that you don’t default to the first value — unless, of course, that is the intention:
<option value="">Choose one …</option>
Edit
Apropos by comment that you shouldn’t use inline event handlers in modern JavaScript, here is how you would do it today:
In HTML:
<select id="zoneSelect">
<!-- options-->
</select>
In JavaScript:
document.addEventListener("DOMContentLoaded",init);
function init() {
document.querySelector('select#zoneSelect').addEventListener('click')=updateChar;
}
Better still, if the select element is part of a form, then it should have a name attribute, and you wouldn’t need an id attribute. In JavaScript, you can refer to it as:
document.querySelector('select[name="…"]')
and ditto for any CSS you might apply.

Dropdown menu not anchored below field

I've the following, very basic code:
<select id="dir">
<option value="N">N</option>
<option value="S">S</option>
<option value="E">E</option>
<option value="W">W</option>
</select>
My system displays HTML using IE. In the displayed page:
On loading the page, the initial value displayed in the field is N.
I click the field. The dropdown menu appears with the N option hovering over the field. The S, E & W options are below the field.
I click S. The dropdown menu disappears, and the value displayed in the field is now S.
I click the field again. The dropdown menu appears with the S option hovering over the field. The N option is above the field, while the E & W options remain below the field.
This is not how I expected dropdown menus to display. How do I change the code such that the entire dropdown menu is below the field whenever it's displayed, neither partially hovering over the field nor above it?
This is the normal behaviour of a dropdown select.
If you want it otherwise you'd have to either build it yourself in javascript/jquery or look for a jquery plugin.
You'd have to remove the select options above the selected one and add them afterwards again. You could use the onchange handler for that.
As said - this is the normal behaviour, even though it isn't expected by you.

Alternative to onblur/onchange in select

I am trying to find a way to run a JavaScript function when a user selects an option in an HTML select box, regardless of whether this option was already selected. So onchange is out of the question.
The problem with using onblur is that (in Chrome and Safari, at least) the event is not triggered until the user clicks another element. This can also prove annoying if the user focuses on the select, then clicks away without choosing an option, in which case I do not want the event to be triggered.
I was able to get some success by giving each of the options an onmouseup handler, but this only works in Firefox, as far as I can tell. Any ideas?
Since nobody has bothered to answer this, I'll post a generic version of my code:
<select id="mySelect" onfocus="this.selectedIndex=0;" onchange="userDidSomething(event)">
<option>Choose one:</option>
<option>Option 1</option>
<option>Option 2</option>
</select>
The JavaScript:
function userDidSomething(event) {
// Your Code Here.
}
Try using
var s = document.getElementById("mySelect");
s.attachEvent("onchange", function() {
// function here
});

jQuery: How to cancel blur event if the element that will receive focus is a particular type?

I'm writing a custom form UI and currently building a select box replacement. The custom select control is basically a div with a hidden (off screen) select input in it, along with a span containing anchor elements mirroring the options of the select input:
<span class="input select">
<span id="select-select1" class="select-input"><span><span>This is the second option <a class="button" href="#"></a></span></span></span>
<span id="select-select1-options" class="select-options">
<a value="1" href="#"><span>This is the first option</span></a>
<a value="2" href="#"><span>This is the second option</span></a>
<a value="3" href="#"><span>This is the third option</span></a>
</span>
<select name="select1" id="select1" tabindex="2">
<option value="1">This is the first option</option>
<option value="2">This is the second option</option>
<option selected="selected" value="3">This is the third option</option>
</select>
</span>
When the user tabs to the field or clicks it, they actually give focus to the hidden select; the parent span then gets highlighted (with the addition of a CSS class) so that they can see which field has focus.
$('.input select').bind('focus', function() {
$(this).closest('.input').addClass('focused');
}).bind('blur', function(e) {
$(this).closest('.input').removeClass('focused');
});
However, here's what's happening:
User clicks the custom select. The span is highlighted to show it has focus, and the option anchors appear.
User clicks an option, and the option anchors are hidden again. But because the clicked option is an anchor, it then receives focus and the main select highlight disappears, when it should stay (because we still want the select to have focus).
So what I'm trying to achieve is that when one of the anchors in the custom select control is clicked, it doesn't fire the blur event on the hidden select input.
What's the best way to do this?
P.S. Sorry if this is a little confusing, it's quite difficult to explain clearly!
I'm actually building a custom selectbox replacement as well as I find all the current solutions to be lacking. You can try e.preventDefault() to see if that cancels the blur event, but my preferred method is to just give focus back to the select if an anchor is clicked, with $(this).closest('input').focus();
Also, is there a reason you are giving focus to the hidden select? You can allow your span to capture focus (and respond to tabbing) by setting its tabindex:
$('.input').attr("tabindex", $('.input select').attr("tabindex") || "0");
And then prevent the hidden input from capturing focus by hiding it fully:
$('.input select').hide();

Selecting an item in an HTML SELECT list using keyboard doesnt trigger the CLICK event

I have an HTML select list which, when an item is selected, must show different information beneath it. The onclick or JQuery change events are triggered when a select list item is selected by being clicked on (mouse), but not when the user uses key presses (keyboard).
Any idea what event to watch in order to determine when the selected list item has changed?
Here is a BASIC test example:
<select id="mylist" name="mylist">
<option value="">(none)</option>
<option value="1">Test 1</option>
<option value="2">Test 2</option>
<option value="3">Test 3</option>
</select>
<span id="myspan"></span>
<script type="text/javascript">
$("#mylist").change(function() {
$("#myspan").html($("#mylist").attr("selectedIndex"));
});
</script>
The code will run when the select box loses focus
(press tab or click anywhere outside of the select box)
The OnChange event is different from browser to browser when an item is changed with keyboard shortcuts.
For example, in IE, the event is fired the same way with the keyboard and the mouse, but in Firefox, to trigger the event with the keyboard, you need to press enter when the item selected is the good one. The event is also fired when the <select> loose focus (OnBlur - and only if OnChange has not already been fired) as Gaby pointed out.
It the way it's made...
It works if you change add attribute:
multiple="multiple"
if you want the dropbox, I'd bind a 'global' keyup event handler to the document.body
and do some magic there.

Categories

Resources