How to correctly bind event handlers?

How to correctly bind event handlers?

dts_sldts_sl Posts: 5Questions: 2Answers: 0

This is puzzling me to no end, so I'm resorting to asking for help!

I'm using 1.10.2 from the CDN. I'm using client-side processing, with an ajax datasource.

My goal is to create a column at the end of each row that has buttons for various actions. Those buttons will act on the data in the row the buttons appear in (typical edit/delete scenario).

My problem is that my implementation works fine when the page is first loaded, and when doing some direct manipulation of the data/table. However, some operations require the datatable to be completely reloaded, at which point the buttons begin doing their actions twice. I thought I covered this case, but apparently I've misunderstood something, and can't see it. Any help would be much appreciated! Here's what I'm doing ...

Table creation:

    $("#notices-table")
      .on('preXhr.dt', function (e, settings, json) {
        unbindButtons();
      })
      .on('xhr.dt', function (e, settings, json) {
        bindButtons();
      })
      .DataTable(options);

My understanding here is that if you do .on() multiple times, then you're "stacking" events ... so that's what I'm trying to avoid here. The bind/unbind functions:

  function unbindButtons() {
    var body = $("#notices-table tbody");
    body.off('click', '.publish-btn,.edit-btn,.del-btn');
  }

  function bindButtons() {
    var body = $("#notices-table tbody");
    body.on('click', '.del-btn,.edit-btn,.publish-btn', function () {
    ...

Lastly, when the table needs to be reloaded because something changed, I'm using:

          var table = $("#notices-table").DataTable();
          table.ajax.reload();

And in case it matters:

    var options = {
      "ajax": {
        "url": "data/datasource.notices.php",
        "type": "POST"
      },
      "ordering": true,
      ...

So, it all works fine on the initial page load, and on the reload() the unbind function is definitely getting called, but maybe I've missed something as far as the timing of these events vs the dom updating vs who-knows-what?

Or is there maybe a totally different approach I should be using?

Thanks!

Answers

  • dts_sldts_sl Posts: 5Questions: 2Answers: 0

    I'm gonna answer my own question since I finally figured it out....

    When you use obj.on("click", "selector1,selector2,selector3"... you must have the selectors listed in the same order for the off() call, otherwise some of them won't get removed. Go figure.

  • allanallan Posts: 63,522Questions: 1Answers: 10,473 Site admin

    Interesting - I suspect that jQuery is doing a trivial == compare on the selector used - which is fair enough for the use case I guess!

    Worth noting that you are using a delegated event there, so you don't really need to unbind and then bind again. You can just do it once and there won't be any memory leaks.

    Allan

This discussion has been closed.