JQuery Data-Tables + Ember Works Now


#1

So attempting to use JQuery’s Data-Tables with a table defined in the dom prior to the new ember release was impossible whether calling .dataTable() from a view’s didInsertElement, or the route using run.scheduleOnce(‘afterRender’), the same error would occur, “cannot apply transform to a meteamorph not in the DOM”, or something along those lines. Now any of those methods work fine. Something has changed with the way ember renders it’s templates and I would like to know just for curiosity’s sake and learning what changed and why this integration works now, to the technical details, if anyone would be willing to take the time and explain. I’ve looked at the source code a bit but I think that rabbit hole is a little too deep for me to dive into alone quite yet.


#2

Hi, Can you show me, how are you using a datatables? I successfully insert table structure, but without a data :frowning: {{#each}} parameter doesn’t work and I don’t know what I would use instead of that. Thanks.


#3

I am not so sure if we can use {{each}} in the template using datatables. But maybe this may help you to get things started: JS bin for Ember with DataTables.


#4

Nice, thanks. I found out “collectionView” works for one line, but I don’t know how to generate more lines by collection view. Otherwise a parameter aaData in this.$().dataTable( {…}) works well. Now If I want add some data dynamically from store, what I will need add to aaData? this.store.find(‘someModel’) doesn’t work from view definition.


#5

You can use #each helper but you will need to do some work when modifying the data , by creating a mixin. However you can get the data table to display with dynamic elements fairly easy. Put the table template in the view template without including the table <> or class tags. Specify those in the view by overriding classNameBindings and tag. Then on the onRender() method simply follow the standard example on Data Table web-site for generating from the DOM and it will work. You can also use this in the route. /Ember.run.scheduleOnce(‘afterRender’, this, function(){ console.log(“after render”); $(’#searchResultsTable’).dataTable(); });/


#6

like:

App.TableView = Em.View.extend({
    classNames:['table','table-striped','table-bordered','dataTable'],
    tagName:'table',
    didInsertElement:function (){ // or onRender: ?
       this.$().dataTable();

     }
});

HTML:

{{#view App.TableView}}
                <thead>
  		  <tr>
  		     <th> Type </th>
  		     <th> Name </th>
  		  </tr>
  		</thead>
  		<tbody>
                  {{#each devices }}
                    <tr>
  		        <td>
  			   {{type}}
  			</td>
  		        <td>
  		           {{name}}
  	    		</td>
  		     </tr>
                  {{/each}}
  	  	</tbody>
  {{/view}}

this doesn’t work :frowning:


#7

What error is it throwing exactly? I don’t use the {{#view}} helper. Instead I put the template in a separate template file and then reference it in the view class’ template, or templateName property. Then in the template where you have your {{#view}} helper, put instead {{view App.TableView}} And everything should then work. If you give me more details on the error you’re getting I can help figure out why your method doesn’t work, although i suspect it’s because the view’s template is being inserted as the main template is loaded and data-tables probably attempts to modify the content before the didInsertElement fires.


#8

Also in the didInsertElement hook use document.ready before calling the data-tables. I am not 100 percent sure but this ensures that ember finishes some of it’s bindings / metamorphs before data-tables works it’s own magic. Also try using the id selector explicitly and define the id value in your view’s property statically or use this.getElementId and put that in a string for the Jquery selector.

$(document).ready(function(){
		console.log('document is ready');
		$('#searchResultsTable').dataTable();
	});

#9

Oh and unless you’re using a really old version of ember Em.View shouldn’t be working right? the new namespace is Ember


#10

Can you provide a jsFiddle with an example of that? Also, what version of Ember are you using?


#11

I’m using the latest release, it wasn’t working prior to the latest release. And yes i’ve never made a JSfiddle before so i’m going to check it out, unless you wanna give me the quick and dirty way of making one then I’ll give you an example.


#12

Hi meph, Sorry for the late reply,

the ‘this.store.find(‘someModel’)’ will not work simply because in javascript there is a scope concept. You can read it everywhere in the web in regards of this. If you notice, in the js bin, i put " var self = this ". this is because if i want to access the App.DataTableView’s scope instead of the jquery’s, i can simply do it by using self.watevermethodInView ,this way i can escape the jquery scope.

Going back to your question, i still dont think by doing {{each}} will be the best way forward (Since we use a third party plugin, better to stay with datatables way of doing things - lots of guides etc out there). You can still access the App.YourDynamicObjectThatContainsDynamicData or in my latest JSBin below, the App.Datas

Keep in mind, Ember will automagically make the standard javascript Array to be Ember.Array. So this will enable you to use App.Datas.get(1) to get the index 1 object.

You can also use Fixtures or ember-data if you like though. Hope this helps

Updated JSBin


#13

Thanks for this code. It is works for me

but I can’t fulfill table from store. I tried this:

but App.BookArray doesn’t return correct array format.

I need send array to “aaData”, but it doesn’t recognize Ember-data Array.

P.S.:Sorry for my low English skill and low Ember skill :frowning:


#14

Hi meph,

To access the fixtures data, just use App.YourModel.FIXTURES and it will return an array of data.

Here is the jsBin for accessing the fixtures data: DataTables with Fixtures Data


#15

In my example there are fixtures, but I will use RestAdapter in future. This is reason why I need load data from store to dataTable.


#16

Hi, these are some modifications, which (of course) don’t help. I set property of controller (aaData) to books array (books.toArray()) and then I want set the aaData to dataTable “aaData”, but I don’t if mistake is at data format or at an accessing to the controller.


#17

This code finnaly works:

App.BookRoute = Ember.Route.extend({

model: function(){
        return this.store.find('book');
    },

    setupController: function(controller,model){
       templateName: "datatable";
       controller.set('data',model); // model -> recordArray, this.model() -> PromiseArray
    }
});

in template:

 {{view App.DatatableView valueBinding="data"}}

and view:

App.DatatableView = Ember.View.extend({

    tagName:'table',
    classNames:['table','table-striped','table-bordered','dataTable'],

    didInsertElement: function(){
        if (this.get('value')){
            var data = this.get('value').getEach('data');
            var self = this;
            this.$().dataTable({
                //"bProcessing": true,
                "aaData": data,
                "aoColumns": [
                    { "sTitle" : "Added", "mData": "id" },
                    { "sTitle" : "Author", "mData": "author" },
                    { "sTitle" : "Title", "mData": "title" },
                    { "sTitle" : "Year", "mData": "year" }]
              });
        }
    }
});

However, new problem is appeared. This view is repetedly added on page after click on the page and it is visible on other pages. Do you know, where an error is?


#18

That error happens in the new ember when there’s something wrong with your html. Usually a missing closing tag .


#19

This code works fine, the problem I have is that the first time I load the page I don’t get any record and the table is empty, the second time I have them instead… do you what can be the cause of this?


#20

JSBin based on this example: