Search code examples
sortingdatatablepaginationalloy-ui

Table with aui-pagination and datatable-sort


I am using AlloyUI to display a table with pagination + datatable-sort. Problem: The data is sorted ONLY on the current page. Instead I want to sort all the data each time I click on a column and I want the user to be sent back to the first page.

How my code works: I divide my big table into small ones and link each table with a page.

Here is my code:

YUI().use('aui-datatable', 'aui-pagination', 'datatable-sort', function (Y) 
{  
    dataPages = [{ .... }, { ... }, ... , { ... }];   => contains 18 rows
    var columns = [
         { key: 'Tel', label: 'Tel', sortable: true },
           ...
         { key: 'Register', label: 'Register', sortable: true }
    ];

    var dataTable = new Y.DataTable( 
            { columns: columns, data: dataPages} 
                                     ).render('#DataTableConsult');
    new Y.Pagination(
            {contentBox: '#pagination .aui-pagination-content', page: 1,
                  on: { changeRequest: function (event) {
    var dataPageOne = new Array();    ... i fill in this first table with lines N° 0 to 6 of dataPages table
    var dataPageTwo = new Array();    ... i fill in this first table with lines N° 7 to 13 of dataPages table
    var dataPageThree = new Array();  ... i fill in this first table with lines N° 14 to 17 of dataPages table

   if (event.state.page === 1) { dataTable.set('data', dataPageOne); }
   else if (event.state.page === 2) { dataTable.set('data', dataPageTwo); }
   else if (event.state.page === 3) { dataTable.set('data', dataPageThree); }}}}).render();
});

Solution

  • You can make this work with a few changes:

    1. You need a hidden DataTable which contains all the data:

      var hiddenDataTable = new Y.DataTable({
          columns: columns,
          data: dataPages
      });
      
    2. Instead of listening to the Paginator's changeRequest event, listen to the pageChange event:

      on: { pageChange: function (event) { // ...
      
    3. In the pageChange function, set each page to a slice of the hiddenDataTable's data.

      var hiddentData = hiddenDataTable.get('data')._items;
      var dataPageOne = hiddentData.slice(0, 6);
      var dataPageTwo = hiddentData.slice(6, 12);
      var dataPageThree = hiddentData.slice(12, 18);
      
    4. Finally, listen for the sort event of the visible DataTable, and sort the hidden DataTable and set the page to 1:

      dataTable.on('sort', function (event) {
          hiddenDataTable.sort(event.sortBy);
          pagination.set('page', 1);
      });
      

    Once you do this, all data will be sorted every time you sort by a column, and the user will be sent to the first page. Here is a runnable example using your sample code:

    YUI().use('aui-datatable', 'aui-pagination', 'datatable-sort', function(Y) {
      var dataPages = [{
        Tel: '345678901',
        Register: '\x65\x66\x67\x68\x69\x70\x71\x72'
      }, {
        Tel: '456789012',
        Register: '\x66\x67\x68\x69\x70\x71\x72\x73'
      }, {
        Tel: '567890123',
        Register: '\x67\x68\x69\x70\x71\x72\x73\x74'
      }, {
        Tel: '678901234',
        Register: '\x68\x69\x70\x71\x72\x73\x74\x75'
      }, {
        Tel: '789012345',
        Register: '\x69\x70\x71\x72\x73\x74\x75\x76'
      }, {
        Tel: '890123456',
        Register: '\x70\x71\x72\x73\x74\x75\x76\x77'
      }, {
        Tel: '901234567',
        Register: '\x71\x72\x73\x74\x75\x76\x77\x78'
      }, {
        Tel: '012345678',
        Register: '\x72\x73\x74\x75\x76\x77\x78\x79'
      }, {
        Tel: '123456789',
        Register: '\x73\x74\x75\x76\x77\x78\x79\x80'
      }, {
        Tel: '234567890',
        Register: '\x74\x75\x76\x77\x78\x79\x80\x81'
      }, {
        Tel: '345678901',
        Register: '\x75\x76\x77\x78\x79\x80\x81\x82'
      }, {
        Tel: '456789012',
        Register: '\x76\x77\x78\x79\x80\x81\x82\x83'
      }, {
        Tel: '567890123',
        Register: '\x77\x78\x79\x80\x81\x82\x83\x84'
      }, {
        Tel: '321014567',
        Register: 'asdfasdf'
      }, {
        Tel: '786234567',
        Register: 'zxcvsdfg'
      }, {
        Tel: '451234567',
        Register: 'rtyucvbn'
      }, {
        Tel: '678901234',
        Register: '\x78\x79\x80\x81\x82\x83\x84\x85'
      }, {
        Tel: '789012345',
        Register: '\x79\x80\x81\x82\x83\x84\x85\x86'
      }, {
        Tel: '890123456',
        Register: '\x80\x81\x82\x83\x84\x85\x86\x87'
      }, {
        Tel: '901234567',
        Register: '\x81\x82\x83\x84\x85\x86\x87\x88'
      }];
    
      var columns = [{
        key: 'Tel',
        label: 'Tel',
        sortable: true
      }, {
        key: 'Register',
        label: 'Register',
        sortable: true
      }];
    
      var hiddenDataTable = new Y.DataTable({
        columns: columns,
        data: dataPages
      });
    
      var dataTable = new Y.DataTable({
        columns: columns
      }).render('#DataTableConsult');
    
      var pagination = new Y.Pagination({
        contentBox: '#pagination .aui-pagination-content',
        page: 1,
        on: {
          pageChange: function(event) {
            var hiddentData = hiddenDataTable.get('data')._items;
            var dataPageOne = hiddentData.slice(0, 6);
            var dataPageTwo = hiddentData.slice(6, 12);
            var dataPageThree = hiddentData.slice(12, 18);
    
            if (event.newVal === 1) {
              dataTable.set('data', dataPageOne);
            } else if (event.newVal === 2) {
              dataTable.set('data', dataPageTwo);
            } else if (event.newVal === 3) {
              dataTable.set('data', dataPageThree);
            }
          }
        }
      }).render();
    
      dataTable.on('sort', function(event) {
        hiddenDataTable.sort(event.sortBy);
        pagination.set('page', 1);
      });
    });
    <script src="http://cdn.alloyui.com/2.0.0/aui/aui-min.js"></script>
    <link href="http://cdn.alloyui.com/2.0.0/aui-css/css/bootstrap.min.css" rel="stylesheet"></link>
    <div id="pagination">
      <ul class="pagination aui-pagination-content">
        <li><a href="#">Prev</a>
        </li>
        <li><a href="#">1</a>
        </li>
        <li><a href="#">2</a>
        </li>
        <li><a href="#">3</a>
        </li>
        <li><a href="#">Next</a>
        </li>
      </ul>
    </div>
    <div id="DataTableConsult"></div>

    Note: This method will not scale very well (because it sends all the data to the client), so I recommend doing this kind of sorting on the back end and sending only the current page to the client. Also, this does not seem very user friendly.