Eventlistener on <options> always trigger the first click

Hello,

I am displaying the value of an <option> from a <select> when I click on it.
My problem is that when I first time click on the select field (which mean I just want to see the options) the first <option>of the <select>is displayed.

codepen: https://codepen.io/johnthecoder/pen/JjYaNYy

HTML (using tailwind)

<div class="flex flex-wrap mb-6 -mx-3">
        <div class="w-full md:w-1/2 px-3">
            <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="properties[]">
                Properties
            </label>
            <div class="relative">
                <select class="prop_select block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="property" name="property">
                    <?php foreach($properties as $id => $name): ?>
                        <option name="property" value="<?= $id ?>"><?= $name ?></option>
                    <?php endforeach ?>
                    <option name="property">test</option>
                    <option name="property">test2</option>
                </select>
                <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
                    <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
                </div>
            </div>
            <div class="relative">
                <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mt-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" name="autre" id="autre" type="text" placeholder="Autre">
                <div class="pointer-events-auto cursor-pointer absolute inset-y-0 right-0 flex items-center px-4 font-bold text-gray-700" id="autre_validate">
                    OK
                </div>
            </div>
        </div>
        <div class="w-full md:w-1/2 px-3">
            <ul class="properties_show"></ul>
        </div>
    </div>

JS

const prop_options = document.querySelectorAll('.prop_select')
const properties_show = document.querySelector('.properties_show')

prop_options.forEach(option => {
        option.addEventListener('click', (e) => {
            let li = document.createElement('li')
            li.innerHTML = e.target.value
            properties_show.appendChild(li)
        })
    })

So when I click on the <select> there is always a test or test2 displayed in the properties_show div before I select the value I want.

How could I do to remove the behavior of the first click on the <select> tag ?

What you can try to use is a default value for the options, and disable it.

<select>
  <option value="" disabled selected>Select an option</option>
  <option value="option 1">option 1</option>
  <option value="option 2">option 2</option>
</select>
1 Like

This usually is solved by adding disabled and selected option like so :point_up:

And then you would listen to change event rather then 'click`

1 Like

You can listen for the change event on the select element. As already suggested you should add a disabled and selected option element before the others.

<option name="property" disabled selected>Select an option</option>

const prop_options = document.querySelector(".prop_select");
const properties_show = document.querySelector(".properties_show");

prop_options.addEventListener("change", (e) => {
  const optionValue = e.target.value;
  render(optionValue);
});

const render = (value) => {
  let li = document.createElement("li");
  li.innerHTML = value;
  properties_show.appendChild(li);
};
1 Like

Thanks, I also used the ‘change’ instead of ‘click’ event because if I just use ur solution i’ll have empty <li></li> each time I click the <select>

That’s perfect, thank you :slight_smile: