Tinkle Pooplebottham Tinkle Pooplebottham - 14 days ago 5
Javascript Question

Which event to use for adding and option in a select?

What I want is something like an onchange event with an html select element. But apparently the change event is for the options in a select. I need to detect when a new option is added.

I've searched google and SO and the links within but I don't want to use any frameworks.

I read up on creating events but I don't understand how to use the created event "onAdded". Like select.onAdded -> how does select know something (an option) is added?

Or is there a simpler way that I'm over looking? An event that I missed?

My point is, I want to do something like this



var select = document.getElementById("slct");

var btn = document.getElementById("btn");
btn.addEventListener("click", () => {
var option = document.createElement("option");
option.text = `${select.length} please work!`;
select.add(option );
//!!!select optionAdded event should have triggered!!!
})

function addPoint(){
//do things
}

/*
select.addEventListener("optionAdded", addPoint);
or
onSelectValueCountChanged(appropriateFunctionHere);
*/

<form>
<select id="slct" style="width: 300px" mutiple="true" size="11">
</select>

<button type="button" id="btn">click
</button>

</form>





Is it possible? In an easy to understand (I'm new to js) way without any frameworks?

Answer

You can create a custom event and fire it on the select element. Here is a code I used for it some time ago. It should be supported quite well, but cannot tell you precise information on that now.

function triggerCustomEvent(element, eventType, eventProperties) {
  let event;

  // a cross-browser way to create an event object
  // don't know which branch is for which
  if (document.createEvent) {
    event = document.createEvent('HTMLEvents');
    event.initEvent(eventType, true, true);
  } else {
    event = document.createEventObject();
    event.eventType = eventType;
  }

  // also for being cross-browser
  event.eventName = eventType;

  // events are just objects, we can add properties to them, so we extend it
  // with our custom properties if any
  if (eventProperties && typeof eventProperties === "object") {
    for (var property in eventProperties) {
      event[property] = eventProperties[property];
    }
  } 

  // cross-browser way of firing the actual event object on the given element
  if (document.createEvent) {
    element.dispatchEvent(event);
  } else {
    element.fireEvent('on' + event.eventType, event);
  }
}

You can use it like this

triggerCustomEvent(select, "onoptionadded", { options: opt });

The third argument is optional, if you want to add some properties to the fired event object.

If you want to go this way, you should introduce a method for adding options, so you can be sure that you always trigger this event.

function addOption(select, option) {
  select.add(option);
  triggerCustomEvent(select, "onoptionadded", { options: option });
}

Note that the code snippet is only for example purposes, it's not widely tested and you shouldn't just copy-paste it.