1

I want a select element to contain one default option that shows a popup when selected. So I've created HTMLOptionElement and add an event to onclick event listener but the event doesn't trigger when the option is clicked.

Here is my code:

const selectDefaultOption = new Option(".. show popup ...");
selectDefaultOption.addEventListener("mouseup", () => {
    // ... show pop up
});
document.querySelector("#select").appendChild(selectDefaultOption);

Am I doing something wrong? Or it's not possible to achieve what I'm trying to?

Conclusion & Solution

After a few attempts I came to the conclusion that there is no neat solution to simply trigger event attached to a select option.

However, I've managed to achieve performing an action when specific option is selected (although it's not as elegant as was my initial intention).

The solution:

const selectElement = document.querySelector("#select");

const placeholderOption = new Option("<< select option >>", "<< select option >>", true, true);
placeholderOption.style.display = "none"; // this option is never display in the selection and serves only as a placeholder
selectElement.add(placeholderOption, null);

const onclickOption = new Option("onclick option", "onclick option")
onclickOption.onclick = () => alert("onlick option clicked!");
selectElement.add(onclickOption, null);

let previousSelectedValue;
selectElement.onmouseenter = event => {
  previousSelectedValue = event.target.value;
  event.target.value = placeholderOption.value;
  event.target.onmouseleave = event => {
    event.target.value = previousSelectedValue;
  };
} 
selectElement.oninput = event => {    
  event.target.onmouseleave = undefined; // reset the onmouseleave so it doesn't change current value
  const selectedOption = event.target.selectedOptions[0];
  if (selectedOption.onclick){
    selectedOption.onclick(selectedOption.event); 
    event.target.value = previousSelectedValue; // you may assign placeholderOption.value
  }
};
<select id="select">
    <option>option#1</option>
    <option>option#2</option>
</select>

2 Answers2

2

First I add eventListener to the select container. As trigger i took focus. Then i use your code to create a new option element. This element i assign a new eventListener which trigger the alert().

Update for all Browsers

The assigned EventListener on options tags on a created element will fail on most browsers. That is why it is right to tie the EventListerner to the Select Tag. Then you can check which field it is via the value field.

const s = document.getElementById('select');
let isLoaded = false;

s.addEventListener('focus', () => {  
  if (! isLoaded) {
    const selectDefaultOption = new Option(".. show popup ...");    
    selectDefaultOption.setAttribute('value', "popup");
    s.appendChild(selectDefaultOption);
  }
  isLoaded = true;
});

function callPopUp(event) {
  let s = document.getElementById('select');
  if (s.value === 'popup') {
    alert('PopUp')
  }
}
select {
  width: 200px;
  background: gray;
  padding:10px;
}
<select id="select" onclick='callPopUp(event)'>
  <option value="123">123</option>  
  <option value="456">456</option>  
</select>

Note

Together with @Olafvolafka we found out that in most browsers (Chrome, Opera) it is not possible to successfully bind an event to the option tag / element. No event was triggered. Only in Firefox was an event triggered. Therefore, we have to work with a workaround. Status 01/2022.

Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
  • Your solution works (although it has some flaws), but your answer doesn't answer my initial question and that's: Is possible to achieve triggering an event on an option being clicked? – Olafvolafka Jan 28 '22 at 12:34
  • @Olafvolafka No only in Firefox would it be possible. See my first answer and the conversation from the chat. – Maik Lowrey Jan 28 '22 at 13:02
  • 1
    I know. I was just pointing out that this information is missing in your answer ;) If you update your answer to be fully answering my question then I will accept it. – Olafvolafka Jan 28 '22 at 13:30
  • 1
    @Olafvolafka I updated my answer (add Note). That was a tough nut to crack! Merci and Cheers – Maik Lowrey Jan 28 '22 at 13:52
0

You would put the listener on the select element and check for the value (rather than put a listener on the option element directly)

document.querySelector('select').addEventListener('change', e => {
  if (e.target.value === '2') console.log('The special option was chosen');
})
<select>
  <option value='1'>1</option>
  <option value='2'>Special</option>
  <option value='3'>3</option>
</select>
Kinglish
  • 23,358
  • 3
  • 22
  • 43
  • It's not exactly what I'm trying to achive. This only works when selected option is changed. My goal is to perform some action after selecting the default option even if it's been already selected. – Olafvolafka Jan 26 '22 at 20:13