Skip to content

Instantly share code, notes, and snippets.

@craigh411
Last active October 2, 2015 13:54
Show Gist options
  • Save craigh411/c7085b2db5b0172a939f to your computer and use it in GitHub Desktop.
Save craigh411/c7085b2db5b0172a939f to your computer and use it in GitHub Desktop.
Knockout binding handler for sortable table rows using jQuery UI.

Create Sortable Table rows using KnockoutJS and jQuery UI

Custom binding handler for sorting table rows. It overrides the helper option of jQuery sortable to make sure that the table row

keeps it's width and attempts to set the correct background colour for the helper, however, background can be set by passing in the helperBg parameter:

<table data-bind="sortableTable: {'helperBg': '#000000'}">

Basic Usage:

It will allow sorting on all rows in the <tbody></tbody> section of the table, so this tag is required!

<table data-bind="sortableTable">
  <thead>
    <tr>
      <th>Table Header</th>
       <th>Table Header</th>
    </tr>
  </thead>
  <tbody>
      <tr>
        <td>Sortable Table Row</td>
        <td>Sortable Table Row</td>
    </tr>
    <tr>
        <td>Sortable Table Row</td>
        <td>Sortable Table Row</td>
    </tr>
  </tbody>
</table>

Setting sortable options

To set your options you can bind sortOptions to the same data-bind attribute:

<table data-bind = "sortableTable, sortOptions: {start: function(){console.log('Sort Started');}}">

However, it's better to put this logic in your viewModel:

var MyViewModel = function() {
	var self = this;

  self.sortOptions = function(){
    return {
      start: function(e,ui){
        console.log('Sort Starting');
      },
      stop: function(e,ui){
        console.log('Sort Stopped');
      }
    };
  };
}

ko.applyBindings(new MyViewModel());

This can then be bound like so:

<table data-bind="sortableTable, sortOptions: $root.sortOptions">

See: JSFiddle for a working example.

For a full list of available options see: jQuery UI Sortable

(function ($, ko) {
ko.bindingHandlers.sortableTable = {
init: function (element, valueAccessor, allBindingsAccessor) {
var values = valueAccessor() || {};
var defaultBg = $(element).find('tbody tr td').css('background-color');
if (defaultBg == 'rgba(0, 0, 0, 0)') {
defaultBg = $(element).closest('div').css('background-color');
}
var helperBg = values.helperBg || defaultBg;
var options = allBindingsAccessor().sortOptions || {};
options = $.extend({
helper: function (e, ui) {
var original = ui.children();
var helper = ui.clone();
helper.children().each(function (index) {
// Set helper cell sizes to match the original sizes
$(this).width(original.eq(index).width());
$(this).closest('tr').children('td').css('background-color', helperBg);
});
return helper;
}
}, options);
$(element).find('tbody').sortable(options);
}
};
}(jQuery, ko));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment