4

koGrid does not seem to be able to sort all items when there are multiple pages. It looks as though it only sorts the page being displayed when you click on a column header. When you go to the next (or any subsequent or previous) page, the data is not sorted according to the column you clicked. This is even the case in the "Server-Side Paging Example" given on the koGrid website:

http://ericmbarnard.github.com/KoGrid/#/examples

Has anyone gotten sorting working over multiple pages using koGrid?

Thank you.

function EmailBlastsViewModel() {
  // Data
  var self = this;

  self.blasts = ko.observableArray();
  self.selectedItems = ko.observableArray();
  self.status = ko.observable('queued');

  self.pagingOptions = {
    pageSizes: ko.observableArray([25, 50, 100]),
    pageSize: ko.observable(25),
    totalServerItems: ko.observable(),
    currentPage: ko.observable(1)
  }

  self.pagingOptions.currentPage.subscribe(function(data) {
    self.reload();
  });

  self.pagingOptions.pageSize.subscribe(function(data) {
    self.reload();
  });

  self.gridOptions = {
    displaySelectionCheckbox: true,
    data : self.blasts,
    selectedItems: self.selectedItems,
    multiSelect: false,
    pagingOptions: self.pagingOptions,
    enablePaging: true,
    columnDefs: [
      { field: 'creator.name', displayName: 'From', width: 105 },
      { field: 'to_name', displayName: 'To', width: 105 },
      { field: 'subject', displayName: 'Subject', width: 160 },
      { field: 'status', displayName: 'Status', width: 132 },
      { field: 'date_scheduled', displayName: 'Date Scheduled', width: 160 },
      { field: 'date_sent', displayName: 'Date Sent', width: 160 },
      { displayName: ' ', cellTemplate: $('#cell-template').html(), width: 40 }
    ]
  }

  self.allMail = function(item, event) {
    self.status(null);
    self.reload()
  }

  self.queuedMail = function(item, event) {
    self.status('queued');
    self.reload()
  }

  self.sentMail = function(item, event) {
    self.status('sent');
    self.reload();
  }


  self.archiveEmail = function(item, event) {
    var email = self.selectedItems()[0];
    email.archive();
  }

  self.approveEmail = function(item, event) {
    var email = self.selectedItems()[0];
    email.approve();
  }

  self.rejectEmail = function(item, event) {
    var email = self.selectedItems()[0];
    email.reject();
  }

  self.deleteEmail = function(item, event) {
    var email = self.selectedItems()[0];
    email.deleteEmail();
  }


  self.reload = function() {
    var spinner = new Spinner().spin(document.getElementById('spin'));

    var data = {
      'page' : self.pagingOptions.currentPage(),
      'limit' : self.pagingOptions.pageSize()
    }

    if( self.status() ) {
      data['status'] = self.status()
    }

    $.ajax({
      type: "GET",
      data: data,
      cache: false,
      url: "/api/emailblast",
      contentType: "application/json",
      success: function(data, textStatus, jqXHR) {
        spinner.stop();

        var newData = [];

        $.each(data.results, function(index, value){
          var eb = new EmailBlast(self, value);
          newData.push( eb );
        })
        self.blasts( newData );
        self.pagingOptions.totalServerItems(data.total);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        spinner.stop();
        noty({text: 'There was an error retrieving the email blasts.', type: 'error', timeout: 5000});
      }
    });
  }

  // Initialization
  self.init = function() {
    self.reload();
  }
  self.init();

};

emailBlastsViewModel = new EmailBlastsViewModel();
ko.applyBindings(emailBlastsViewModel);
Jim Remedios
  • 41
  • 1
  • 5

1 Answers1

2

Some of your KO Model

self.sortInfo = ko.observable();
    self.sortOnServer = ko.observable(false);
    self.sortInfo.subscribe(function (data) {
        self.sortOnServer(!self.sortOnServer());
        if (!self.sortOnServer()) return;
        paginationInfo.SortColumnName = self.sortInfo().column.field;
        if (self.sortInfo().direction === 'desc') {
            paginationInfo.DescendingSort = true;
        } else {
            paginationInfo.DescendingSort = false;
        }
        showLoading();
        self.getPagedDataAsync(self.pagingOptions.pageSize(), self.pagingOptions.currentPage(), self.filterOptions.filterText());
    });

self.gridOptions = {
        data: self.results,
        enablePaging: true,
        pagingOptions: self.pagingOptions,
        filterOptions: self.filterOptions,
        columnDefs: self.columns,
        displaySelectionCheckbox: false,
        rowHeight: 20,
        selectWithCheckboxOnly: true,
        jqueryUIDraggable: true,
        useExternalSorting: true,
        sortInfo: self.sortInfo
    };

HTML

<div id="grid" class="gridStyle" data-bind="koGrid: gridOptions">
        </div>

This code will use the sortInfo observable to update field and direction information when the header is clicked. I had to add a hack to it because the subscribe is called twice. This is a known bug, https://github.com/Knockout-Contrib/KoGrid/issues/174. Basically the hack uses the sortOnServer observable and whenever it is true it will send the call to the server.

The paginationInfo is an object I created to transport information to the server.

segFault
  • 1,228
  • 2
  • 18
  • 41
  • Thank you for your reply. I tried making the changes as you suggested but with no luck. I just went back an added my original code (without your suggestions) to my posting. Maybe this will clarify why things are not working. – Jim Remedios Mar 29 '13 at 20:35
  • I am implementing a sort on the server. It is not possible for the koGrid to sort all rows on multiple pages when using paging because it only has the page being displayed. – segFault Mar 29 '13 at 22:07
  • Okay. Thank you for your insight anyway. – Jim Remedios Apr 01 '13 at 23:17