Slickgrid + ModelBinder

by amorris

HTML

<script src="http://mleibman.github.com/SlickGrid/slick.core.js"></script>
<link rel="stylesheet" href="http://mleibman.github.com/SlickGrid/examples/examples.css">
<link rel="stylesheet" href="http://mleibman.github.com/SlickGrid/slick.grid.css">
<script src="http://mleibman.github.com/SlickGrid/lib/jquery.event.drag-2.0.min.js"></script>
<script src="http://mleibman.github.com/SlickGrid/slick.grid.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.modelbinder/0.1.3/Backbone.ModelBinder-min.js"></script>
<script src="https://raw.github.com/theironcook/Backbone.ModelBinder/master/Backbone.CollectionBinder.min.js"></script>
<h1>Slickgrid Example</h1>
<br/>
<div id="myGrid" style="width:400px;height:150px;"></div>

<div id="viewContent">
    
<script id="my-template" type="text/x-underscore-template">
    <table id="sales_table"  border="1" cellspacing="1" cellpadding="1" summary="table">
      <thead>
      <tr><th COLSPAN=4>Sales Table</th>
      <tr>
        <th>Year</th>
        <th>Sales</th>
        <th>Sales/PSF</th>
        <th>GSF</th>
      </tr></thead>
      <tbody>
        <tr>
            <td name="year"></td>
            <td><input type="text" name="sales"/></td>
            <td><input type="text" name="sales_psf"/></td>
            <td><input type="text" name="gsf"/></td>
        </tr>
      </tbody>
    </table>
</script>

CoffeeScript

$.app = $.app || {}
$.app.MyView = $.app.MyView || {}


grid1 = undefined
columns = [
  {id: "title", name: "Title", field: "title"},
  {id: "duration", name: "Duration", field: "duration"},
  {id: "%", name: "% Complete", field: "percentComplete"},
  {id: "start", name: "Start", field: "start"},
  {id: "finish", name: "Finish", field: "finish"},
  {id: "effort-driven", name: "Effort Driven", field: "effortDriven"}
]
options = { enableCellNavigation: true, enableColumnReorder: false}

$ ->
  data = []
  i = 0
  while i < 100
    data[i] =
      title: "Task " + i
      duration: "#{i%5} days"
      percentComplete: Math.round(Math.random() * 100)
      start: "01/0#{i%5}/2012"
      finish: "01/0#{i%5+5}/2012"
      effortDriven: (i % 5 is 0)
    i++
  grid1 = new Slick.Grid("#myGrid", data, columns, options)
  
  class MyObject extends Backbone.Model
    defaults:
      year: 1
      sales: 2000
      gsf: 100
      
    # Don't allow GSF < 1 to bypass division by zero errors.
    setGSF: (gsf) ->
      if gsf >= 1
        @set('gsf',gsf)
        return gsf
      else
        @set('gsf',1)
        return 1
      
        
  class MyView extends Backbone.View
    el: '#viewContent'
    template: _.template($('#my-template').html())
    
    initialize: ->
      @modelBinder = new Backbone.ModelBinder()
      @render
        
    close: ->
      @modelBinder.unbind()
        
    gsfConverter: (direction, value, attribute, model) =>
      if direction == 'ViewToModel'
        value = model.setGSF(value)
        # Since Sales hasn't changed, but Sales/PSF needs to be re-calculated,
        # we manually trigger the attribute binding, as per the discussion:
        # https://github.com/theironcook/Backbone.ModelBinder/issues/36
        @modelBinder._copyModelToView(@modelBinder._attributeBindings['sales'])
        return value
      else
        return value
        
    salesConverter: (direction, value, attribute, model) ->
      if direction == 'ViewToModel'
    ...