Using JQuery Server side datatables in ruby app and pagination shows blank page after 1st page
Asked Answered
G

0

32

I am using Jquery Server side datatables and am not able to get the pagination to work on pages 2+.

I have 200 records. The first page shows 50. When I click the pagination numbers at the bottom of the page it navigates to page 2, but page 2 is empty.

I am using non-serverside datatables in the same app (but another table) and it works fine.

In addition pagination, the select menu that chooses #of records to display per page is not working and column sorting is not working.

Search is working

I'm using: "1.12.4" Rails 5 DataTables 1.10.16

index.json.jbuilder

json.draw params[:draw]
json.recordsTotal @cooks.length
json.recordsFiltered @cooks.length
json.data do
  json.array! @paginated do |cook|
    json.DT_RowClass "js-cook-row js-cook-row-#{donor.id}"
    if browser.device.mobile?
      json.partial! 'cooks/mobile_data', cook: cook, project: @project
    else
      json.partial! 'cooks/desktop_data', cook: cook, project: @project
    end
  end
end

Page with table (slim)

table.table.table-striped.table-bordered.table-hover.js-cook-table.cooks-table.dataTables-example.small-font.kitchen-table id="#{table_id}" data-toggle="table" width="100%"
  thead
    tr
      - if source == RouteSourceConsts::WIZARD
        th.updated-th data-field="cook-checkbox"
      th.cook-category data-field="given" data-sortable="true" = t('cooks.table_title.given')
      th.cook-vendor data-field="cook_name" data-sortable="true" = t('cooks.table_title.name')
      th data-field="recipes" = t('cooks.table_title.recipes')
      th data-field="helper" data-sortable="true" = t('cooks.table_title.helper')
      th.status-info-th data-field="status" data-sortable="true" = t('cooks.table_title.status')
      - if source == RouteSourceConsts::WIZARD
        th data-field="contact_info" data-sortable="false" Info
        th.updated-th  data-field="updated" data-sortable="true" = t('cooks.table_title.updated')

  tbody.js-assignable-table-body

  javascript:
  $(document).ready(function () {
    var default_columns = [
      {data: "given", className: "cook-value-received"},
      {data: "cook_name", className: "cook-name"},
      {data: "recipes", className: "recipes-list", orderable: false},
      {data: "helper", className: "assignment-info.doer-info", orderable: true},
      {data: "status", className: "cook-status"}
    ];

    if (#{source == RouteSourceConsts::WIZARD}) {
      var columns = default_columns.concat([ {data: "contact_info", className: "cook-info"}, {data: "updated", className: "updated-at"}]);
      columns.unshift({data: "cook_checkbox"})
    } else {
      var columns = default_columns
    }
    if (#{source == RouteSourceConsts::WIZARD}) {
      var custom_options = {
        lengthMenu: [50, 100, 150],
      };
    } else {
      var custom_options = {lengthMenu: [50, 100, 150]};
    }
    var default_table_options = {
      autoWidth: false,
      serverSide: true,
      searching: true,
      searchDelay: 1000,
      paging: true,
      responsive: true,
      dom: '<"pull-left"l><"pull-right"f>t<"bottom"p><"clear">',
      pagingType: "full_numbers",
      language: {emptyTable: '', zeroRecords: ''},
      ajax: {
        url: "#{project_cooks_path(project, source: source, type: type)}",
        type: 'GET',
        data: function (data) {
          data.type_filter = $('select.js-cook-type-filter').val()
        }
      },
      drawCallback: function (_settings) {
        initializecookStatusSelect();
        var pagination = $(this).closest('.js-donation-tabs, .js-cooks-main-container').find('.dataTables_paginate');
        pagination.toggle(this.api().page.info().pages > 1);
      },
      headerCallback: function (_thead, _data, _start, _end, _display) {
        cells = $('##{table_id} th');
        $(cells[0]).removeClass('cook-value-received');
        $(cells[1]).removeClass('cook-name');
        $(cells[2]).removeClass('recipes-list');
        $(cells[3]).removeClass('assignment-info.doer-info');
        $(cells[4]).removeClass('cook-status');
        $(cells[5]).removeClass('cook-info');
        $(cells[6]).removeClass('updated-at');
      },
      columns: columns,
      order: []
    };
    $("##{table_id}").dataTable($.extend({}, default_table_options, custom_options));

    channel = pusher.subscribe('cooks-#{project.id}');
    channel.bind('update', function (_data) {
      $('##{table_id}').DataTable().rows().invalidate('data').draw(false);
    });

    channel = pusher.subscribe('cooks-#{project.id}');
    channel.bind('imported', function (_data) {
      $('##{table_id}').DataTable().rows().invalidate('data').draw(false);
    });
  });
Gebelein answered 13/4, 2018 at 0:26 Comment(10)
It'll probably have something to do with the Ajax response. Can you post it here, please. Take a look at this page, datatables.net/examples/server_side/simple.html, go to the Ajax tab, this is the response format that's expected.Jarret
This one would be a better example: datatables.net/examples/server_side/object_data.html - as it's using objects the same as you are.Jarret
{"draw":"3","recordsTotal":200,"recordsFiltered":200,"data":[]} This is the call on page 3 @JarretGebelein
I recently upgraded from rails 4.2 to rails 5.1Gebelein
is that data in your draw:3 really an empty array? If so, that would mean there's nothing to display.Jarret
@Jarret It's not really empty....each page has 50 results....all pages except #1 are turning up with "data" :[] but the data should have 50 results. Only page 1 has 50.Gebelein
@Jarret I mean, it's not empty in the DBGebelein
That's the cause of the problem, something with the server-side script not filling in the data array. I'm not familiar enough with that to be able to really help, but it doesn't look like it's doing any counting to consider the page length, or the page starting point.Jarret
@NothingToSeeHere, try to replicate the problem on a smaller scale, e.g., display 1 record per page, and get only 2 records from the server-side. To do that: 1. add default_table_options.pageLength: 1. 2. Inside ajax.data, set data.length = 2. Assuming that the error you described still persists, please post here the ajax request and response.Virus
@paginated is probably empty on pages 2, 3, etc. Either your app's controller failed to properly paginate the data, or maybe the controller isn't getting the correct page number or data offset. Try rubygems.org/gems/jbuilder_pagination_plus ?Ut

© 2022 - 2024 — McMap. All rights reserved.