Hello. After spending some time trying to find a simple solution that works with bootstrap 4 styling, including looking at the offered solutions and dead threads waiting on this open issue: https://github.com/snapappointments/bootstrap-select/issues/990, I decided to roll my own.
The following solution relies on the live-search option to be enabled on the bootstrap-select element. It uses the live search field to add the user-typed, custom value to the list of options. It is a hacky solution and not the prettiest thing, but maybe this concept could be directly integrated into bootstrap select to finally solve issue 990.
Just add this code to your page. Replace (yourselector) with your selector. For my project, I just wanted any selectpicker element that wasn't multiple capable, so I used .selectpicker:not([multiple]).
var newOption;
$(document).ready(function () {
//Custom editable combobox
$(document).on("loaded.bs.select", "(yourselector)", function (e, clickedIndex, isSelected, previousValue) {
newOption = ""; //Reset newOption before doing a new search
$(e.currentTarget).siblings(".dropdown-menu").on('keyup', '.bs-searchbox input', function (ie) {
//if more than one and search is 0 characters, continue. If more than one and search is 1 character and character doesn't match first character of newValue, delete newValue.
//If 1 and class is "no-results", delete old newValue and add newValue.
console.log("running keyup script for " + e.currentTarget.id);
var searchList = $(e.currentTarget).siblings("div.dropdown-menu ul.dropdown-menu li");
var searchPhrase = $(ie.currentTarget).val();
//Something was found
if (searchList.length > 0 && !$(searchList[0]).hasClass("no-results")) {
//new search
if (searchPhrase.length == 0)
return;
else {
//they haven't started searching the same phrase again
if (newOption && newOption.toLowerCase().indexOf(searchPhrase.toLowerCase()) < 0) {
console.log("newOption: " + newOption + "\nsearchPhrase: " + searchPhrase + "\nSubstring?: " + newOption.toLowerCase().indexOf(searchPhrase.toLowerCase()));
//delete newOption from options list and reset
$("#" + e.currentTarget.id + " option[value='" + newOption + "']").remove();
newOption = "";
$(e.currentTarget).selectpicker("refresh");
$(ie.currentTarget).trigger('propertychange');
}
}
}
//Nothing was found
else {
$("#" + e.currentTarget.id + " option[value='" + newOption + "']").remove();
newOption = searchPhrase;
$(e.currentTarget).append($('<option>').val(searchPhrase).text(searchPhrase));
$(e.currentTarget).selectpicker("refresh");
$(ie.currentTarget).trigger('propertychange');
}
})
});
$(".selectpicker").on("changed.bs.select", function (e, clickedIndex, newValue, oldValue) {
newOption = ""; //Reset newOption before doing a new search
});
});