How do I select an option in the selected.js dropdown menu using the tab key?
Good,
I've tried many different things, but I can't figure out how to get the tab key to select the selected option after typing in a search. The enter key works really well.
I would show that I've tried, but I honestly don't know where to start.
Here's some sample code:
<html>
<head>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.6.4.js'></script>
<script type='text/javascript' src="http://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<link rel="stylesheet" type="text/css" href="http://harvesthq.github.io/chosen/chosen.css">
</head>
<body>
<select id="chosen_example" style="width: 200px;" multiple="multiple">
<option value="1">A English Test A</option>
<option value="1">B German Test B</option>
<option value="1">C Greek Test C</option>
</select>
<script>
$(document).ready(function () {
var chosen_control = $('#chosen_example');
chosen_control.chosen().keydown(function (e, obj) {
//it not getting in here
console.log('key pressed');
if (e.which == 9) {
console.log('tab key pressed');
//not sure what to do at this point
}
});
});
</script>
</body>
</html>
I've tried it .chosen().bind(...)
. I have tried $('#chosen_example').bind(...)
and a few more things
Here is the JS Fiddle that comes with it.
If you need more information please comment on any help or guidance.
Edit - Solution
Based on the answers I received, one of the Wondercricket led me in the right direction.
After modifying the main js file choosen.jquery.js
, I added in the case 9
following:
if (this.results_showing) {
this.result_select(evt);
}
this.mouse_on_container = false;
break;
I added it as Chosen.prototype.keydown_checker
well as toAbstractChosen.prototype.keyup_checker
source to share
This is a pretty interesting thing, as it only works for selecting one choice, but it doesn't work for selecting multiple favorites.
I was able to get the options tab-selectable with multi-select, but it required very little change to the chosen.js
script.
After diving into a file chosen.js
on my local machine, I saw that there was already written functionality to handle the functions keydown
, depending on the following:
Chosen.prototype.keydown_checker = function (evt) {
var stroke, _ref1;
stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
this.search_field_scale();
if (stroke !== 8 && this.pending_backstroke) {
this.clear_backstroke();
}
switch (stroke) {
case 8:
this.backstroke_length = this.search_field.val().length;
break;
case 9:
if (this.results_showing && !this.is_multiple) {
this.result_select(evt);
}
this.mouse_on_container = false;
break;
case 13:
if (this.results_showing) {
evt.preventDefault();
}
break;
case 32:
if (this.disable_search) {
evt.preventDefault();
}
break;
case 38:
evt.preventDefault();
this.keyup_arrow();
break;
case 40:
evt.preventDefault();
this.keydown_arrow();
break;
}
};
Being tab key 9, there is already functionality to handle it; however, it contains logic that prevents you from doing what you want.
If you want to tab-select an option when using multiple selection, remove the condition !this.is_multiple
in the statement if
.
case 9:
if (this.results_showing) {
this.result_select(evt);
}
this.mouse_on_container = false;
break;
source to share
Answer and demo
There is no easy way to do this, but I made it work , I updated the JSFiddle to demonstrate the effect.
Html
<select id="chosen_example" style="width: 200px;" multiple="multiple">
<option value="1">A English Test A</option>
<option value="1">B German Test B</option>
<option value="1">C Greek Test C</option>
</select>
Same as your initial markup :)
##JavaScript##
var selector = "#chosen_example";
var chosen_control = $(selector);
chosen_control.chosen();
var chosen_element = $(selector + "_chosen");
var chosen_input = chosen_element.find("input");
chosen_input.keydown(function (e) {
if (e.which == 9) {
e.preventDefault();
var chosen_option = chosen_element.find("div > ul > li");
var chosen_index = chosen_option.attr( "data-option-array-index" );
var index = parseInt( chosen_index ) + 1;
var chosen_control_option = chosen_control.find("option:nth-child(" + index + ")");
chosen_control_option.prop( "selected" , true );
chosen_control.trigger('chosen:updated');
}
});
This is where the magic happens.
Description
Variables
- selector : your controller selector (preferably an id, not tested with anything else)
- selected_control :
JQuery object
containing your selection. - selected_element :
JQuery object
containing the plugin containerdiv
. - selected_input :
JQuery object
containing the plugininput
. (Where do you actually type) - selected_option :
JQuery object
containing the current option displayed in the plugin containerdiv
. - selected_index :
string
containing the index of the specified option according todata-option-array-index
. Be aware that this index starts at zero and the index of the index starts at 1. - index : the index of the options, equivalent to the selected index + 1.
- selected_control_option . The actual option in the select element at the specified index.
Development of
So this is how I did it, as I said, it is not easy / beautiful, but it works:
- First we receive your
select
orchosen_control
- Then we execute the plugin and get the container
div
orchosen_element
- Then we get
chosen_input
and bind the keydown to itevent
. -
event
will detect if a tab was clicked and it will do some dirty calculations to select the option the tab should display and it will select it. - We run a trigger command on the selected item to update ourselves.
Note
I just realized that the code does not work if there is more than one option that starts with the same letter, it will just pick the first one, I will fix it, but not now, these are new years here
Goodbye:)
source to share
Based on existing answers, I put this together to avoid changing the selected Source Code:
// Initialise Chosen
$select.chosen(/* ... */);
// Handle Tab correctly in a multi-select input
$select.next().find('.chosen-search-input').keydown(function (event) {
if (event.key === 'Tab') {
let $input = $(this);
// If the search results list is open
if ($input.closest('.chosen-container').hasClass('chosen-with-drop')) {
// Cancel Tab
event.preventDefault();
// Send Enter instead
let replacementEvent = $.Event('keyup');
replacementEvent.which = 13;
$input.trigger(replacementEvent);
}
}
});
However, I didn't use it because the dropdown menu opens as soon as the field is focused, so the user might accidentally select something while moving the form with the keyboard.
source to share