LStarky
LStarky

Reputation: 2777

Using jQuery DataTables with Aurelia

I need some advice regarding the usage of jQuery DataTables with Aurelia. Basically I'm running into two problems.

  1. I can't determine the best way to initialize it AFTER the repeat.for binding loop has completed. Apparently that loop is still working even after the attached() lifecycle is fired.
  2. If I use $(myRef).DataTables(data: myArray) method to populate the table, and insert links (<a href-route=... click.delegate=...>) into that table, Aurelia doesn't seem to recognize the links or activate the router.

Problem 1: Here's my attempt to populate the table using Aurelia's binding. Aurelia correctly makes the table, and I can just wait 2-3 seconds and then load DataTables, but that's not the right way. I don't have a definitive event to trigger the loading of the DataTables class because I don't know when repeat.for is completed.

<div class="table-responsive">
  <table ref="tblUserList" class="table table-condensed table-hover table-striped" width="100%">
    <thead>
      <tr>
        <th><span t="Username"></span></th>
        <th><span t="First_name"></span></th>
        <th><span t="Last_name"></span></th>
      </tr>
    </thead>
    <tbody>
      <tr repeat.for="record of records">
        <td><a route-href="route: user; params.bind: {id: record.user_id}" click.delegate="$parent.select(record)">${record.user_username}</a></td>
        <td>${record.p_fname}</td>
        <td>${record.p_lname}</td>
      </tr>
    </tbody>
  </table>
</div>

Problem 2: Here's my attempt to populate the table using the jQuery method. DataTables successfully loads the table, but Aurelia doesn't recognize the links or trigger action.

$(this.tblUserList).dataTable({
  "paginate": true,
  "pageLength": 10,
  data: this.records,
  columns: [
    { data: 'user_username',
      fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
        $(nTd).html("<a route-href='route: user; params.bind: {id:" + oData.user_id + "}' click.delegate='$parent.select(" + oData.user_id + ")'>" + oData.user_username + "</a>");
      }
    },
    { data: 'p_fname' },
    { data: 'p_lname' }
  ]
});   

Can anyone help me solve any one of the above problems? Or... am I approaching this whole issue the wrong way? Is it better to use the jQuery method to populate, or the Aurelia repeat.for binding loop?

Upvotes: 0

Views: 1609

Answers (2)

jmdavid
jmdavid

Reputation: 58

I know this is old, but just in case, if it can help. When you add DOM elements after binding, they are not aureliazed. You should use the enhance method of TemplatingEngine:

  1. import the TemplatingEngine and inject it:

    import {inject, TemplatingEngine} from 'aurelia-framework';
    @inject(TemplatingEngine)
    
  2. In the constructor, initialize the template engine:

    constructor(templatingEngine) {
        this.templatingEngine = templatingEngine;
    }
    
  3. in Aurelia's attached() method, do your datatable init stuff, and add a class to be able to retrieve your newly created DOM elements:

    $(nTd).html("<a class='myclass' ...
    
  4. Enhance your elements:

    $('.myclass').each(function (index, value) { 
      let el = $(this);
      if (!el.hasClass('au-target')) { //can't enhance already aureliazed elm
        this.templatingEngine.enhance({element: el[0], bindingContext: this});
        //el[0] is important to have DOM and not jQuery object
      }
    });
    

Then your binding should work.

Upvotes: 1

Rabah
Rabah

Reputation: 2062

Using the first approach (aurelia binding), remove data from the config object and load your data in the activate lifecycle hook:

import 'datatables';

export class UserList {
    activate() {
        this.records = [...];
    }

    attached() {
        $(this.tblUserList).dataTable();
    }
}

Upvotes: 1

Related Questions