Backbone React Sortable Table

By Blaine Hatab | December 21, 2014

This screencast shows you how to make a sortable table using react and backbone with a custom react mixin and backbone sorting. It uses backbone react component to interface backbone to react.

Sort Mixin

This is the sort mixin that is used on the component that contains the sortable table. You could rewrite this slightly and move this to the sortable table if that makes more sense to you.

# /javascripts/mixins/

MyApp.Mixins.SortMixin =

  getInitialState: ->
    { sortAttribute: @props.collection.sortAttribute, sortDirection: @props.collection.sortDirection }

  sortCollection: (attr)->
      newSortDirection = 1
      if @state.sortAttribute == attr
        newSortDirection = @state.sortDirection * -1

      @setState(sortAttribute: attr, sortDirection: newSortDirection)

    sortedData: ->

      sortedData = @getCollection()

      sortedData.sortDirection = @state.sortDirection

User Collection

The user collection defines which fields are displayed in the table, the initial sorting attribute, and the initial sorting direction. It uses Backbone's comparator method to sort the collection and exposes a sortBy method for resorting.

# /javascripts/collections/

MyApp.Collections.Users = Backbone.Collection.extend
  url: ''
  model: MyApp.Models.User

  sortAttribute: 'name'
  sortDirection: 1

    'name' : 'Name'
    'website' : 'Website'

  sortBy: (attr) ->
    @sortAttribute = attr

  comparator: (a, b) ->
    a = a.get(@sortAttribute)
    b = b.get(@sortAttribute)

    return 0 if a is b 
    if @sortDirection is 1
      (if a > b then 1 else -1)
      (if a < b then 1 else -1)

Sortable Table Component

This is the sortable table component. It triggers the sortCollection method in the mixin when a th element is clicked. I use @getCollection() from backbone-react-component to get the sort attribute, sort types, and sort direction data so we don't have to pass those down as props.

# /javascripts/components/

{thead, table, tbody, th, td, tr, i} = React.DOM

SortableTable = React.createFactory React.createClass
  mixins: [Backbone.React.Component.mixin]

  sortCollection: (sort_key)->

  render: ->
    table className: 'table table-bordered table-hover',
      thead {}, @getCollection().sortTypes, (sortTitle, sortKey) =>
          th onClick: @sortCollection.bind(@, sortKey), key: sortKey,
            ' '
            if @getCollection().sortAttribute == sortKey
              if @getCollection().sortDirection == 1
                i className: 'fa fa-caret-down'
                i className: 'fa fa-caret-up'

      tbody {},
        @getCollection().map (model)=>
          tr key: model.get('id'),
   @getCollection().sortTypes, (sortTitle, sortKey) =>
              td key: sortKey, model.get(sortKey)

MyApp.Views.SortableTable = SortableTable

User Table Component

This is the table that is rendered into the page and contains the sortable table component. I use backbone's fetch method to get the data from the api url, which is defined in the user collection. Then I pass it into the component's props as collection so we can use backbone-react-component's @getCollection() method.

# /javascripts/components/

{div, p, h1} = React.DOM

UserTable = React.createFactory React.createClass
  mixins: [

  render: ->
    div className: 'row',
      div className: 'col-xs-12',
        h1 {}, 'Backbone React Sortable Table Screencast'
        MyApp.Views.SortableTable(data: @sortedData(), sortCollection: @sortCollection)

users = new MyApp.Collections.Users

users.fetch().done ->
  React.render UserTable(collection: users), document.getElementById('home-page-wrapper')







comments powered byDisqus