title: How to add/remove rows using SlickGrid
body: <p>How to write such functions and bind them to two buttons like "add row" and "remove row":</p>
  
  <p>The now working example code only support adding new row by editing on the blank bottom line.</p>
  
  <pre><code>&lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"&gt;
    &lt;title&gt;SlickGrid example 3: Editing&lt;/title&gt;
    &lt;link rel="stylesheet" href="../slick.grid.css" type="text/css"/&gt;
    &lt;link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/&gt;
    &lt;link rel="stylesheet" href="examples.css" type="text/css"/&gt;
    &lt;style&gt;
      .cell-title {
        font-weight: bold;
      }
  
      .cell-effort-driven {
        text-align: center;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;div style="position:relative"&gt;
    &lt;div style="width:600px;"&gt;
      &lt;div id="myGrid" style="width:100%;height:500px;"&gt;&lt;/div&gt;
    &lt;/div&gt;
  
    &lt;div class="options-panel"&gt;
      &lt;h2&gt;Demonstrates:&lt;/h2&gt;
      &lt;ul&gt;
        &lt;li&gt;adding basic keyboard navigation and editing&lt;/li&gt;
        &lt;li&gt;custom editors and validators&lt;/li&gt;
        &lt;li&gt;auto-edit settings&lt;/li&gt;
      &lt;/ul&gt;
  
      &lt;h2&gt;Options:&lt;/h2&gt;
      &lt;button onclick="grid.setOptions({autoEdit:true})"&gt;Auto-edit ON&lt;/button&gt;
      &amp;nbsp;
      &lt;button onclick="grid.setOptions({autoEdit:false})"&gt;Auto-edit OFF&lt;/button&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;script src="../lib/firebugx.js"&gt;&lt;/script&gt;
  
  &lt;script src="../lib/jquery-1.7.min.js"&gt;&lt;/script&gt;
  &lt;script src="../lib/jquery-ui-1.8.16.custom.min.js"&gt;&lt;/script&gt;
  &lt;script src="../lib/jquery.event.drag-2.0.min.js"&gt;&lt;/script&gt;
  
  &lt;script src="../slick.core.js"&gt;&lt;/script&gt;
  &lt;script src="../plugins/slick.cellrangedecorator.js"&gt;&lt;/script&gt;
  &lt;script src="../plugins/slick.cellrangeselector.js"&gt;&lt;/script&gt;
  &lt;script src="../plugins/slick.cellselectionmodel.js"&gt;&lt;/script&gt;
  &lt;script src="../slick.formatters.js"&gt;&lt;/script&gt;
  &lt;script src="../slick.editors.js"&gt;&lt;/script&gt;
  &lt;script src="../slick.grid.js"&gt;&lt;/script&gt;
  
  &lt;script&gt;
    function requiredFieldValidator(value) {
      if (value == null || value == undefined || !value.length) {
        return {valid: false, msg: "This is a required field"};
      } else {
        return {valid: true, msg: null};
      }
    }
  
    var grid;
    var data = [];
    var columns = [
      {id: "title", name: "Title", field: "title", width: 120, cssClass: "cell-title", editor: Slick.Editors.Text, validator: requiredFieldValidator},
      {id: "desc", name: "Description", field: "description", width: 100, editor: Slick.Editors.LongText},
      {id: "duration", name: "Duration", field: "duration", editor: Slick.Editors.Text},
      {id: "%", name: "% Complete", field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar, editor: Slick.Editors.PercentComplete},
      {id: "start", name: "Start", field: "start", minWidth: 60, editor: Slick.Editors.Date},
      {id: "finish", name: "Finish", field: "finish", minWidth: 60, editor: Slick.Editors.Date},
      {id: "effort-driven", name: "Effort Driven", width: 80, minWidth: 20, maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkmark, editor: Slick.Editors.Checkbox}
    ];
    var options = {
      editable: true,
      enableAddRow: true,
      enableCellNavigation: true,
      asyncEditorLoading: false,
      autoEdit: false
    };
  
    $(function () {
      for (var i = 0; i &lt; 500; i++) {
        var d = (data[i] = {});
  
        d["title"] = "Task " + i;
        d["description"] = "This is a sample task description.\n  It can be multiline";
        d["duration"] = "5 days";
        d["percentComplete"] = Math.round(Math.random() * 100);
        d["start"] = "01/01/2009";
        d["finish"] = "01/05/2009";
        d["effortDriven"] = (i % 5 == 0);
      }
  
      grid = new Slick.Grid("#myGrid", data, columns, options);
  
      grid.setSelectionModel(new Slick.CellSelectionModel());
  
      grid.onAddNewRow.subscribe(function (e, args) {
        var item = args.item;
        grid.invalidateRow(data.length);
        data.push(item);
        grid.updateRowCount();
        grid.render();
      });
    })
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>