Angular 2, DataTables, and Pagination using DataTables.net-bs
Angular 2, DataTables, and Pagination using DataTables.net-bs
Hello,
I'm currently writing an application using Angular 2 and have it configured to use DataTables.net, DataTables.net-bs, and DataTables.net-select.
For the most part, everything looks and works great. With one exception, the pagination for the application shows up with as though no styling is applied.
I checked the source within the browser and the default classes and HTML structure is applied:
<div class="dataTables_paginate paging_full_numbers" id="myTable_paginate">
<a tabindex="0" class="paginate_button first disabled" id="myTable_first" aria-controls="myTable" data-dt-idx="0">First</a>
<a tabindex="0" class="paginate_button previous disabled" id="myTable_previous" aria-controls="myTable" data-dt-idx="1">Previous</a>
<span>
<a tabindex="0" class="paginate_button current" aria-controls="myTable" data-dt-idx="2">1</a>
<a tabindex="0" class="paginate_button " aria-controls="myTable" data-dt-idx="3">2</a>
<a tabindex="0" class="paginate_button " aria-controls="myTable" data-dt-idx="4">3</a>
<a tabindex="0" class="paginate_button " aria-controls="myTable" data-dt-idx="5">4</a>
<a tabindex="0" class="paginate_button " aria-controls="myTable" data-dt-idx="6">5</a>
<span class="ellipsis">…</span>
<a tabindex="0" class="paginate_button " aria-controls="myTable" data-dt-idx="7">580</a>
</span>
<a tabindex="0" class="paginate_button next" id="myTable_next" aria-controls="myTable" data-dt-idx="8">Next</a>
<a tabindex="0" class="paginate_button last" id="myTable_last" aria-controls="myTable" data-dt-idx="9">Last</a>
</div>
The functionality of the links work and the it just looks ugly on the display because I'm using the DataTables Bootstrap CSS and it is not outputting the appropriate HTML using an unordered list. I went into the debugger in the browser and the code for the DataTables.net-bs is being loaded. I added a bunch of break points to the JavaScript and the factory method is being called. However, it appears that it is never called again.
Here is the relevant code for my vendors.browser.ts
require('datatables.net')();
require('datatables.net-bs')();
require('datatables.net-select')();
require('file-saver');
I also have AMD turned off because I know that was an issue for some people. Here is the relevant code for the webpack.common.js file:
{
test: /datatables\.net.*/,
loader: 'imports?define=>false'
},
As an aside, the other plugin, Datatables.net-select, functions properly.
If I can't figure this out, I can use the styling included in DataTables.net-dt, but I would much rather get this working properly.
Does anyone have any potential ideas on what is going on?
This question has an accepted answers - jump to answer
Answers
I resolved the problem.
The issue was with this code:
The problem is within the checks at the beginning of the modules for DataTables.net. At the top of each module, you have the following:
With the above code, we are not passing in the global $ variable. When the first import runs, the $ variable is null and so it sets the value appropriately. When the second import, the value passed in is null and it gets reset along with the extensions for the plugin. When the third import runs, we have the same issue. The select functionality is now there, but we overwrote the functionality for the Bootstrap plugin.
So, the corrected code is the following (edited by allan per comment below):
I was basing my code on this: [https://github.com/brakmic/Angular2-Articles/blob/master/article6/src/init/vendor.ts][1]
My typescript editor was barfing at the first line, so I removed it not fully understanding what was going on behind the scenes. Lesson learned.
Hi, do you have a tutorial on this? Im trying to adapt data tables.net to angular 4... I would appreciate a lot!
Thanks in advance
Jessie
Sorry for the late reply. I didn't see that anyone responded to this thread.
I don't have a tutorial. However, this series of tutorials was very helpful: blog.brakmic.com/category/coding/javascript/angular/.
What was also most helpful to me was this repository by the author of the tutorials:
https://github.com/brakmic/Angular2-Articles/tree/master/article6/src
Thanks for posting back and updating your response above with the information about passing the jQuery object in!
I need to get around to writing such tutorials myself! The one thing that keeps me from doing that is that I've never found a nice way of mixing Require and CSS. Are you using a solution for that?
Allan
Also, if you happen to read this again, Allan, is there a way to edit the responses? For some reason, I cannot edit the first response.
The code in that response:
Should be:
The application, through WebPack, the global variables window and $ defined so you can pass them into the require function. If it is not possible, I'll leave that here for anyone else who happens upon this thread.
For some reason, the forum ate my other response to you.
I didn't do anything special for including the CSS. I am still new to Angular 2 and I chose a template that used WebPack.
In the vendor.browser.ts section, I included the following code:
This code uses the style-loader plugin for WebPack. Here is the relevant reference:
https://webpack.github.io/docs/stylesheets.html
The above code tells WebPack to insert a style tag in the DOM.
I've edited the post. The forum only allows edits in a relatively short window. There were too many cases of folks changing their question or even removing it in some cases!
Thanks for the link for the style loader. I'll take a look into the code they are using.
What I really want is to be able to do
require('datatables.net-bs')(...)
and that would load jQuery, DataTables, Bootstrap integration for DataTables, both JS and CSS.Allan
STEPS TO INTEGRATE datatables.net TO ANGULAR 4 CLI
We need to install datatables.net as a global library (available to all components). This means that the library will not be lazy-loaded, but rather imported/downloaded on the first page load.
After 2 days of research and a lot of digging into Angular CLI I was able to make it work with the latest version of the CLI (
1.1.3
) and Angular 4These are the relevant articles in the wiki that helped me:
https://github.com/angular/angular-cli/wiki/stories-global-scripts
https://github.com/angular/angular-cli/wiki/stories-third-party-lib
Now lets configure typyings so we let the compiler understand these libraries and don't error while compiling.
Open
tsconfig.app.json
and undertypes
node add the following typings:Finally, we need to add our libraries to the global scripts and styles section.
Open
tsconfig.app.json
file and update thestyles
andscripts
sections as follows:Just make sure you set the order of the libraries right, it doesn't really matter if you add libraries in the middle. But essentially you need
JQuery
, thenBootstrap
, thendatatables.net
, and finally any datatables.net extensions or plugins you may need.Please note that the same procedure should be done for importing almost any other JQuery plugin to an Angular 4 CLI project.
Now you can use datatables in a component as follows:
Awesome! Thanks you very much for taking the time to write this up and share it with the community!
Allan
@felimartina - Thank you so much for your example code. Been struggle for ages to reload the table with different data sets until i found this. The .clear is what i was looking for all along because the destroy alone reuses the previous data set.
After upgrading Angular to 4.2.4 and using the ng cli I started seeing an error when trying to build the project. After some debugging it turned out to be that one of the scripts in the .angular-cli.json was pointing to the wrong file and was generating builds and
ng serve
to fail.in your .angular-cli.json under the scripts tag you should have this
Hope this helps someone else.
Working with version 1.10.16 of datatables (2017-10-19)
@felimartina : Thank you so much for your help i can use now DataTables on my Angular APP.
I still have a problem if you have any idea plz : how can i use Render template with angular 2 ?
Thank you in advance
@felimartina : I've registered to this forum just to tell you how much I love you,
You just solved a problem that got me stuck for 3 days !
We need more small tutorials like that ! Thanks a lot
@felimartina : I also registered to this forum just to tell you that you are awesome.. Please tell me how can i freeze columns of a table using this. Please guide us more if you have a series of tutorials or youtube channel. Also please post the repo URL so we can better understand.
@simed
Sorry for late reply...what do you mean by Render template? If you mean how to custom render a column in datatables then it should be as easy as this:
columns: [
{ title: 'First Name', data: 'firstName' },
{ title: 'Last Name', data: 'lastName' },
{ title: 'Email', data: 'email' },
{ title: 'Phone Number', data: 'phone' },
{
title: 'Birth Date',
data: 'dob',
render: function (data, type, row) {
return moment(row.dob).format('MM/DD/YYYY');
}
},
{
title: 'Status',
data: 'disabled',
render: function (data, type, row) {
let html = '';
if (row.disabled) {
html = ' <span class="label label-danger">DISABLED</span>';
} else {
html = ' <span class="label label-success">ACTIVE</span>';
}
if (row.isAdmin) {
html += ' <span class="label label-primary">IS ADMIN</span>';
}
return html;
}
}
],
I hope it helps...please let me know!
@felimartina
The on method is never getting called. I am using the below to color the selected rows.
I want to select rows and then press a button which would make an ajax call to delete the data to the server. I want to use the on the method but it's never getting called.
Hi,
Good day.
Anybody have a working fiddle? Been struggling to get this to work. Thanks.
Regards.
JJ