Data table pagination

This post was planned to show the custom pagination that we created to the jQuery DataTable. At first we had only one custom pagination. A unique pagination.

We created a function to create pagination with 4 callbacks. Callbacks for getting the next and previous pages and hasNextPage, hasPreviousPage. These callbacks communicate directly with functions of the angular controller. Which functions call the server to get the new data of one page according to the actual settings.

But meanwhile I write these blog posts the data table implementation has changed according to the new requirements.
After using this version of pagination we had two projects where we wanted to use the features of our data table implementations but with other pagination without server side connection. It was not so easy because some other parts of our earlier implementation was based on this custom pagination and removing this one and using the original pagination of the jQuery DataTable was not available.

Now we have two custom types of pagination. : )

In this post we will go through the steps of creating own pagination. After reading this post hopefully you will be able to create easily and fast your own pagination. If you know the principles of it, it isn’t a big deal anymore.

Where to start?

The place where you can define the pagination type of the data table is the creation method of it:

                    var table = $(tableId).dataTable({
                        "aoColumns": headerTitles,
                        "aaData": rows,
                        "iDisplayLength": pageSize,
                        "fnInfoCallback": onInfoChanged,
                        "sPaginationType": pagination, 	//my implementation in dataTablesExtensions
                        ...
                    });

“pagination” here is only a string. The name of the pagination. This name is the registered function name what we selected to our pagination. It needs to be unique and we have to be careful not to choose same names that are already defined to the jQuery DataTable. We used the “my_” prefix to our implementations.

How to define?

We need to register our pagination objects to the jQuery DataTable’s implementation and we can use the following way to do that:

$.fn.dataTableExt.oPagination.my_button_name = {…};

We can define this pagination where we want. We choose a separated dataTableExtensions js file but it can be defined in the same file as the data table creation file or you can place it anywhere you want.

The registered pagination needs to have two functions:

  • fnInit – To initialize DOM elements required for pagination with a list of the pages, called only at initialization time
  • fnUpdate – To update the list of page buttons, called after every change of the data table

fnInit

fnInit : function ( oSettings, nPaging, fnCallbackDraw ) {...}

In this function we get the nPaging as the second parameter. This is the UI section where we want to add our buttons.

In our both implementation we use the ul-li-a combination of controls to have the required Twitter Bootstrap style.

blogpost

We used jQuery to create the UI elements and append to each other.

var pager = $('<ul class="pager">').appendTo(nPaging);

            console.log(pager);

            var nPreviousWrapper = $('<li id="previousPager">').appendTo(pager);//.addClass("paginate_enabled_previous");
            var nNextWrapper = $('<li id="nextPager">').appendTo(pager);//.addClass("paginate_enabled_next");

            var nPrevious = $('<a>').text("Previous").appendTo(nPreviousWrapper);
            var nNext = $('<a>').text("Next").appendTo(nNextWrapper);

Now we have the UI elements and we need to add the functionality to the “buttons” we defined.

One way is to append our callback functions to them.

            //click event subscribe on previous
            nPrevious.click(previousCallback);

            //click event subscribe on next
            nNext.click(nextCallback);

Or you can use the original implementation to get the original pagination functionality. (with custom styled UI)

            oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
            oSettings.oApi._fnBindAction( nNext,     {action: "next"},     fnClickHandler );

In both example the nPrevious and the nNext are the jQuery elements we defined.

In the first version we register the callbacks to the click events of the “buttons”.
In the other version we use the original mechanism of the jQuery DataTable. You can create the fnClickHandler using the oSettings, first parameter of the fnInit function and the fnCallbackDraw, the third parameter of the fnInit function.

fnUpdate

fnUpdate: function (oSettings) {...}

In both of our implementations we only wanted to show / hide the buttons according to the first / last page of the table. At the first page hide the previous button and at the last page hide the next button so easy. It is only a switch between two CSS classes. We created a helper method to do the switch according to the result of a callback.

