Open Nitrodist opened 3 years ago
I think I have fixed it with a few lines that removes the options programmatically upon keydown of the search input (ajax-bootstrap-select listens to keyup, thankfully).
My workaround involves marking the preset options, removing them from the select, notifying bootstrap-selectpicker to refresh the list, and then emptying out the internal selected list that Ajax-Bootstrap-Select uses:
// Fixes an issue where we want to display an initial list of options but
// the current behaviour of AjaxBootstrapSelect with preserveSelected set
// to true is to on keyup after typing into the live search show that
// initial list as 'currently selected'.
//
// This is visually incorrect since the user did not click on any of the
// initial list of options.
//
// See this issue that I reported:
//
// https://github.com/truckingsim/Ajax-Bootstrap-Select/issues/199
$(
".js-calendar-filter-by-person-container .bootstrap-select input"
)[0].addEventListener(
"keydown",
(event) => {
$(
'.js-calendar-filter-by-person-container [data-remove-preset="true"]'
).remove(); // bootstrap-select: remove options and then invoke selectpicker("refresh") on the next line - these are the standard instructions from the bootstrap-select lib.
$(".selectpicker").selectpicker("refresh"); // bootstrap-select: list is visually removed from UI at this point
$(".selectpicker").data("AjaxBootstrapSelect").list.selected = []; // Ajax-Bootstrap-Select: this line is needed so that the list is not restored into the `Currently Selected` optgroup upon keydown
},
{ once: true }
);
Mmm, I may have fixed it from sticking around after searching, but I also broke the functionality where they actually select an item from the initial list they're presented.
I've made some adjustments to respect when they're actually selected, see below for the code where I use lodash to filter out items that are not selected.
Speaking of which, while I was code spelunking inside the codebase I saw that we rely on jquery's :selected
pseudo-filter to know what the preserved list should be. Is it possible to replace that logic going forward with something like this? What do you reckon'?
- (event) => {
+ (_event) => {
+ // bootstrap-select: remove options and then invoke selectpicker("refresh") on
+ // the next line - these are the standard instructions from the
+ // bootstrap-select lib.
+ //
+ // Also, I think I may be a little bit aggressive here in removing
+ // options against options that may actually be selected, however,
+ // nothing visually or otherwise indicates a problem with this code as
+ // it is and the effect of this code is limited to only one invocation,
+ // so I'm comfortable with this as is.
+ //
+ // Versions:
+ // "ajax-bootstrap-select": "^1.4.5",
+ // "bootstrap-select": "^1.13.18",
$(
'.js-calendar-filter-by-person-container [data-remove-preset="true"]'
- ).remove(); // bootstrap-select: remove options and then invoke selectpicker("refresh") on the next line - these are the standard instructions from the bootstrap-select lib.
+ ).remove();
$(".selectpicker").selectpicker("refresh"); // bootstrap-select: list is visually removed from UI at this point
- $(".selectpicker").data("AjaxBootstrapSelect").list.selected = []; // Ajax-Bootstrap-Select: this line is needed so that the list is not restored into the `Currently Selected` optgroup upon keydown
+ var actually_selected_for_us_to_keep = _.filter(
+ $(".selectpicker").data("AjaxBootstrapSelect").list.selected,
+ (item) => {
+ return item.selected;
+ }
+ );
+
+ $(".selectpicker").data(
+ "AjaxBootstrapSelect"
+ ).list.selected = actually_selected_for_us_to_keep; // Ajax-Bootstrap-Select: this line is needed so that the list is not restored into the `Currently Selected` optgroup upon keydown
I am using ajax-bootstrap-select to search against people in my business's application. Up to this point I was using it without the
multiple
option, so I wasn't taking advantage of a few features.Remote search works great. Prepopulating the list doesn't work great. It thinks I am 'selecting' the initial list of options that I've provided.
With the non-multiple select tag in use, I was able to initialize the search list with a few preferred items using ajax-bootstrap-select. When I switched this new tag to use
multiple
, I've run into an issue where ajax-bootstrap-select groups the initial list into an<optgroup>
off 'Currently Selected' items even though none of them were selected.Steps to reproduce:
<option>
tags is grouped into 'Currently Selected'Desired Behaviour
Assuming that we have
preserveSelected: true
, that it only preserves the ones that were actually selected instead of all options in the list.I believe this is a problem where we rely on
$obj.find(':selected')
on this line of code insrc/js/classes/AjaxBootstrapSelectList.js #L69
Code
HAML:
Generated HTML: