I tried several solutions given here and elsewhere, however none worked in chosen.js 1.8.5 (jQuery: 3.3.1) and so I ended up with the following since I didn't want to use a fork that might not always be up-to-date to the master branch:
For the case that I might not want any .chosen-select
to allow new values, I added a new class .chosen-newValuesAllowed
. I set an event handler on this class where CTRL + I adds the new value if it is not yet present. The focus on the input field does not get lost afterwards. In my example, I check the innerHTML of the since @value actually contains database ids and therefore the new value, which is a string in my example that would be processed by the server later, could never be found in @value. If you want to check @value, please see the comment inside the snippet.
The code handles single and multiple selects.
$(document).on("keydown", ".chosen-container.chosen-newValuesAllowed input", function(e) {
if (e.ctrlKey === true && e.keyCode === 73) { // CTRL + I
e.preventDefault();
var newValue = $(this).val();
if (newValue) {
try {
// only add if there is no option having the content/text of "input" yet!
// instead of filter() for the content of <option> you can check on its @value by: find("option[val='...']")
var $selectElement = $(e.target).closest("div.chosen-container").prev(); // the previous sibling should be the <select>. If not, grab it some other way, e.g. via @id
if (!$selectElement.find("option").filter(function () { return $(this).html() === newValue; }).length) {
if (!$selectElement.attr("multiple")) { // unselect for single-select
$selectElement.val('');
}
$selectElement.append('<option val="' + newValue + '" selected>' + newValue + '</option>');
$selectElement.trigger('chosen:updated');
}
} catch(error) {
// pass
}
e.target.focus();
}
return false;
}
});
Another solution would be to call the triggerable function chosen:no_results if new values should only be added if there explicitly is no result:
$(".chosen-select.chosen-newValuesAllowed").on("chosen:no_results", function(e, data){
var newValue = data.chosen.get_search_text();
...
});