(function ($) {
    $.fn.switchClass = function (conditionCallback, classA, classB) {

        var classToAdd;
        var classToRemove;

        if (conditionCallback()) {
            classToAdd = classA;
            classToRemove = classB;

        } else {
            classToAdd = classB;
            classToRemove = classA;
        }

        $(this).removeClass(classToRemove);
        $(this).addClass(classToAdd);
    };
})(jQuery);

With the callbacks I only check that we have a previous and/or next page and if one direction is not available I hide the button from the UI.

Tip

fnUpdate is called at the creation time too! It is important because you don’t have to add the default classes to the controls. fnUpdate will be called and add the right classes to the controls according to the actual state at initialization time as well.
First time there is no previous page so it hides the button from the user.

Sources

You can read about the principles of creating custom pagination in the documentation of the jQuery DataTable and you can check our implementation on github.

Advertisements

Data table in angular

A whole new extension from me! Download it, use it, rate it! Any feedback is welcomed!

banner

Have you ever found yourself in need of a fully customisable data table in an angular app?

No? – Than this is not the post you are looking for.

We needed one anyway.

So, first we started to look for a good data table implementation.
After some researching we found a pretty one, which is called DataTables.
It has many cool functions and it is well documented as well. But its best feature is that it is fully customisable. Exactly what we wanted!

How easy is the use the dataTable?
1. Create a <table> HTML tag with an id.
2. Write the following call inside your script.

$(document).ready(function() {
$('#theId').dataTable();
} );

3. Ready.

It looks cool and has a lot of built-in functionalities.

dataTables-original-table

So we had the base implementation but we had a lot of custom requirements for it:

  • We needed it as an angular.js directive.
  • We use Twitter Bootstrap to design our UI and to style the data table as well.
  • Custom header controls for many other filtering options.
  • Custom paging. We had the dodgiest requirement here.
    (To explain this it will be devoted a whole post.)
  • Custom row selection. Row selection and navigation with the arrow keys.
  • Custom controls for rows. Inline delete, edit options to rows.
  • Custom column hiding and sorting.

And we wanted all of this through a friendly API. How we succeeded?

Check the result!

The usage of my implementation in HTML:

&lt;div my-data-table
   my-source=&quot;dataSource&quot;
   refresh=&quot;refresh(data)&quot;
   header=&quot;headerControls&quot; //optional
   page-sizes=&quot;pageSizes&quot; //optional
   sorting-properties=&quot;sortingProperties&quot; //optional
   hiding-properties=&quot;hidingProperties&quot; //optional
   delete-row=&quot;deleteRow(item)&quot; //optional
   edit-row=&quot;editRow(item)&quot; //optional
   select-row=&quot;select(item)&quot; //optional
&gt;
&lt;/div&gt;

And the result looks like this:

dataTables-my-table

This sort blog post series will be about showing the main steps of the implementation.

My implementation with a small sample app is available on github. So you can check it out, download it and try it for yourself!

By reading the upcoming blog post you can get the big picture about the frameworks of the development. You can get the answers of the why?-s and how?-s.

Check the next post in this series!

Start up

This is my journey into the world of javascript,
but dear reader, I hope it will be our journey together!

It is a whole new world for me after working so much only with Microsoft related technologies,
I’m definitely ready to conquer it.

I started to be interested in javascript about one and a half years ago.
First, it was just about reading and playing with smaller examples, well, everybody has to start somewhere. But the more I learned about it, the more I felt gaps in my knowledge so I decided to change and put more effort on understanding such problems.

I have just changed my job, which gives me the possibility to work with javascript technologies in bigger projects. Solving programming puzzles and sucking with hard tasks in a real life project is the best way to learn and I did/do both. : )

This blog will be about my experiences gained during these project works.

There will be posts about almost everything from javascript world. About server side-, client side javascript, about no-sql and testing as well and so on.

I hope you will enjoy and of course learn from it!

Spoiler:
The first series will be about creating a data table as an angular.js directive including the use of jQuery and Twitter Bootstrap.