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
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;
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:)
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.