htmlstreamofficial / preline

Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
https://preline.co
Other
4.9k stars 309 forks source link

Values in ComboBoxes does not update when selection made #467

Open Aux9 opened 2 months ago

Aux9 commented 2 months ago

Summary

Values in ComboBoxes does not update when selection made

Steps to Reproduce

When I try this Example here a basic usage of ComboBox its working perfectly, however the value of the input is not changing whenever new selection is made because somehow it loses focus maybe, when you try just something like this <input id="input1" onblur="testValue(this)" to test the value with a function like this :

        function testValue(el) {
            console.log(el.value);
            console.log('value: ' + document.getElementById("input1").value); 
        }

the value of the input is always empty! is there something wrong or my approach is wrong?

the aim is to verify the input value when users change selection please.

Demo Link

https://preline.co/docs/combobox.html

Expected Behavior

When user select something, the input value should change accordingly and save the user selection for further use besides it should not lose focus!

Actual Behavior

The input value is empty because it loses focus as I believe.

Screenshots

No response

olegpix commented 1 month ago

@Aux9 Hi, The value only changes if you select one of the items in the dropdown list, otherwise the value reverts to the original value. To get the current value when the value changes, you can use the built-in select method:

window.addEventListener("load", () => {
  const {element} = HSComboBox.getInstance('#input1', true);

  element.on('select', () => {
    console.log(element.value);
  });
});
mohsinhijazee commented 1 month ago

@Aux9 Hi, The value only changes if you select one of the items in the dropdown list, otherwise the value reverts to the original value. To get the current value when the value changes, you can use the built-in select method:

window.addEventListener("load", () => {
  const {element} = HSComboBox.getInstance('#input1', true);

  element.on('select', () => {
    console.log(element.value);
  });
});

@olegpix I have tested it and went through the code so probably not. Basically, the fireEvent() method is dispatching the whole HTML element which happens to be the whole div containing the combobox and does not have .value property on it.

Side note - .value is a private property so it might be valid for JS to access it but writing Typescript would generate error.

And here's the setValue() method in action.

private setValue(val: string) {
  this.selected = val;
  this.value = val;
  this.input.value = val;

  this.fireEvent('select', this.el);
  dispatch('select.hs.combobox', this.el, this.value);
 }

This does not help that the whole flow of click event leading to close() here and then setValue() (listed above) does not set the .selected classes on the combobox items (data-hs-combo-box-output-item and such) and thus doing a querySelector* on the dispatched element in the event handler is not going to be able to determine what exactly was selected.

Ideally, the event handler should dispatch:

  1. The reference to the DOM node that was clicked.
  2. The value (label, the visible one)
  3. The object of custom attribute (those arising from the data-hs-combo-box-output-item-attr)

Basically, the combobox at the moment has no way of:

  1. Letting the event handlers know what was selected
  2. Neither a method that lets check the current value without manually and directly accessing the DOM which I guess would be brittle and sensitive to markup.

I can contribute the changes. At the moment what's in public repo (v2.5.0) - rendering of items works (JSON or HTML) but events and value extraction is broken. Even direct DOM manipulation/querying is not going to help the user of this component to determine what was selected because setValue() retains the selection as private variable of the class and it is nowhere reflected in the DOM.

Some properties/methods and adjustments are in order. This becomes more important because such an top class UI library will rarely be used as plain HTML and would end up almost always wrapped up by people as components (Svelte/React/Vue) etc.

FYI @jahaganiev

lenart commented 1 month ago

(I think) I have a similar issue with updating values (v2.5.0). I wanted to use Combobox for autocomplete search where I want to display values (eg. product names) but I need the value to be the id. This is a common practice so I believe CB should support such behavior. As soon as I move data-hs-combo-box-value to a different element than data-hs-combo-box-search-text the text is not populated and no value is set on the combobox.

CleanShot 2024-10-14-07 11 18

This does not work (in a template)

    <div data-hs-combo-box-output-item-field="id" data-hs-combo-box-value></div>
    <div data-hs-combo-box-output-item-field="name" data-hs-combo-box-search-text></div>
    <div data-hs-combo-box-output-item-field="description"></div>

This works but is not usable (due to possible name duplicates)

    <div data-hs-combo-box-output-item-field="id"></div>
    <div data-hs-combo-box-output-item-field="name" data-hs-combo-box-search-text data-hs-combo-box-value></div>
    <div data-hs-combo-box-output-item-field="description"></div>