felixRo felixRo - 21 days ago 8
Javascript Question

assign event again after element is destroyed and initialized again

Let me show what I mean on an example with bootstrap-select:

HTML

<a href="#" id="link">Show Select options</a>
<div id="gap"></div>
<a href="#" id="link2">Destroy Select</a>

<div id="searchSelect">
<select name="searchName" id="idSelect" data-live-search="true" data-size="10">
<option value="John">John</option>
<option value="Janet">Janet</option>
</select>
</div>


JS:

$("#idSelect").selectpicker();

$("#link").click(function(e) {
e.preventDefault();
$("#searchSelect").show();
setTimeout(function () {
$('#idSelect').selectpicker('toggle');
});
});

$("#link2").click(function(e) {
e.preventDefault();
$('#idSelect').selectpicker('destroy');
$("#searchSelect").hide();
alert("Select destroyed");
});

$("#idSelect").on("hide.bs.select", function () {
alert("onHide fired");
});


When you run for the first time, this event works fine:

$("#idSelect").on("hide.bs.select", function () {


but after you destroy the element and initialize again, the event won't fire anymore, is there a way to assign the event again to the element?

The best way to see what I mean is to go through:
take look at JSFIDDLE


  1. Click the button "Show Select options"

  2. Click outside the dropdown menu, it will close and it will show the alert message.

  3. Click the button "Destroy Select"

  4. Repeat step 1,2 it will close but it won't show the alert message.


Answer

Change to using a delegated event handler:

  $(document).on("hide.bs.select", "#idSelect", function () {
    alert("onHide fired");
  });

Jsfiddle: https://jsfiddle.net/n1zz8kkw/17/

This works by listing for the event on a non-changing ancestor, then applying the filter (#idSelect) to the items in the bubble chain, then applying the function to the matching element that caused the event. The upshot is that the element does not need to exist except at event time.

document is the best default if nothing else is closer. body has a bug, so best to avoid and document always exists, so a delegated handler on document does not even need to be inside a doc ready handler :)