sa-si-dev / virtual-select

A javascript plugin for dropdown with virtual scroll
https://sa-si-dev.github.io/virtual-select
MIT License
242 stars 57 forks source link

onChange event is fired twice when you change value after using search #293

Open vivekmakwanadikus opened 8 months ago

vivekmakwanadikus commented 8 months ago

To recreate this bug.

VirtualSelect.init({
  ...
  search: true,
});

document.querySelector('#sample-select').addEventListener('change', function() {
  console.log(this.value);
});

Now when you search a value and select it the change event is fired twice

rich1888 commented 7 months ago

I'd also like to know how to stop this if possible.

Im using it with livewire and allowing multiple selections.

When you select an option after searching it is breaking the rule that selections should be an array as on the first change event the value is a string (the search term), and immediately after that the change event is triggered again with the selected values as an array.

vivekmakwanadikus commented 7 months ago

I have made a hotfix for it. I'm using this with jQuery event listeners.

$(document).on("change", ".foo", function (e) {
    if (virtualSelectFix($(this), e)) {
        return;
    }
})
function virtualSelectFix(that, event) {
    if (that.val() !== event.target.value) {
        return true;
    }
    return false;
}
gnbm commented 5 months ago

@sa-si-dev could you help clarifying this?

rich1888 commented 5 months ago

This is still causing some issues.

When you search and hit enter, the value passed is the string you searched, and not the option you selected.

@sa-si-dev Could you help please 🙏

ShaunWilders commented 5 months ago

I can confirm the search value is being passed back as the value before the selected value/s. I have this setup as a Livewire component and have managed to ignore the search value for now, but as I'm not using onServerSearch there's no need for the search value to be passed back at all.

ShaunWilders commented 4 months ago

@rich1888, I am also using this as a livewire component but I have it setup as a reusable component using https://github.com/livewire/livewire/discussions/4725 as my starting point.

Technically, the search input is changing, but I have tweaked the x-on:change attribute to only set the model value (and as a result, trigger a livewire update) if the className is "vscomp-ele pop-comp-ele pop-comp-active" or "vscomp-ele pop-comp-ele":

original: 'x-on:change="select = event.target.value"'

tweak: 'x-on:change="if(event.target.className=='vscomp-ele pop-comp-ele' || event.target.className=='vscomp-ele pop-comp-ele pop-comp-active'){select = event.target.value;}"'

I added console.log(event); into the attribute while testing to see all available attributes: 'x-on:change="console.log(event);select = event.target.value"'

fekoerbel commented 1 month ago

this is a temporary solution to solve this problem:

          let lastValue = '';
          document.querySelector('#sample-select').addEventListener('change', function() {
              if (this.value != lastValue) {
                  console.log(this.value);
                  lastValue = this.value;
            }
          });