It happens in many projects that you start out with a rather simple table to give your client an overview of some entity, say users. When the project evolves, the number of columns changes and at some point, the client requires the table to be sortable, searchable and so on. My first pick for such a table is the neat Datatables plugin.
Datatables requires jQuery and has a very large set of options and capabilities so it may take a while to know how it works exactly. Fortunately, there is a lot of documentation and a helpful support forum.
In a recent project I had to use Datatables to sort a column with dates in the format dd-mm-yyyy (the default date format in the Netherlands). Additionally, the assets are compiled with Webpack and ES6 imports are used in this project. I made it work, but it took me quite some time to find out how to do it.
I wondered whether it is possible to use this plugin in a Vue table component. It turns out this is not so complicated once you know how to do it. I’ll summarize what I have done for you and my future self 😉
In addition, I found the Tabulator project in a newsletter and the Vue plugin for it. I gave it a try and it works very Vue-ish and I definitely advice using this plugin over Datatables in a Vue project.
You can find all code in this sample project on Github. Just clone or download it, install dependencies and give it a go!
Sample project setup
I have set up a new project using the Vue CLI graphical user interface by typing ‘vue ui’ in the terminal. I configured the project manually and only took the babel plugin to start. After running the task serve, which installs the required node_modules, I installed the following dependencies one by one via the UI:
In addition, I like to use the Font Awesome (v4) icons so I downloaded the css file from the website, added it to my src folder manually and imported it in the main.js file.
The last step was to remove the Hello World sample component.
Sortable Datatable component
I create a new component in the components folder, called SortableDatatable.vue. The template is rather simple, it contains a container div with a table holding some hardcoded data. For the purpose of this demo, the table contains user data with names, locations, dates of birth and last login dates.
The script part of the component is the most interesting. Since datatables depends on jQuery to be available as $, importing jQuery goes like this
import $ from ‘jquery’
Then I import datatables itself, followed by moment and the datatables plugin for sorting. Note that the datatables.net-plugins module contains all kinds of handy plugins to extend the behavior of datatables (filtering, internationalization, pagination to name a few).
According to the docs of the ‘date sorting with moment’ plugin, for each date column a format is required to tell Datatables how to sort it. If these lines are omitted, normal alphabetical sorting is applied which yields wrong results if the dates are in the format used here. In this example there are two date columns with dates in the format dd-mm-yyyy and in normal English (e.g., Tuesday, September 10 2019) respectively. Hence, we need to add two formats. The moment docs give us all we need, and formats are defined as follows:
$.fn.dataTable.moment('DD-MM-YYYY'); $.fn.dataTable.moment('dddd, MMMM D YYYY');
Finally, the Datatables plugin is instantiated in the mounted hook of the component.
Basically this is all we need for correct date sorting, when modules are imported using the ES6 syntax.
The SortableDatatable component can be found in the project on Github.
And now we do it the Vue way
I found out about this project Tabulator last week and this demo is a perfect place to try the Vue plugin that comes with it. This way we can remove our dependency on jQuery. Moreover, with vue-tabulator, as the package is called, things go the Vue way.
First install the package with
npm install --save vue-tabulator
and import it in your main.js file and make it ‘usable’:
import VueTabulator from vue-tabulator Vue.use(VueTabulator)
I create the table component SortableTabulator and import it in App.vue (not shown).
To be able to use the default styling of VueTabulator the default stylesheet is imported in App.vue. However, since the stylesheet is a .scss file, node-sass and sass-loader are required as dependencies of our project.
Once the setup is done, the template part of the SortableTabulator is extremely simple. Again, I create some dummy data and set up the VueTabulator component with some options.
The data should be an array of objects. Each object resembles one row in the table and each property of this object corresponds to a column.
This package also comes with a lot of options, but I’ll keep it as simple as possible in this example. You have to define a height for the table. If you choose it too small, some rows will not be displayed. For my small table I chose a height of 500px. Furthermore, a layout property was added with value ‘fitColumns’ to fit all columns nicely over the available width.
The most important property is ‘columns’. If you leave it out, the package will try to figure it all out by itself, but with the current sorting requirements, it is better to be explicit about the columns. The columns property is also an array of objects and describes the columns of the table. The title property is used for the header row of the table, the field property should match the name of the column used as properties in the data array.
The default sorting algorithm assumes that the content of the column is a string (as in the datatables plugin), but in this situation the properties ‘sorter’ and ‘sorterParams’ are required. Since the moment.js library is already available I just set the correct format for sorting and we are good to go.
You can find the full component on Github.
In this post I have shown two ways of adding date sorting to a table in a Vue CLI project. The first approach using jQuery and Datatables.net works fine but feels a bit old fashioned. It does the job and it works nicely, but it simply does not feel like working in Vue.
The second approach felt a lot more natural by using Vue’s data binding and a plugin created to work with Vue. My advice is to use VueTabulator in a Vue project.
For the sake of this post I kept the table data to a minimum. There are all kinds of extensions and improvements possible:
- $.fn.dataTable.moment(format) takes a second argument, a locale (e.g., ‘nl’) to make this work for dates in your preferred language.
- Table data is hardcoded in these examples but it is simple enough to add some logic to read the data from a server.
I’ll end with a quick note on the performance of moment.js which we depend heavily on in this example. It is a rather large module due to all the i18n files that are loaded out of the box. Most projects will only use a few languages at most and the bundle size of your compiled app can be reduced significantly by not bundling all those language files. Have a look at my vue.config.js file to see how simple it is to ignore all locale files. If you still need to import one, have a look at main.js where the commented lines 9-12 show how to import a locale. I found this handy trick by first reading this and consequently by following moment’s docs and arriving here.