greetings…
I’m building a fancy Select2 based system for creating custom time window ranges, I’ve got 90% of it working, but I’m struggling with the last part of it…
my markup is being generated on page load, with the following bare minimum structure:
<select title="Select your time window here, enter a name to create a new entry." name="time_window_name">
<option class="internal-option"></option>
<option value="custom" disabled="disabled" class="internal-option">Custom Window</option>
</select>
- the empty option here is used by Select2 as a placeholder for “no selection”.
- the “Custom Window” option is used by my logic to show when either a “start” or “end” time input field has a value (not shown here).
when a new <option>
is added to the source <select>
element, it appears in the list as per the following two examples:
<select title="Select your time window here, enter a name to create a new entry." name="time_window_name">
[ snip... ]
<option value="7,8">Morning Rush</option>
<option value="16,17">Evening Rush</option>
</select>
- where the option’s
value
refers tostartHour,endHour
.
I’m initialising Select2 with the following config:
{
allowClear: true,
placeholder: "no filter",
tags: true,
createTag: createTagHandler,
templateResult: templateResultHandler,
}
where createTagHandler
just does some basic checks (valid name, at least start or end time, etc) and templateResultHandler
modifies the rendered select result entries as follows:
function templateResultHandler(state) {
if (!state.id || ["custom"].includes(state.id)) {
return state.text;
}
const item = $("<div>", {
class: "select2-result-item d-flex align-items-center",
});
$("<span>", {
class: "select2-result-item__text",
text: state.text,
}).appendTo(item);
const deleteButton = $("<button>", {
type: "button",
class: "btn btn-danger btn-sm ms-auto",
}).appendTo(item);
$("<i>", {
class: "fa fa-trash",
}).appendTo(deleteButton);
return item;
}
- note: the
select2-result-item
classes seen here were suggested by other resources that I’ve found online, not sure if they are helping or not.
the end result (with extra “start hour” and “end hour” inputs) is a UI that looks like this:
the crux of my issue here, is that I cannot figure out how to get a custom event handler bound to the custom <button>
element that I’m adding to each option… no matter what I try, Select2 always takes a click anywhere on the option item as “selecting that option”, even if I click the button I added.
I’ve tried event.preventDefault()
and event.stopPropagation()
in the “click” handler, I’ve tried attaching the handler to different parent elements, I’ve even tried hooking into and overriding the select2:select
handler… I cannot get Select2 to not select the item when I click my custom button.
please can someone help me out here? what am I missing??