PageRenderTime 51ms CodeModel.GetById 3ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 1ms

/index.html

https://github.com/rhinoman/backgrid
HTML | 1903 lines | 1785 code | 103 blank | 15 comment | 0 complexity | e1de209f884b16cb7de88602fba882fc MD5 | raw file
   1<!doctype html>
   2<!--
   3  backgrid
   4  http://github.com/wyuenho/backgrid
   5
   6  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
   7  Licensed under the MIT @license.
   8 -->
   9<html lang="en">
  10  <head>
  11    <meta charset="utf-8" />
  12    <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1" />
  13    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
  14    <meta name="keywords" content="backgrid,backgrid.js,backbone,backbone.js,datagrid,grid,paginator,javascript" />
  15    <meta name="description" content="A powerful widget set for building data grids with Backbone.js" />
  16
  17    <title>Backgrid.js - A powerful widget set for building data grids with Backbone.js</title>
  18
  19    <link rel="canonical" href="http://backgridjs.com" />
  20
  21    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap.min.css" />
  22    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap-responsive.min.css" />
  23    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/select2/3.3.2/select2.min.css" />
  24    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/codemirror.min.css" />
  25    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/ambiance.min.css" />
  26    <link rel="stylesheet" href="lib/backgrid.min.css" />
  27    <link rel="stylesheet" href="lib/extensions/paginator/backgrid-paginator.min.css" />
  28    <link rel="stylesheet" href="lib/extensions/text-cell/backgrid-text-cell.min.css" />
  29    <link rel="stylesheet" href="lib/extensions/moment-cell/backgrid-moment-cell.min.css" />
  30    <link rel="stylesheet" href="lib/extensions/select2-cell/backgrid-select2-cell.min.css" />
  31    <link rel="stylesheet" href="lib/extensions/select-all/backgrid-select-all.min.css" />
  32    <link rel="stylesheet" href="lib/extensions/filter/backgrid-filter.min.css" />
  33    <link rel="stylesheet" href="assets/css/doc.css" />
  34    <!--[if lt IE 9]>
  35        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
  36        <![endif]-->
  37  </head>
  38  <body>
  39    <div id="main">
  40      <header>
  41        <div class="navbar navbar-fixed-top">
  42          <div class="navbar-inner">
  43            <div class="container">
  44              <a href="."
  45                 class="brand" title="A powerful widget set for building data grids with Backbone.js">Backgrid.js</a>
  46              <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
  47                <span class="icon-bar"></span>
  48                <span class="icon-bar"></span>
  49                <span class="icon-bar"></span>
  50              </a>
  51              <div class="nav-collapse collapse">
  52                <ul class="nav nav-pills">
  53                  <li class="dropdown">
  54                    <a class="dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
  55                      Introduction
  56                      <b class="caret"></b>
  57                    </a>
  58                    <ul class="dropdown-menu">
  59                      <li><a href="#features">Features</a></li>
  60                      <li><a href="#getting-started">Getting Started</a></li>
  61                      <li><a href="#examples">Examples</a></li>
  62                    </ul>
  63                  </li>
  64                  <li class="dropdown">
  65                    <a class="dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
  66                      API Reference
  67                      <b class="caret"></b>
  68                    </a>
  69                    <ul class="dropdown-menu">
  70                      <li><a href="#api-grid">Grid</a></li>
  71                      <li><a href="#api-column">Column</a></li>
  72                      <li><a href="#api-cell">Cell</a></li>
  73                      <li><a href="#api-formatter">Formatter</a></li>
  74                      <li><a href="#api-header">Header</a></li>
  75                      <li><a href="#api-row">Row</a></li>
  76                      <li><a href="#api-body">Body</a></li>
  77                      <li><a href="#api-footer">Footer</a></li>
  78                      <li class="divider"></li>
  79                      <li><a href="#extensions"><strong class="muted">Extensions</strong></a></li>
  80                      <li class="divider"></li>
  81                      <li><a href="#api-select-all">SelectAll</a></li>
  82                      <li><a href="#api-paginator">Paginator</a></li>
  83                      <li><a href="#api-filter">Filter</a></li>
  84                      <li><a href="#api-text-cell">TextCell</a></li>
  85                      <li><a href="#api-moment-cell">MomentCell</a></li>
  86                      <li><a href="#api-select2-cell">Select2Cell</a></li>
  87                    </ul>
  88                  </li>
  89                  <li class="dropdown">
  90                    <a class="dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
  91                      More Info
  92                      <b class="caret"></b>
  93                    </a>
  94                    <ul class="dropdown-menu">
  95                      <li><a href="#styling">Styling</a></li>
  96                      <li class="divider"></li>
  97                      <li><a href="#faq">FAQ</a></li>
  98                      <li><a href="https://github.com/wyuenho/backgrid/blob/master/CHANGELOG.md" target="_blank">Change Log</a></li>
  99                      <li><a href="#license">License</a></li>
 100                    </ul>
 101                  </li>
 102                  <li id="social-media">
 103                    <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://backgridjs.com" data-counturl="wyuenho.github.com/backgrid" data-via="wong_jim" data-hashtags="backgridjs,backbone_js">Tweet</a>
 104                    <div class="g-plusone" data-size="medium"></div>
 105                    <iframe src="http://ghbtns.com/github-btn.html?user=wyuenho&repo=backgrid&type=watch&count=true"
 106                            allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
 107                    <a href="https://coderwall.com/wyuenho"><img alt="Endorse wyuenho on Coderwall" src="http://api.coderwall.com/wyuenho/endorsecount.png" /></a>
 108                    <iframe allowtransparency="true" frameborder="0" scrolling="no"
 109                            style="border: 0; margin: 0 0 0 15px; padding: 0;"
 110                            src="https://www.gittip.com/wyuenho/widget.html" width="48pt" height="22pt"></iframe>
 111                  </li>
 112                </ul>
 113              </div>
 114            </div>
 115            <a class="visible-desktop" href="https://github.com/wyuenho/backgrid">
 116              <img style="position: absolute; top: 0; right: 0; border: 0;" src="assets/img/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub">
 117            </a>
 118          </div>
 119        </div>
 120      </header>
 121      <div class="container">
 122        <section class="hero-unit">
 123          <h1>Backgrid.js</h1>
 124          <p class="lead">
 125            Backgrid.js is a set of components for
 126            building <strong>semantic</strong> and <strong>easily
 127            stylable</strong> <strong>data grid</strong> widgets.</p>
 128          <p class="lead">It offers a simple, intuitive
 129              programming interface that makes easy things easy, but <em>hard things possible</em>
 130              when dealing with tabular data.</p>
 131          <p>
 132            <div class="btn-group">
 133              <a class="btn btn-large btn-success" href="#examples">See Examples</a>
 134              <a class="btn btn-large btn-primary hidden-phone hidden-tablet"
 135                 href="https://github.com/wyuenho/backgrid/tags">Download v0.2.6</a>
 136              <a class="btn btn-large btn-info"
 137                 href="https://github.com/wyuenho/backgrid/blob/0.2.6/CHANGELOG.md">What's new?</a>
 138            </div>
 139          </p>
 140        </section>
 141        <div id="features">
 142          <div class="page-header">
 143            <h1>Features</h1>
 144            <p>The goal of Backgrid.js is to produce a set of core Backbone UI
 145              elements that offer you all the basic displaying, sorting and
 146              editing functionalities you&apos;d expect, and to create an
 147              elegant API that makes extending Backgrid.js with extra
 148              functionalities easy.</p>
 149          </div>
 150          <div class="row-fluid">
 151            <div class="span6">
 152              <h2>Advantages</h2>
 153              <ul>
 154                <li>No Hungarian notations.</li>
 155                <li>Solid foundation. Based
 156                  on <a href="http://backbonejs.org">Backbone.js</a>.</li>
 157                <li>Semantic and <a href="#styling">easily stylable</a>. Just
 158                  style with plain CSS like you would a normal HTML table.</li>
 159                <li>Low learning curve. Works with plain old Backbone models and
 160                  collections. Easy things are easy, hards things possible.</li>
 161                <li>Highly modular and customizable. Componenets are just simple
 162                  Backbone View classes, customization is easy if you already
 163                  know Backbone.</li>
 164                <li>Lightweight. Extra features are separated
 165                  into <a href="#extensions">extensions</a>, which keeps the
 166                  bloat away.</li>
 167                <li>Good documentation.</li>
 168                <li>Well tested. Comes with <a href="test/" title="Jasmine Tests">100s of test cases</a>.</li>
 169              </ul>
 170            </div>
 171            <div class="span6">
 172              <h2>Supported browsers: <b style="font-size: 14px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: normal;">[1]</b></h2>
 173              <ul>
 174                <li>Internet Explorer 8+</li>
 175                <li>Chrome 4+</li>
 176                <li>Safari 4+</li>
 177                <li>Firefox 4+</li>
 178                <li>Opera 9+</li>
 179              </ul>
 180              <aside class="note">
 181                <h3>Notes:</h3>
 182                <div>1. Both the desktop and mobile versions of the above browsers are supported.</div>
 183              </aside>
 184            </div>
 185          </div>
 186        </div>
 187        <section id="getting-started">
 188          <div class="page-header">
 189            <h1>Getting Started</h1>
 190          </div>
 191          <div class="row-fluid">
 192            <div class="span6">
 193              <p>
 194                Backgrid.js depends on 3 libraries to function:
 195              </p>
 196              <ul>
 197                <li><a href="http://jquery.com">jquery &gt;= 1.7.0</a></li>
 198                <li><a href="http://underscorejs.org">underscore.js ~ 1.4.0</a></li>
 199                <li><a href="http://backbonejs.org">backbone.js >= 0.9.10</a></li>
 200              </ul>
 201              <aside class="note">
 202                <h5>Note:</h5> If you don&apos;t care about having the latest
 203                versions of the dependencies, you can use the bundled libraries
 204                in the download package.
 205              </aside>
 206            </div>
 207            <div class="span6">
 208              <p>
 209                Something like the following will get
 210                the <strong>Backgrid.js</strong> core loaded:
 211              </p>
 212              <textarea class="code-snippet" data-mode="htmlmixed">
 213                &lt;link rel="stylesheet" href="lib/backgrid.css" /&gt;
 214                &lt;script src="assets/js/jquery.js"&gt;&lt;/script&gt;
 215                &lt;script src="assets/js/underscore.js"&gt;&lt;/script&gt;
 216                &lt;script src="assets/js/backbone.js"&gt;&lt;/script&gt;
 217                &lt;script src="lib/backgrid.js"&gt;&lt;/script&gt;</textarea>
 218              <p>Adjust the paths as needed.</p>
 219            </div>
 220          </div>
 221        </section>
 222        <section id="examples">
 223          <div class="page-header">
 224            <h1>Examples</h1>
 225          </div>
 226          <div class="row-fluid">
 227            <div class="span12">
 228              <div class="row-fluid">
 229                <div class="span6">
 230                  <h2>Collection and Model</h2>
 231                  <p>Before you can display any tabular data in a grid, you must
 232                    first obtain the data.</p>
 233                  <p>At the most basic level, Backgrid pretends that every row
 234                    is a model object and the whole table is backed by a simple
 235                    Backbone collection.</p>
 236                  <p>Suppose we have a list of territory info objects:</p>
 237                </div>
 238                <div class="span6">
 239                  <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
 240                    var Territory = Backbone.Model.extend({});
 241
 242                    var Territories = Backbone.Collection.extend({
 243                      model: Territory,
 244                      url: "examples/territories.json"
 245                    });
 246
 247                    var territories = new Territories();</textarea>
 248                </div>
 249              </div>
 250              <div class="row-fluid">
 251                <div class="span12">
 252                  <h2 id="example-1">Grid</h2>
 253                  <p>
 254                    The main entry point of the Backgrid package is the
 255                    Backgrid.Grid class. You can create a default Backgrid by
 256                    first defining some columns, and then put that list of
 257                    columns and the collection of data into the Grid constructor
 258                    like this:
 259                  </p>
 260                  <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
 261                    var columns = [{
 262                      name: "id", // The key of the model attribute
 263                      label: "ID", // The name to display in the header
 264                      editable: false, // By default every cell in a column is editable, but *ID* shouldn&apos;t be
 265                      // Defines a cell type, and ID is displayed as an integer without the &apos;,&apos; separating 1000s.
 266                      cell: Backgrid.IntegerCell.extend({
 267                        orderSeparator: &apos;&apos;
 268                      })
 269                    }, {
 270                      name: "name",
 271                      label: "Name",
 272                      // The cell type can be a reference of a Backgrid.Cell subclass, any Backgrid.Cell subclass instances like *id* above, or a string
 273                      cell: "string" // This is converted to "StringCell" and a corresponding class in the Backgrid package namespace is looked up
 274                    }, {
 275                      name: "pop",
 276                      label: "Population",
 277                      cell: "integer" // An integer cell is a number cell that displays humanized integers
 278                    }, {
 279                      name: "percentage",
 280                      label: "% of World Population",
 281                      cell: "number" // A cell type for floating point value, defaults to have a precision 2 decimal numbers
 282                    }, {
 283                      name: "date",
 284                      label: "Date",
 285                      cell: "date",
 286                    }, {
 287                      name: "url",
 288                      label: "URL",
 289                      cell: "uri" // Renders the value in an HTML anchor element
 290                    }];
 291
 292                    // Initialize a new Grid instance
 293                    var grid = new Backgrid.Grid({
 294                      columns: columns,
 295                      collection: territories
 296                    });
 297
 298                    // Render the grid and attach the root to your HTML document
 299                    $("#example-1-result").append(grid.render().$el);
 300
 301                    // Fetch some countries from the url
 302                    territories.fetch({reset: true});</textarea>
 303                </div>
 304              </div>
 305              <div class="row-fluid">
 306                <div class="span12">
 307                  <h3>Result</h3>
 308                  <div id="example-1-result" class="backgrid-container"></div>
 309                  <aside class="note">See <a href="http://en.wikipedia.org/wiki/List_of_countries_by_population">Wikipedia</a></aside>
 310                  <br />
 311                  <p>The list of column definitions Backgrid.Grid expects is
 312                    simply a list of JSON objects, which you can hardcode into
 313                    your HTML templates or retrieve from a server when the DOM
 314                    is ready. Backgrid.js doesn&apos;t care where the column
 315                    definitions come from, as long as you supply the list to the
 316                    Grid constructor.</p>
 317                  <p>As expected, you now have a basic editable data grid
 318                    displayed. All the columns headers are labeled and sortable by
 319                    default. ID cells are not editable, and all other cell types
 320                    have reasonable validation built in. If the table gets too
 321                    large, you get a scroll bar.</p>
 322                  <p>Backgrid.js comes with <a href="#api-cell" title="Cells">10
 323                      basic cell types</a> in the core
 324                      and <a href="#api-text-cell" title="TextCell">many others
 325                      as extensions</a>. Cell types such as
 326                    <a href="#api-select2-cell"
 327                       title="Select2Cell">Select2Cell</a>
 328                       and <a href="#api-moment-cell"
 329                       title="MomentCell">MomentCell</a> give you a much richer
 330                       editing interface for option lists and datetime values on
 331                       desktop browsers. In addition, there&apos;s a wide range
 332                       of possibilities with how the data is converted for
 333                       display and persistence by using <a href="#api-formatter"
 334                       title="Formatter">formatters</a> or
 335                       customizing <a href="#api-cell">cell classes</a>.</p>
 336                </div>
 337              </div>
 338              <div class="row-fluid">
 339                <div class="span12">
 340                  <h2 id="example-2">A More Complete Example</h2>
 341                  <p>If you have a large result set like the above, you&apos;d
 342                    probably want to be able to paginate and filter your
 343                    results. This is easily achieved in Backgrid.js.</p>
 344                  <p>Backgrid.js comes with a number of filters and a paginator
 345                    extension which you can load by including the following into
 346                    your <code>head</code> tag:</p>
 347                  <textarea class="code-snippet" data-mode="htmlmixed">
 348                    &lt;link rel="stylesheet" href="lib/extensions/filter/backgrid-filter.css" /&gt;
 349                    &lt;link rel="stylesheet" href="lib/extensions/paginator/backgrid-paginator.css" /&gt;
 350                    &lt;script src="assets/js/backbone-pageable.js"&gt;&lt;/script&gt;
 351                    &lt;script src="lib/extensions/filter/backgrid-filter.js"&gt;&lt;/script&gt;
 352                    &lt;script src="lib/extensions/paginator/backgrid-paginator.js"&gt;&lt;/script&gt;</textarea>
 353                  <p>To use the paginator, you must first declare your
 354                    collections to be
 355                    a <a href="https://github.com/wyuenho/backbone-pageable/"
 356                         title="Backbone.PageableCollection">Backbone.PageableCollection</a>,
 357                    which is a simple subclass of the Backbone.js Collection with added
 358                    pagination behavior.</p>
 359                  <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
 360                    var PageableTerritories = Backbone.PageableCollection.extend({
 361                      model: Territory,
 362                      url: "examples/pageable-territories.json",
 363                      state: {
 364                        pageSize: 15
 365                      },
 366                      mode: "client" // page entirely on the client side
 367                    });
 368
 369                    var pageableTerritories = new PageableTerritories();
 370
 371                    // Set up a grid to use the pageable collection
 372                    var pageableGrid = new Backgrid.Grid({
 373                      columns: columns,
 374                      collection: pageableTerritories
 375                    });
 376
 377                    // Render the grid
 378                    var $example2 = $("#example-2-result");
 379                    $example2.append(pageableGrid.render().$el)
 380
 381                    // Initialize the paginator
 382                    var paginator = new Backgrid.Extension.Paginator({
 383                      collection: pageableTerritories
 384                    });
 385
 386                    // Render the paginator
 387                    $example2.append(paginator.render().$el);
 388
 389                    // Initialize a client-side filter to filter on the client
 390                    // mode pageable collection's cache.
 391                    var filter = new Backgrid.Extension.ClientSideFilter({
 392                      collection: pageableTerritories.fullCollection,
 393                      fields: ['name']
 394                    });
 395
 396                    // Render the filter
 397                    $example2.prepend(filter.render().$el);
 398
 399                    // Add some space to the filter and move it to the right
 400                    filter.$el.css({float: "right", margin: "20px"});
 401
 402                    // Fetch some data
 403                    pageableTerritories.fetch({reset: true});</textarea>
 404                </div>
 405              </div>
 406              <div class="row-fluid">
 407                <div class="span12">
 408                  <h3>Result</h3>
 409                  <div id="example-2-result" class="backgrid-container"></div>
 410                </div>
 411              </div>
 412            </div>
 413          </div>
 414        </section>
 415        <section>
 416          <div class="page-header">
 417            <h1>API Reference</h1>
 418          </div>
 419          <div class="row-fluid">
 420            <div class="span2">
 421              <h2 id="api-grid">Grid</h2>
 422              <ul class="nav">
 423                <li><a href="api/index.html#!/api/Backgrid.Grid">Backgrid.Grid</a></li>
 424              </ul>
 425              <h3>Events</h3>
 426              <ul class="nav">
 427                <li><a href="api/index.html#!/api/Backgrid.Grid-method-render">backgrid:rendered</a></li>
 428              </ul>
 429            </div>
 430            <div class="span10">
 431              <h3>How to Use the Grid</h3>
 432              <p>As described in the <a href="#examples">examples</a> above, a
 433                basic grid needs only a collection and a list of column
 434                definitions.</p>
 435              <h3>Manipulating Columns and Rows</h3>
 436              <p>It is very easy to insert or remove a row in a grid, you just
 437                have to pass a model reference
 438                to <a href="api/index.html#!/api/Backgrid.Grid-method-insertRow">Grid#insertRow</a>
 439                or <a href="api/index.html#!/api/Backgrid.Grid-method-removeRow">Grid#removeRow</a>.</p>
 440              <textarea class="code-snippet" data-mode="javascript">
 441                // Inserting rows
 442                grid.insertRow([{
 443                  // model 1
 444                }, {
 445                  // model 2 ... etc
 446                }]);
 447
 448                // Remove rows
 449                var musketeers = grid.collection.where({ job: "Musketeer" });
 450                grid.removeRow(musketeers);</textarea>
 451              <p>Inserting and remove columns is similarly easy. You just need
 452                to pass some definitions
 453                to <a href="api/index.html#!/api/Backgrid.Grid-method-insertColumn">Grid#insertColumn</a>
 454                or
 455                <a href="api/index.html#!/api/Backgrid.Grid-method-removeColumn">Grid#removeColumn</a>.</p>
 456              <textarea class="code-snippet" data-mode="javascript">
 457                // Insert a few new columns. Make sure your model has these attributes though.
 458                grid.insertColumn([{
 459
 460                    name: "selected",
 461                    label: "",
 462                    cell: "boolean",
 463                    sortable: false,
 464                    headerCell: MySelectAllCell
 465
 466                  }, {
 467
 468                    name: "address",
 469                    label: "Address",
 470                    cell: "string"
 471
 472                  }]);
 473
 474                // Remove a column
 475                var genderCol = grid.columns.where({ name: "gender" });
 476                grid.removeColumn(genderCol);</textarea>
 477              <h3>Customization</h3>
 478              <p>The various ways of customizing a grid are described in the
 479                following sections.</p>
 480            </div>
 481          </div>
 482          <div class="row-fluid">
 483            <div class="span2">
 484              <h2 id="api-column">Columns</h2>
 485              <ul class="nav">
 486                <li><a href="api/index.html#!/api/Backgrid.Column" title="Backgrid.Column">Backgrid.Column</a></li>
 487                <li><a href="api/index.html#!/api/Backgrid.Columns" title="Backgrid.Columns">Backgrid.Columns</a></li>
 488              </ul>
 489            </div>
 490            <div class="span10">
 491              <h3>Column Defaults</h3>
 492              <p>Column defaults and required parameters are defined in
 493                the <a href="api/index.html#!/api/Backgrid.Column-method-initialize">Backgrid.Column#initialize</a>
 494                method.</p>
 495              <h3>Column Definition</h3>
 496              <p>A Column is a placeholder for a column definition.</p>
 497              <p>You usually don&apos;t need to create an instance of this class
 498                yourself, as a collection of column instances will be created for
 499                you from a list of column object literals you provide to the
 500                Backgrid.js view class constructors.</p>
 501              <p>Internally, columns are stored as a collection in the form of
 502                Backgrid.Columns. In addition, all parent views will convert the
 503                column definition into
 504                a <a href="api/index.html#!/api/Backgrid.Columns">Backgrid.Columns</a>
 505                collection and pass a reference to any subviews that require
 506                it.</p>
 507              <h3>Listening to Column Attribute Changes</h3>
 508              <p>Occasionally, you may want to listen to column attribute change
 509                events. In that case, you can choose to initialize a
 510                Backgrid.Columns collection and listen to events from the
 511                individual models.</p>
 512              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 513                var myColumns = new Backgrid.Columns({
 514                  name: "id", label: "ID", cell: "string"
 515                }, {
 516                  // ...
 517                });
 518
 519                myColumns.on("change:renderable", function (col, colAttr) {
 520                  if (!colAttr) {
 521                    // hide the column
 522                  }
 523                });</textarea>
 524            </div>
 525          </div>
 526          <div class="row-fluid">
 527            <div class="span2">
 528              <h2 id="api-cell">Cell</h2>
 529              <ul class="nav">
 530                <li><a href="api/index.html#!/api/Backgrid.Cell">Backgrid.Cell</a></li>
 531                <li><a href="api/index.html#!/api/Backgrid.DatetimeCell">Backgrid.DatetimeCell</a></li>
 532                <li><a href="api/index.html#!/api/Backgrid.DateCell">Backgrid.DateCell</a></li>
 533                <li><a href="api/index.html#!/api/Backgrid.TimeCell">Backgrid.TimeCell</a></li>
 534                <li><a href="api/index.html#!/api/Backgrid.NumberCell">Backgrid.NumberCell</a></li>
 535                <li><a href="api/index.html#!/api/Backgrid.IntegerCell">Backgrid.IntegerCell</a></li>
 536                <li><a href="api/index.html#!/api/Backgrid.StringCell">Backgrid.StringCell</a></li>
 537                <li><a href="api/index.html#!/api/Backgrid.UriCell">Backgrid.UriCell</a></li>
 538                <li><a href="api/index.html#!/api/Backgrid.EmailCell">Backgrid.EmailCell</a></li>
 539                <li><a href="api/index.html#!/api/Backgrid.BooleanCell">Backgrid.BooleanCell</a></li>
 540                <li><a href="api/index.html#!/api/Backgrid.SelectCell">Backgrid.SelectCell</a></li>
 541                <li><a href="api/index.html#!/api/Backgrid.CellEditor">Backgrid.CellEditor</a></li>
 542                <li><a href="api/index.html#!/api/Backgrid.InputCellEditor">Backgrid.InputCellEditor</a></li>
 543                <li><a href="api/index.html#!/api/Backgrid.SelectCellEditor">Backgrid.SelectCellEditor</a></li>
 544              </ul>
 545              <h3>Events</h3>
 546              <ul class="nav">
 547                <li><a href="api/index.html#!/api/Backgrid.Cell-method-enterEditMode">backgrid:edit</a></li>
 548                <li><a href="api/index.html#!/api/Backgrid.Cell-method-enterEditMode">backgrid:editing</a></li>
 549                <li><a href="api/index.html#!/api/Backgrid.InputCellEditor-method-saveOrCancel">backgrid:edited</a></li>
 550                <li><a href="api/index.html#!/api/Backgrid.InputCellEditor-method-saveOrCancel">backgrid:error</a></li>
 551              </ul>
 552            </div>
 553            <div class="span10">
 554              <h3>Demo</h3>
 555              <p class="label label-success">Try them</p>
 556              <div id="cell-demo-grid-1" class="backgrid-container" style="height: auto"></div>
 557              <div id="cell-demo-grid-2" class="backgrid-container" style="height: auto"></div>
 558              <aside class="note">
 559                <h5>Note:</h5>
 560                <p>Backgrid.js and its author are not associated with Santa and
 561                  santaclaus.com in any way.</p>
 562              </aside>
 563              <h3>Configuring Cells</h3>
 564              <p>While many built-in cells provide reasonable defaults, you may
 565                choose to configure them to suit your own needs.</p>
 566              <p>Cell types that you are most likely to configure are the
 567                NumberCell, DatetimeCell and SelectCell classes. Once
 568                configured, you may use them as the cell attribute values in
 569                column definitions.</p>
 570              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 571                var grid = new Backgrid.Grid({
 572
 573                  columns: [{
 574                    name: "id",
 575                    label: "ID",
 576                    editable: false,
 577                    // Dynamically defines a new cell type with new defaults.
 578                    // ID is displayed as an integer without &apos;,&apos;s.
 579                    cell: Backgrid.IntegerCell.extend({
 580                      orderSeparator: ''
 581                    })
 582                  }, {
 583                    name: "lastaccessed",
 584                    label: "Last Login Time",
 585                    editable: false,
 586                    cell: Backgrid.DatetimeCell.extend({
 587                      includeMilli: true
 588                    })
 589                  }, {
 590                    name: "gender",
 591                    label: "Gender",
 592                    cell: Backgrid.SelectCell.extend({
 593                      // It's possible to render an option group or use a
 594                      // function to provide option values too.
 595                      optionValues: [["Male", "m"], ["Female", "f"]]
 596                    })
 597                  }],
 598
 599                  collection: col
 600                });
 601              </textarea>
 602              <p class="label label-info">Pro Tip</p>
 603              <p>SelectCell treats all option values as strings by default, if
 604                you need to persist a different type of values into your model,
 605                you should extend SelectCell to provide your
 606                own <a href="#api-formatter"
 607                title="Formatter">formatter</a>.</p>
 608              <p>See the <a href="api/index.html" title="API Doc">JSDoc</a> for
 609                the various Cell classes for details on what you can configure
 610                using this method.</p>
 611              <h3>Custom Cell</h3>
 612              <p>If the built-in and extension cell classes are not enough for
 613                you, you may choose to create your own cell class and supply it
 614                to a column definition.</p>
 615              <p>If your custom cell will still use a
 616                <code>&lt;input type="text" /&gt;</code> like the predefined
 617                ones for editing, you may choose to
 618                subclass <a href="api/index.html#!/api/Backgrid.Cell">Cell</a>
 619                or one of the predefined classes and simply define a className
 620                and a <a href="#api-formatter"
 621                title="Formatter">formatter</a>. In fact, most of the core cell
 622                classes are done this way.</p>
 623              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 624                // This is how StringCell is defined.
 625
 626                Backgrid.StringCell = Cell.extend({
 627
 628                  // Cell default class names are the lower-cased and dasherized
 629                  // form of the the cell class names by convention.
 630                  className: "string-cell"
 631
 632                  formatter: Backgrid.StringFormatter
 633
 634                });</textarea>
 635              <p>If your cell class will render differently in display mode, you
 636                may simply
 637                override <a href="api/index.html#!/api/Backgrid.Cell-method-render">Cell#render()</a>
 638                in your subclass.</p>
 639              <h3>Custom CellEditor</h3>
 640              <p class="label label-warning">Advanced Usage</p>
 641              <p>Some cell types, like the
 642                <a href="#api-text-cell" title="TextCell">TextCell</a>
 643                extension, may only make sense if the editor is rendered in a
 644                modal dialog or a form element in a different part of the
 645                page. In that case the
 646                default <a href="api/index.html#!/api/Backgrid.InputCellEditor"
 647                title="InputCellEditor">InputCellEditor</a>, which renders a
 648                <code>&lt;input type="text" /&gt;</code>, will not be suitable
 649                and a new <a href="api/index.html#!/api/Backgrid.CellEditor"
 650                title="CellEditor">CellEditor</a> must be defined.</p>
 651              <p>A custom cell editor should subclass <a
 652                href="api/index.html#!/api/Backgrid.CellEditor">CellEditor</a>
 653                as it defines a number of required parameters in its initializer
 654                and clean up operations that are necessary for most cell
 655                editors. When a cell class enters edit mode, a new editor
 656                instance is constructed by given it the required parameters, and
 657                then a Backbone event <code>backgrid:edit</code> is fired from
 658                the cell instance itself. A custom cell class can act on this
 659                event to do anything before the cell editor is rendered.</p>
 660              <p>Once the cell has entered edit mode, a Backbone event
 661                <code>backgrid:editing</code> is fired. A custom cell class can
 662                then act on it to do anything after the cell editor has been
 663                rendered, e.g. placing the focus inside the editor.</p>
 664              <p>During editing, if an error is encountered (see the <a
 665                href="#api-formatter">formatter protocol</a> below), a cell
 666                editor should fire a Backbone event <code>backgrid:error</code>
 667                so that listeners&mdash;usually a cell instance&mdash;can
 668                respond appropriately. When editing is done, a cell editor
 669                should fire a Backbone <code>backgrid:done</code> event. A cell
 670                should be listening to this event so it can remove its editor
 671                and re-render itsef in display mode.</p>
 672              <p class="label label-important">Truely Advanced Hacking</p>
 673              <p>At the most basic level, Cells and CellEditors are simply
 674                <a href="http://backbonejs.org/#View"
 675                title="Backbone.View">Backbone.View</a> classes that are
 676                guaranteed to be given a number of parameters when constructed
 677                by <a href="api/index.html#!/api/Backgrid.Row"
 678                title="Row">Row</a>. You can use any Backbone.View as your Cell
 679                and CellEditor.</p>
 680            </div>
 681          </div>
 682          <div class="row-fluid">
 683            <div class="span2">
 684              <h2 id="api-formatter">Formatter</h2>
 685              <ul class="nav">
 686                <li><a href="api/index.html#!/api/Backgrid.CellFormatter">Backgrid.CellFormatter</a></li>
 687                <li><a href="api/index.html#!/api/Backgrid.DatetimeFormatter">Backgrid.DatetimeFormatter</a></li>
 688                <li><a href="api/index.html#!/api/Backgrid.NumberFormatter">Backgrid.NumberFormatter</a></li>
 689              </ul>
 690            </div>
 691            <div class="span10">
 692              <h3>Custom Formatters</h3>
 693              <p>In Backgrid.js, cell formatters serves the purpose of converting values
 694                between JSON value types and strings, and validation. Writing
 695                formatters for value conversion and validation is easy as you only
 696                have to conform to a very simple protocol.</p>
 697              <p>Any formatters must have the following two methods defined:</p>
 698              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 699                var formatter = {
 700                  // function (*): string
 701                  fromRaw: function (rawData) { },
 702                  // function (string): *|undefined
 703                  toRaw: function (formattedData) { }
 704                };</textarea>
 705              <p><code>fromRaw()</code> is called by Backgrid.Cell and its
 706                subclasses whenever a raw model value needs to be formatted into
 707                a humanized form for display.</p>
 708              <p><code>toRaw()</code> is called by Backgrid.CellEditor and its
 709                subclasses whenever a user input string needs to be converted back
 710                to a raw JSON value for model persistence.</p>
 711              <h3>Validation</h3>
 712              <p>In addition to user input conversion, toRaw() also validates
 713                the user input during conversion. If the user input is invalid
 714                or cannot be converted to a JSON value,
 715                toRaw() <strong>MUST</strong> return <code>undefined</code>
 716                instead of throwing an Error.</p>
 717              <p>In addition to using formatters to do simple yes or no
 718                validations, if your model class has
 719                a <a href="http://backbonejs.org/#Model-validate"
 720                title="Backbone.Model#validate">validate()</a> method defined,
 721                it will also be used for validation after trying with the
 722                formatter.</p>
 723              <h3>Using Custom Formatters</h3>
 724              <p>A custom formatter can be used instead of the cell's default by
 725                extending the cell:</p>
 726              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 727                var grid = new Backgrid.Grid({
 728                  columns: [{
 729                    name: "url",
 730                    cell: "uri",
 731                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
 732                      fromRaw: function (rawValue) {
 733                        return rawValue.replace("http://", '');
 734                      }
 735                    })
 736                  }],
 737                  collection: col
 738                });</textarea>
 739            </div>
 740          </div>
 741          <div class="row-fluid">
 742            <div class="span2">
 743              <h2 id="api-header">Header</h2>
 744              <ul class="nav">
 745                <li><a href="api/index.html#!/api/Backgrid.Header">Backgrid.Header</a></li>
 746                <li><a href="api/index.html#!/api/Backgrid.HeaderRow">Backgrid.HeaderRow</a></li>
 747                <li><a href="api/index.html#!/api/Backgrid.HeaderCell">Backgrid.HeaderCell</a></li>
 748              </ul>
 749              <h3>Events</h3>
 750              <ul class="nav">
 751                <li><a href="api/index.html#!/api/Backgrid.HeaderCell-method-sort">backgrid:sort</a></li>
 752              </ul>
 753            </div>
 754            <div class="span10">
 755              <h3>Understanding the Default Header</h3>
 756              <p>Backgrid.js comes with a default header section, a header row
 757                and a header cell implementation that renders a sorter if the
 758                column is sortable. The text inside the header cells comes from
 759                the column definitions. If a <em>label</em> is not defined in a
 760                column definition, its name is used as the label instead.</p>
 761              <p>The default header cell implementation supports sorting in
 762                ascending or descending order, using the column&apos;s natural
 763                ordering. The sorter will also allow cycling back to the
 764                table&apos;s default sorting order, which is sorting by the
 765                model <a href="http://backbonejs.org/#Model-id"
 766                title="Backbone.Model#id">server IDs</a>
 767                and <a href="http://backbonejs.org/#Model-cid"
 768                title="Backbone.Model#cid">client IDs</a>.</p>
 769              <h3>Customizing the Header</h3>
 770              <p>If you want to change the default sort behavior to only toggle
 771                between sorting in ascending or descending order, you do this
 772                by passing ```sortType: "toggle"``` as part of your column
 773                definition.</p>
 774              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 775                var grid = new Backgrid.Grid({
 776                  columns: [{
 777                    name: "id",
 778                    label: "ID"
 779                  },{
 780                    name: "name",
 781                    label: "Name"
 782                  },{
 783                    name: "age",
 784                    label: "Age",
 785                    sortTye: "toggle"
 786                  }]
 787                });
 788              </textarea>
 789              <p class="label label-warning">Advanced Usage</p>
 790              <p>You are allow to use a different header cell class on
 791                columns. There is no restriction on what a header cell must do. In fact,
 792                any <a href="http://backbonejs.org/#View"
 793                title="Backbone.View">Backbone.View</a> class can be
 794                used. However, if you wish to modify how the sorter behaves, you
 795                must implement the sorting protocol. See
 796                the <a href="api/index.html#!/api/Backgrid.HeaderCell"
 797                title="Backgrid.HeaderCell API">JSDoc</a> for details.</p>
 798              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 799                var SelectAllHeaderCell = Backgrid.HeaderCell.extend({
 800                  // Implement your "select all" logic here
 801                });
 802
 803                var grid = new Backgrid.Grid({
 804
 805                  columns: [{
 806                    name: "selected",
 807                    label: "",
 808                    sortable: false,
 809                    cell: "boolean",
 810                    headerCell: SelectAllHeaderCell
 811                  }],
 812
 813                  collection: col
 814                });</textarea>
 815            </div>
 816          </div>
 817          <div class="row-fluid">
 818            <div class="span2">
 819              <h2 id="api-row">Row</h2>
 820              <ul class="nav">
 821                <li><a href="api/index.html#!/api/Backgrid.Row">Backgrid.Row</a></li>
 822              </ul>
 823            </div>
 824            <div class="span10">
 825              <h3>Customizing Row</h3>
 826              <p class="label label-warning">Advanced Usage</p>
 827              <p>A row is simply an intermediary view class that constructs the
 828                appropriate Cell class instances for rendering the model
 829                columns.</p>
 830              <p>If you would like to override how a row is rendered, you may
 831                define your own Row subclass and give it to the Grid constructor
 832                as an option:</p>
 833              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 834                var ZebraStrippingRow = Backgrid.Row.extend({
 835                  // ...
 836                });
 837
 838                var grid = new Backgrid.Grid({
 839                  row: ZebraStrippingRow, // <-- Tell the new Body class to use ZebraStrippingRow to render rows.
 840                  columns: [{
 841                    //...
 842                  }],
 843                  collection: col
 844                });</textarea>
 845            </div>
 846          </div>
 847          <div class="row-fluid">
 848            <div class="span2">
 849              <h2 id="api-body">Body</h2>
 850              <ul class="nav">
 851                <li><a href="api/index.html#!/api/Backgrid.Body">Backgrid.Body</a></li>
 852              </ul>
 853              <h3>Events</h3>
 854              <ul class="nav">
 855                <li><a href="api/index.html#!/api/Backgrid.Body-method-refresh">backgrid:refresh</a></li>
 856              </ul>
 857            </div>
 858            <div class="span10">
 859              <h3>Customizing Body</h3>
 860              <p class="label label-important">Truely Advanced Hacking</p>
 861              <p>Body is the intermediary view that coordinates between the
 862                various parts of the grid. Specifically, the default
 863                implementation is responsible for re-rendering the rows when any
 864                model is inserted into, removed from, or reordered in the
 865                underlying collection. See
 866                the <a href="api/index.html#!/api/Backgrid.Body">JSDoc</a> for
 867                details.</p>
 868              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 869                var MyBody = Backgrid.Body.extend({
 870                  // I really don't know why you would do this, but you can if you want
 871                });
 872
 873                var grid = new Backgrid.Grid({
 874                  body: MyBody,
 875                  columns: [{
 876                    // ...
 877                  }],
 878                  collection: col
 879                });</textarea>
 880            </div>
 881          </div>
 882          <div class="row-fluid">
 883            <div class="span2">
 884              <h2 id="api-footer">Footer</h2>
 885              <ul class="nav">
 886                <li><a href="api/index.html#!/api/Backgrid.Footer">Backgrid.Footer</a></li>
 887              </ul>
 888            </div>
 889            <div class="span10">
 890              <h3>Putting Things at The End of a Table</h3>
 891              <p>The default Footer class is an abstract class that only defines
 892                a number of required constructor parameters. If you wish to
 893                append additional information to the end of a table you must
 894                subclass Footer and supply the class to the Grid
 895                constructor.</p>
 896              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
 897                var CaptionFooter = Backgrid.Footer.extend({
 898
 899                  render: function () {
 900                    this.$el.html("&lt;tr&gt;&lt;td colspan=&apos;6&apos;&gt;Hello World!&lt;/td&gt;&lt;/tr&gt;");
 901                    return this;
 902                  }
 903
 904                });
 905
 906                var grid = new Backgrid.Grid({
 907                  columns: [{
 908                    //...
 909                  }],
 910                  collection: col,
 911                  footer: CaptionFooter // <--
 912                });</textarea>
 913              <p>Very often, you&apos;ll want to append a paginator to the end
 914                of your table if there are too many rows. For this, there&apos;s already
 915                a <a href="#api-paginator">paginator extension</a> provided for you.</p>
 916            </div>
 917          </div>
 918        </section>
 919        <section id="extensions">
 920          <div class="page-header">
 921            <h1>Extensions</h1>
 922            <p>It is not necessary to create an extension project if you simply
 923              want to customize or extend some Backgrid.js classes for your own
 924              private use; however, if you have one or more Backgrid.js
 925              components that add new features to the core, you may consider
 926              packaging them up to share with the world.</p>
 927            <p>A Backgrid.js extension is a directory structure that packages
 928              the necessary JS, CSS, tests, and document files.</p>
 929            <p>To create an extension, clone the tree into your file system and
 930              type:</p>
 931            <textarea class="code-snippet" data-mode="shell">
 932              $ cd backgrid
 933              $ make extension</textarea>
 934            <p>A new extension directory structure should have been created for
 935              you under <code>src/extensions</code>. The current implementation
 936              of <code>make extension</code> only creates a blank directory
 937              filled with a number of blank files for you. You should take a
 938              look at other extensions to copy what you need. e.g. Makefile,
 939              .gitignore.</p>
 940            <h2>Extension Development Guide</h2>
 941            <p>The following is a guideline for extension development:</p>
 942            <ul>
 943              <li>There should be 1 .js file and 1 .css file. If your code base
 944                gets too large, consider breaking it into multiple extensions.</li>
 945              <li>There should be 1 .min.js file and 1 .min.css file produced
 946                for distribution.</li>
 947              <li>Your Makefile should emulate other extensions as closely
 948                as possible. Specifically, you should have a <code>dist</code>
 949                rule that will take a <code>DIST_DIR</code> variable from
 950                top-level make invocations and copy the output files to the
 951                destination directory.</li>
 952              <li>You should use recess to lint your CSS file(s).</li>
 953              <li>You should follow the JS coding style defined <a
 954                href="https://github.com/wyuenho/backgrid/blob/gh-pages/CONTRIBUTING.md#coding-style">here</a>.</li>
 955              <li>Your .gitignore file inside the extension directory should
 956                ignore all output files.</li>
 957              <li>You should wrap your JS file in an immediately invoked
 958                anonymous function that lists out your dependencies in the
 959                parameter list.</li>
 960              <li>Your extension should live under
 961                the <code>Backgrid.Extension</code> module.</li>
 962              <li>You should clearly specify your dependencies in the README
 963                file if your extension relies on any libraries other than
 964                Backgrid.js and its dependencies.</li>
 965              <li>When in doubt, look at the other extensions for clues in
 966                organizing your code.</li>
 967            </ul>
 968          </div>
 969          <div class="row-fluid">
 970            <div class="span3">
 971              <h2 id="api-select-all">SelectAll</h2>
 972              <ul class="nav">
 973                <li><a href="api/index.html#!/api/Backgrid.Extension.SelectRowCell">Backgrid.Extension.SelectRowCell</a></li>
 974                <li><a href="api/index.html#!/api/Backgrid.Extension.SelectAllHeaderCell">Backgrid.Extension.SelectAllHeaderCell</a></li>
 975              </ul>
 976              <h3>Events</h3>
 977              <ul class="nav">
 978                <li><a href="api/index.html#!/api/Backgrid.Extension.SelectAllHeaderCell-method-initialize">backgrid:select</a></li>
 979                <li><a href="api/index.html#!/api/Backgrid.Extension.SelectAllHeaderCell-method-initialize">backgrid:selected</a></li>
 980              </ul>
 981              <h4>Best Used On</h4>
 982              <ul>
 983                <li>Desktop</li>
 984                <li>Mobile</li>
 985              </ul>
 986            </div>
 987            <div class="span9">
 988              <h3>When to Use</h3>
 989              <p>When you want to select multiple models at a time for batch operations.</p>
 990              <textarea class="code-snippet" data-mode="htmlmixed">
 991                &lt;link rel="stylesheet" href="lib/extensions/select-all/backgrid-select-all.css" /&gt;
 992                &lt;script src="lib/extensions/select-all/backgrid-select-all.js"&gt;&lt;/script&gt;</textarea>
 993              <h3>Usage</h3>
 994              <p>To enable the SelectAll extension, you simply have to add a new
 995              column to your column definition like so:</p>
 996              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
 997                var grid = new Backgrid.Grid({
 998                  columns: [{
 999
1000                    // name is a required parameter, but you don't really want one on a select all column
1001                    name: "",
1002
1003                    // Backgrid.Extension.SelectRowCell lets you select individual rows
1004                    cell: "select-row",
1005
1006                    // Backgrid.Extension.SelectAllHeaderCell lets you select all the row on a page
1007                    headerCell: "select-all",
1008
1009                  }].concat(columns),
1010
1011                  collection: new Backbone.Collection([
1012                    {"name": "Afghanistan", "url": "http://en.wikipedia.org/wiki/Afghanistan", "pop": 25500100, "date": "2013-01-01", "percentage": 0.36, "id": 1},
1013                    {"name": "Albania", "url": "http://en.wikipedia.org/wiki/Albania", "pop": 2831741, "date": "2011-10-01", "percentage": 0.04, "id": 2}
1014                  ])
1015                });
1016
1017                $("#select-all-example-result").append(grid.render().el);</textarea>
1018            </div>
1019          </div>
1020          <div class="row-fluid">
1021            <div class="span9 offset3">
1022              <h3>Result</h3>
1023              <div id="select-all-example-result" class="backgrid-container" style="height: auto"></div>
1024            </div>
1025          </div>
1026          <div class="row-fluid">
1027            <div class="span9 offset3">
1028              <h3>Manipulating Selections Programatically</h3>
1029              <p>At any point during the lifetime of your program, if you'd like
1030              to get an array of the currently selected models after you've
1031              rendered your grid, you can easily do so:</p>
1032              <textarea class="code-snippet" data-mode="javascript" data-eval="no">
1033                // This method is only available on Backgrid.Grid after you've
1034                // include the SelectAll extension.
1035                var selectedModels = grid.getSelectedModels();
1036
1037                // To deselect selected models
1038                _.each(selectedModels, function (model) {
1039                  model.trigger("backgrid:select", model, false);
1040                });
1041
1042                // Selecting even numbered rows
1043                grid.collection.each(function (model, i) {
1044                  if (i % 2 == 0) model.trigger("backgrid:select", model, true);
1045                });
1046              </textarea>
1047            </div>
1048          </div>
1049          <div class="row-fluid">
1050            <div class="span9 offset3">
1051              <p class="label label-info">Pro Tip</p>
1052              <p>Each SelectRowCell will trigger a <code>backgrid:select</code>
1053              event directly from the selected models when its checkbox value
1054              changes, so if you want to react to those events, you can attach
1055              your event handlers on the collection.</p>
1056              <p>See the <a
1057              href="api/index.html#!/api/Backgrid.Extension.SelectRowCell">API
1058              documentation</a> for details.</p>
1059            </div>
1060          </div>
1061          <div class="row-fluid">
1062            <div class="span3">
1063              <h2 id="api-paginator">Paginator</h2>
1064              <ul class="nav">
1065                <li><a href="api/index.html#!/api/Backgrid.Extension.Paginator">Backgrid.Extension.Paginator</a></li>
1066              </ul>
1067              <h4>Best Used On</h4>
1068              <ul>
1069                <li>Desktop</li>
1070                <li>Mobile</li>
1071              </ul>
1072            </div>
1073            <div class="span9">
1074              <h3>When to Use</h3>
1075              <p>When you have more data than your grid can fit, you can use
1076                Paginator to break the display of your data into pages.</p>
1077              <h3>Prerequisites</h3>
1078              <p>Backgrid.Extension.Paginator needs a Backbone.Collection
1079                subclass that supports pagination. Luckily, there is already one
1080                available specially written for this purpose
1081                - <a href="https://github.com/wyuenho/backbone-pageable"
1082                title="backbone-pageable">Backbone.PageableCollection</a>.</p>
1083              <p>Backbone.PageableCollection is a strict superset of the vanilla
1084                Backbone.Collection with additional pagination and sorting
1085                functionality. If you like, you can use
1086                Backbone.PageableCollection throughout your application and it
1087                will work exactly the same as Backbone.Collection.</p>
1088              <textarea class="code-snippet" data-mode="htmlmixed">
1089                &lt;link rel="stylesheet" href="lib/extensions/paginator/backgrid-paginator.css" /&gt;
1090                &lt;script src="assets/js/backbone-pageable.js"&gt;&lt;/script&gt;
1091                &lt;script src="lib/extensions/paginator/backgrid-paginator.js"&gt;&lt;/script&gt;</textarea>
1092              <h3>Backbone.PageableCollection</h3>
1093              <p>Out of the box, Backbone.PageableCollection works with RESTful
1094                APIs that accept Ruby's will_paginate pagination query
1095                parameters but you are able to configure the query string
1096                mapping anyway you like. The following example works with
1097                <a href="http://developer.github.com/v3/" title="GitHub API
1098                v3">Github's API</a>:</p>
1099              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1100                var Issue = Backbone.Model.extend({});
1101
1102                // Works exactly like Backbone.Collection.
1103                var Issues = Backbone.PageableCollection.extend({
1104                  model: Issue,
1105
1106                  // Enable infinite paging
1107                  mode: "infinite",
1108
1109                  url: "https://api.github.com/repos/documentcloud/backbone/issues?state=closed",
1110
1111                  // Initial pagination states
1112                  state: {
1113                    pageSize: 15,
1114                    sortKey: "updated",
1115                    order: 1
1116                  },
1117
1118                  // You can remap the query parameters from `state` keys from
1119                  // the default to those your server supports
1120                  queryParams: {
1121                    totalPages: null,
1122                    totalRecords: null,
1123                    sortKey: "sort",
1124                    order: "direction",
1125                    directions: {
1126                      "-1": "asc",
1127                      "1": "desc"
1128                    }
1129                  }
1130                });
1131
1132                var issues = new Issues();</textarea>
1133              <h3>Configuring Backgrid.Extension.Paginator</h3>
1134              <p>Backgrid.Extension.Paginator supports a few configuration
1135                options to adjust to the size of the result set.</p>
1136              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1137                var issueGrid = new Backgrid.Grid({
1138
1139                  columns: [{
1140                    name: "number",
1141                    cell: Backgrid.IntegerCell.extend({ orderSeparator: '' }),
1142                    editable: false,
1143                    sortable: false
1144                  }, {
1145                    name: "title",
1146                    cell: "string",
1147                    sortable: false
1148                  }, {
1149                    name: "body",
1150                    cell: "text", // See the TextCell extension in the next section
1151                    sortable: false
1152                  }, {
1153                    name: "updated_at",
1154                    cell: "datetime",
1155                    editable: false,
1156                    sortable: false
1157                  }, {
1158                    name: "closed_at",
1159                    cell: "datetime",
1160                    editable: false,
1161                    sortable: false
1162                  }],
1163
1164                  collection: issues
1165                });
1166
1167                var $paginatorExample = $("#paginator-example-result");
1168                $paginatorExample.append(issueGrid.render().el);
1169
1170                var GithubPaginator = Backgrid.Extension.Paginator.extend({
1171
1172                  // If you anticipate a large number of pages, you can adjust
1173                  // the number of page handles to show. The sliding window
1174                  // will automatically show the next set of page handles when
1175                  // you click next at the end of a window.
1176                  windowSize: 20, // Default is 10
1177
1178                  // If you anticipate a small number of pages, you can choose
1179                  // to disable the rendering of fast forward handles to save
1180                  // space.
1181                  hasFastForward: true, // true is the default
1182
1183                  fastForwardHandleLabels: {
1184                    prev: "<",
1185                    next: ">"
1186                  }
1187                });
1188
1189                var paginator = new GithubPaginator({
1190                  collection: issues
1191                });
1192                $paginatorExample.append(paginator.render().el);
1193
1194                issues.getFirstPage();</textarea>
1195            </div>
1196            <div class="span12">
1197              <h3>Result</h3>
1198              <div id="paginator-example-result" class="backgrid-container" style="height: auto"></div>
1199            </div>
1200          </div>
1201          <div class="row-fluid">
1202            <div class="span3">
1203              <h2 id="api-filter">Filter</h2>
1204              <ul class="nav">
1205                <li><a href="api/index.html#!/api/Backgrid.Extension.ServerSideFilter">Backgrid.Extension.ServerSideFilter</a></li>
1206                <li><a href="api/index.html#!/api/Backgrid.Extension.ClientSideFilter">Backgrid.Extension.ClientSideFilter</a></li>
1207                <li><a href="api/index.html#!/api/Backgrid.Extension.LunrFilter">Backgrid.Extension.LunrFilter</a></li>
1208              </ul>
1209              <h4>Best Used On</h4>
1210              <ul>
1211                <li>Desktop</li>
1212                <li>Mobile</li>
1213              </ul>
1214            </div>
1215            <div class="span9">
1216              <h3>When to Use</h3>
1217              <p>When you have lots of rows with lots of text, and you just want
1218              to quickly get to the row that only contain certain keywords.</p>
1219              <h3>Prerequisites</h3>
1220              <p>All three Filter classes have an optional dependency
1221                on <a href="http://twitter.github.com/bootstrap/"
1222                      title="Twitter Bootstrap">Twitter Bootstrap's CSS</a>.
1223                This dependency is optional because the filter extension only
1224                uses its CSS for rendering. You are free to override the default
1225                template and CSS if you don't like it.</p>
1226              <p>For LunrFilter, it has a hard dependency on <a
1227                href="http://lunrjs.com/" title="lunr.js">lunr.js</a> for
1228                full-text searching.</p>
1229              <textarea class="code-snippet" data-mode="htmlmixed">
1230                &lt;link rel="stylesheet" href="assets/css/bootstrap.css" /&gt;
1231                &lt;link rel="stylesheet" href="lib/extensions/filter/backgrid-filter.css" /&gt;
1232                &lt;script src="assets/js/lunr.js"&gt;&lt;/script&gt;
1233                &lt;script src="lib/extensions/filter/backgrid-filter.js"&gt;&lt;/script&gt;</textarea>
1234              <h3>Usage</h3>
1235              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1236
1237                // ServerSideFilter delegates the searching to the server by submitting a query.
1238                var serverSideFilter = new Backgrid.Extension.ServerSideFilter({
1239                  collection: issues,
1240                  name: "labels", // the name of the URL query parameter
1241                  placeholder: "Search on the server" // HTML5 placeholder for the search box
1242                });
1243
1244                $("#filter-example-result").append(serverSideFilter.render().el);
1245
1246                // ClientSideFilter performs a case-insensitive regular
1247                // expression search on the client side by OR-ing the keywords in
1248                // the search box together.
1249                var clientSideFilter = new Backgrid.Extension.ClientSideFilter({
1250                  collection: pageableTerritories.fullCollection,
1251                  placeholder: "Search in the browser",
1252                  // The model fields to search for matches
1253                  fields: ['name'],
1254                  // How long to wait after typing has stopped before searching can start
1255                  wait: 150
1256                });
1257
1258                $("#filter-example-result").append(clientSideFilter.render().el);
1259
1260                // LunrFilter is a specialized ClientSideFilter that uses
1261                // lunr.js to perform full-text searching on the client side.
1262                var lunrFilter = new Backgrid.Extension.LunrFilter({
1263                  collection: pageableTerritories.fullCollection,
1264                  placeholder: "Full-text searching",
1265                  // lunr.js field name and boost value
1266                  fields: {
1267                    name: 10
1268                  },
1269                  // lunr.js document key for indexing
1270                  ref: 'id',
1271                  wait: 150
1272                });
1273
1274                $("#filter-example-result").append(lunrFilter.render().el);</textarea>
1275              <div id="filter-example-result"></div>
1276              <p class="label label-info">Pro Tip</p>
1277              <p>The client-side filters won't work unless the collection
1278                contains all the data for filtering at the time the filters are
1279                initialized. If you are fetching data after the filters were
1280                initialized and using Backbone 1.0.0+, you should pass
1281                <code>{remove: true}</code> or <code>{reset: true}</code> to
1282                <code>Collection#fetch()</code> due to the change to
1283                <code>Collection#set()</code>
1284                after <a href="http://backbonejs.org/#Collection-fetch"
1285                         title="Backbone.Collection#fetch">fetching</a> in Backbone
1286                1.0.0+. For this reason, the examples above may or may not work
1287                due to the asynchronous nature of fetching. To see a working
1288                example, scroll up to
1289              <a href="#example-2-result" title="Example 2">example 2</a>.</p>
1290            </div>
1291          </div>
1292          <div class="row-fluid">
1293            <div class="span3">
1294              <h2 id="api-text-cell">TextCell</h2>
1295              <ul class="nav">
1296                <li><a href="api/index.html#!/api/Backgrid.Extension.TextCell">Backgrid.Extension.TextCell</a></li>
1297                <li><a href="api/index.html#!/api/Backgrid.Extension.TextareaEditor">Backgrid.Extension.TextareaEditor</a></li>
1298              </ul>
1299              <h4>Best Used On</h4>
1300              <ul>
1301                <li>Desktop</li>
1302                <li>Mobile</li>
1303              </ul>
1304            </div>
1305            <div class="span9">
1306              <h3>When to Use</h3>
1307              <p>TextCell is a string cell type that renders a form with a text
1308                area in a modal dialog instead of
1309                an <code>&lt;input type="text" /&gt;</code> editor. It
1310                is best suited for entering a large body of text.</p>
1311              <h3>Prerequisites</h3>
1312              <p>TextCell requires <a
1313                href="http://twitter.github.com/bootstrap/javascript.html#modals"
1314                title="bootstrap-modal.js">bootstrap-modal.js</a> to render
1315                it&apos;s modal dialog. TextCell is tested against Bootstrap
1316                version 2.2.2. Bootstrap version 2.3.x is not recommended due to
1317                a number of critical bugs.</p>
1318              <textarea class="code-snippet" data-mode="htmlmixed">
1319                &lt;link rel="stylesheet" href="assets/css/bootstrap.css" /&gt;
1320                <!-- include this if you want to use TextCell on mobile browsers -->
1321                &lt;link rel="stylesheet" href="assets/css/bootstrap-responsive.css" /&gt;
1322                &lt;link rel="stylesheet" href="lib/extensions/text-cell/backgrid-text-cell.css" /&gt;
1323                &lt;script src="assets/js/bootstrap.js"&gt;&lt;/script&gt;
1324                &lt;script src="lib/extensions/text-cell/backgrid-text-cell.js"&gt;&lt;/script&gt;</textarea>
1325              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1326                var Book = Backbone.Model.extend({});
1327                var Books = Backbone.Collection.extend({
1328                  model: Book
1329                });
1330                var books = new Books([{ description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sed nibh tortor, nec mollis diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi venenatis sollicitudin vulputate. Aenean dapibus ultrices odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla id molestie erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut nec erat quis massa gravida facilisis. Ut at nisi ac tortor consectetur ullamcorper id nec purus. Fusce condimentum, lacus vitae convallis condimentum, velit orci auctor dui, et mattis dui est sed purus. Praesent pharetra, metus sit amet lacinia adipiscing, purus dolor sodales orci, non malesuada orci orci sit amet dolor. Sed id nisl et neque sollicitudin condimentum eget in nisl." }]);
1331
1332                var grid = new Backgrid.Grid({
1333                  columns: [{
1334                    name: "description",
1335                    label: "Description",
1336                    // You can use Backgrid.Extension.TextCell.extend() too.
1337                    // See the JSDoc for a list of configurable options.
1338                    cell: "text"
1339                  }],
1340
1341                  collection: books
1342                });
1343
1344                $("#text-cell-example-result").append(grid.render().el);
1345              </textarea>
1346              <h3>Result</h3>
1347              <div id="text-cell-example-result" class="backgrid-container" style="height: auto;"></div>
1348            </div>
1349          </div>
1350          <div class="row-fluid">
1351            <div class="span3">
1352              <h2 id="api-moment-cell">MomentCell</h2>
1353              <h4>Best Used On</h4>
1354              <ul>
1355                <li>Desktop</li>
1356                <li>Mobile</li>
1357              </ul>
1358            </div>
1359            <div class="span9">
1360              <h3>When to Use</h3>
1361              <p>While the core DatetimeCell is light-weight and does the job of
1362                formatting IS0-8601 datetime strings fairly well, it may not be
1363                well suited when the datatime strings are not in ISO
1364                format.</p>
1365              <h3>Prerequisites</h3>
1366              <p>MomentCell uses <a href="http://moment.js/"
1367                title="Moment.js">Moment.js</a> to render a very powerful
1368                datetime cell. MomentCell is tested against Moment.js version
1369                1.7.2.</p>
1370              <textarea class="code-snippet" data-mode="htmlmixed">
1371                &lt;link rel="stylesheet" href="lib/extensions/moment-cell/backgrid-moment-cell.css" /&gt;
1372                &lt;script src="assets/js/moment/moment.js"&gt;&lt;/script&gt;
1373                &lt;script src="lib/extensions/moment-cell/backgrid-moment-cell.js"&gt;&lt;/script&gt;
1374                <!-- Moment.js language files for i18n. -->
1375                <!-- Moment.js language files must be included after
1376                     backgrid-moment-cell.js because it changes moment.js' default
1377                     language -->
1378                &lt;script src="assets/js/moment/lang/zh-tw.min.js"&gt;&lt;/script&gt;</textarea>
1379              <h3>Usage</h3>
1380              <p>The default MomentCell acts just like DatetimeCell, so if you
1381                have a column with datetime values, the default MomentCell is
1382                almost a drop-in replacement, with the only difference being
1383                that an offset is always present in the output.</p>
1384              <p>In addition to the ability to read and write ISO-8601 datetime
1385                strings. By specifying the model and display formats, MomentCell
1386                can convert and validated any datetime values moment.js
1387                understands.
1388              <p>Like the core cell types, you can configure MomentCell
1389                simply by extending it.</p>
1390              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1391                var Datum = Backbone.Model.extend({});
1392
1393                var Data = Backbone.Collection.extend({
1394                  model: Datum
1395                });
1396
1397                var data = new Data([{
1398                  date: "270/3/1",
1399                  time: "12:34:56.789",
1400                  datetime: "1911-10-10T07:00:00"
1401                }]);
1402
1403                var grid = new Backgrid.Grid({
1404                  columns: [{
1405                    name: "datetime",
1406                    // You can use a default MomentCell by just writing a name
1407                    cell: "moment"
1408                  }, {
1409                    name: "date",
1410                    cell: Backgrid.Extension.MomentCell.extend({
1411                      modelFormat: "YYYY/M/D",
1412                      // You can specify the locales of the model and display formats too
1413                      displayLang: "zh-tw",
1414                      displayFormat: "YYYY-MMM-DD"
1415                    })
1416                  }, {
1417                    name: "time",
1418                    cell: Backgrid.Extension.MomentCell.extend({
1419                      modelInUTC: true,
1420                      modelFormat: "HH:mm:ss.SSS",
1421                      displayFormat: "H:m:s",
1422                      // By default all the values are presumed to be in UTC,
1423                      // you can convert it to the browser's local time if you
1424                      // want
1425                      displayInUTC: false
1426                    })
1427                  }],
1428                  collection: data
1429                });
1430
1431                $("#moment-cell-example-result").append(grid.render().el);</textarea>
1432              <h3>Result</h3>
1433              <div id="moment-cell-example-result" class="backgrid-container" style="height: auto;"></div>
1434            </div>
1435          </div>
1436          <div class="row-fluid">
1437            <div class="span3">
1438              <h2 id="api-select2-cell">Select2Cell</h2>
1439              <ul class="nav">
1440                <li><a href="api/index.html#!/api/Backgrid.Extension.Select2Cell">Backgrid.Extension.Select2Cell</a></li>
1441                <li><a href="api/index.html#!/api/Backgrid.Extension.Select2CellEditor">Backgrid.Extension.Select2CellEditor</a></li>
1442              </ul>
1443              <h4>Best Used On</h4>
1444              <ul>
1445                <li>Desktop</li>
1446                <li>Mobile</li>
1447              </ul>
1448            </div>
1449            <div class="span9">
1450              <h3>When to Use</h3>
1451              <p>When you have a relatively large number of available options
1452              for a column, or want to use a select box with autocomplete
1453              capability.</p>
1454              <h3>Prerequisites</h3>
1455              <p>Select2Cell uses the <a
1456                href="http://ivaynberg.github.com/select2/"
1457                title="select2">Select2</a> jQuery plugin to render its select
1458                box. Select2Cell is tested with Select2 version 3.2.</p>
1459              <textarea class="code-snippet" data-mode="htmlmixed">
1460                &lt;link rel="stylesheet" href="assets/css/select2.css" /&gt;
1461                &lt;link rel="stylesheet" href="lib/extensions/select2-cell/backgrid-select2-cell.css" /&gt;
1462                &lt;script src="assets/js/select2.js"&gt;&lt;/script&gt;
1463                &lt;script src="lib/extensions/select2-cell/backgrid-select2-cell.js"&gt;&lt;/script&gt;</textarea>
1464              <h3>Usage</h3>
1465              <p>Select2Cell is a very simple extension of the default
1466              SelectCell. You can configure individual instances by supplying
1467              a <code>select2Options</code> object hash during extension, in
1468              addition to the options SelectCell supports.</p>
1469              <textarea class="code-snippet" data-mode="javascript" data-eval="yes">
1470
1471                var data = new Backbone.Collection([{number: 5, another: 1}]);
1472
1473                // Just like SelectCell, Select2Cell supports option lists and groups
1474                var numbers = [{name: 10, values: [
1475                  [1, 1], [2, 2], [3, 3], [4, 4], [5, 5],
1476                  [6, 6], [7, 7], [8, 8], [9, 9], [10, 10]
1477                ]}];
1478
1479                var MySelect2Cell = Backgrid.Extension.Select2Cell.extend({
1480                  select2Options: {
1481                    // any options specific to `select2` goes here
1482                  },
1483                  optionValues: numbers
1484                });
1485
1486                var grid = new Backgrid.Grid({
1487                  columns: [{
1488                    name: "number",
1489                    cell: MySelect2Cell
1490                  }, {
1491                    name: "another",
1492                    cell: MySelect2Cell
1493                  }],
1494                  collection: data
1495                });
1496
1497                $("#select2-cell-example-result").append(grid.render().el);</textarea>
1498              <h3>Result</h3>
1499              <div id="select2-cell-example-result" class="backgrid-container" style="height: auto;"></div>
1500            </div>
1501          </div>
1502        </section>
1503        <section id="styling">
1504          <div class="page-header">
1505            <h1>Styling</h1>
1506          </div>
1507          <div class="row-fluid">
1508            <div class="span12">
1509              <p>Out of the box, Backgrid.js generates simple semantic HTML
1510                table elements that you can style with pure CSS. This section is
1511                only going to briefly describe some of the more important
1512                classes, and things that you should be aware of when
1513                styling.</p>
1514
1515              <div class="row-fluid">
1516                <div class="span6">
1517                  <h2>.backgrid-container</h2>
1518                  <p>This is the class that you should put into any container
1519                    element that will hold the generated table. By default, it
1520                    has a fixed maximum height and 100% width with no borders
1521                    and paddings. It also serves as a <em>positioned</em>
1522                    element so if you need to absolutely position any elements
1523                    inside your custom table element classes, you can position
1524                    them against this container.</p>
1525                </div>
1526                <div class="span6">
1527                  <h2>&nbsp;</h2>
1528                  <textarea class="code-snippet" data-mode="css">
1529                    .backgrid-container {
1530                      position: relative;
1531                      display: block;
1532                      width: 100%;
1533                      height: 494px;
1534                      padding: 0;
1535                      overflow: auto;
1536                      border: 0;
1537                    }</textarea>
1538                </div>
1539              </div>
1540              <div class="row-fluid">
1541                <div class="span6">
1542                  <h2>.backgrid</h2>
1543                  <p>This is the class that will be applied to every Backgrid.js
1544                    generated table. All other Backgrid.js default styles on
1545                    table elements will only apply to descendents
1546                    of tables of this class.</p>
1547                  <textarea class="code-snippet" data-mode="css">
1548                    /* Say you want to give some shiny gradient background colors
1549                       to your table header */
1550                    .backgrid th {
1551                      background-image: linear-gradient(#2F2727, #1a82f7);
1552                    }</textarea>
1553                </div>
1554                <div class="span6">
1555                  <h2>&nbsp;</h2>
1556                  <p>Although usually unnecessary, if you want to completely
1557                    remove all Backgrid.js styles, you can supply
1558                    a <code>className</code> attribute to
1559                    the <code>Backgrid.Grid</code> constructor:</p>
1560                  <textarea class="code-snippet" data-mode="javascript">
1561                    var grid = new Backgrid.Grid({
1562                      className: "my-awesome-css-animated-grid",
1563                      ...
1564                    });</textarea>
1565                </div>
1566              </div>
1567              <div class="row-fluid">
1568                <div class="span12">
1569                  <h2>.backgrid .*-cell</h2>
1570                  <p>Every cell class Backgrid.js defines has a CSS class
1571                    applied to them of the same, but dasherized name. The
1572                    default styles apply a <code>text-align: left</code> to text
1573                    cells and <code>text-align: right</code> to numeric and
1574                    datetime cells. All cell editor that uses
1575                    the <code>&lt;input&gt;</code> element is absolutely
1576                    positioned against the table cell.</p>
1577                  <p>See the relevant <a href="#api-cell">cell classes</a> for
1578                    details.</p>
1579                </div>
1580              </div>
1581            </div>
1582          </div>
1583        </section>
1584        <section id="faq">
1585          <div class="page-header">
1586            <h1>Frequently Asked Questions</h1>
1587          </div>
1588          <div class="row-fluid">
1589            <div class="span12">
1590              <h2>How do I add or remove a row?</h2>
1591              <p>You can either use <a
1592              href="http://backbonejs.org/#Collection-add"
1593              title="Backbone.Collection#add">Backbone.Collection#add</a> or <a
1594              href="#api-grid" title="Grid#insertRow">Grid#insertRow</a> for
1595              insertion. Similarly, use <a
1596              href="http://backbonejs.org/#Collection-remove"
1597              title="Backbone.Collection#remove">Backbone.Collection#remove</a>
1598              or <a href="#api-grid" title="Grid#removeRow">Grid#removeRow</a>
1599              to remove rows.</p>
1600              <h2>How do I validate user input?</h2>
1601              <p>See <a href="#api-formatter" title="Formatter">Formatter</a>.</p>
1602              <h2>How do I save my row changes to the server immediately?</h2>
1603              <textarea class="code-snippet" data-mode="javascript">
1604                var MyModel = Backbone.Model.extend({
1605                  initialize: function () {
1606                    Backbone.Model.prototype.initialize.apply(this, arguments);
1607                    this.on("change", function (model, options) {
1608                      if (options && options.save === false) return;
1609                      model.save();
1610                    });
1611                  }
1612                });</textarea>
1613              <h2>Why doesn&apos;t Backgrid.js support AMD (or NPM)?</h2>
1614              <p>The same question can be asked for volo, bower, ender,
1615                browserify and many other competing solutions. The number one
1616                reason Backgrid.js does not support AMD is because of the
1617                barrier it presents to writing extensions that require
1618                third-party libraries that don&apos;t support AMD. In addition
1619                to this, Underscore.js and Backbone.js also do not support AMD
1620                at this time.</p>
1621              <p>The problem with supporting any package manager is that
1622                Backgrid.js is a highly modular project, and that deciding to
1623                use any package manager presupposes all its submodules and
1624                dependency is compatible with such a package manager and its
1625                importing mechanism. The Javascript ecosystem has gotten so
1626                diverse now that there is still not yet a clear packaging winner
1627                that everybody uses and works well under most situations, it is
1628                also not clear that ES Harmony&apos;s module system will be
1629                backward compatible with AMD.</p>
1630              <p>Having said that, Backgrid.js doesn&apos;t do anything to
1631                prevent you from adding support to your favorite package
1632                manager. You are encouraged to fork and maintain your own
1633                Backgrid.js packages.</p>
1634              <p>You are also more than welcomed to convince me
1635                on <a href="https://github.com/wyuenho/backgrid/issues">Github</a>
1636                as you may probably know more than I do about packaging
1637                Javascripts.</p>
1638              <h2>Where do I go to ask questions?</h2>
1639              <p>Just ask away
1640                on <a href="https://github.com/wyuenho/backgrid/issues">Github</a>.</p>
1641              <h2>Does Backgrid.js support adaptive scrolling?</h2>
1642              <p>Some data grid widgets out there support a technique
1643                called adaptive scrolling, meaning the DOM elements will be
1644                swapped out of a viewport and new ones appended as the
1645                models are loaded from the server, thus keeping the memory
1646                more or less constant while providing an illusion to
1647                end-users that there&apos;s no limit to the number of rows the
1648                data grid can handle.</p>
1649              <p>Backgrid.js has something better and achieves the same
1650                effect with much cleaner code -
1651                <a href="#api-paginator">paginator extension</a>, which
1652                uses <a href="https://github.com/wyuenho/backbone-pageable/"
1653                title="backbone-pageable">backbone-pageable</a>. The paginator
1654                supports both paging on the server-side, or preloading all the
1655                models and paging purely through the browser. Paginated
1656                Backgrid.Grid instances only render one page of DOM nodes at a
1657                time to save memory and keep your web page responsive.</p>
1658              <h2>Does Backgrid.js support function aggregates?</h2>
1659              <p>No, because it is not the goal of this project to produce a
1660                full-fledged web-based spreadsheet. However, doing aggregation
1661                is trivial using Underscore.js methods</p>
1662              <textarea class="code-snippet" data-mode="javascript">
1663                // sum all the values of a column
1664                var sum = collection.reduce(function (accum, num) {
1665                  return accum + num;
1666                });</textarea>
1667              <h2>Does Backgrid.js support multi-user editing?</h2>
1668              <p>Inside a Backgrid grid, every cell listens to the change event
1669                for its model value. The cells will rerender themselves during
1670                display mode upon changes in the model values. However, this
1671                functionality is only meant for synchronizing data automatically
1672                across multiple grids on the same page. If you are attempting to
1673                synchronize data changes across multiple processes, you will
1674                need some kind of a locking mechanism for the individual cells,
1675                Backgrid.js provides no help for that and you have to do this
1676                yourself. Implementing such web-based spreadsheet-like broker
1677                system is outside of the scope of this project, pull requests
1678                are welcome however.</p>
1679              <h2>Does Backgrid.js support feature (X)?</h2>
1680              <p>If the feature you have in mind isn&apos;t found here in this
1681                Backgrid.js version, it could either be in the works or under
1682                consideration.</p>
1683              <p>See the list
1684                of <a href="https://github.com/wyuenho/backgrid/issues?labels=enhancement%2Ctask&amp;page=1&amp;state=open"
1685                      title="Github Issues">tasks and enhancements</a>.</p>
1686              <h2>How to build Backgrid.js?</h2>
1687              <p><a href="https://github.com/wyuenho/backgrid/blob/gh-pages/CONTRIBUTING.md#building" title="Contributing">See Building.</a></p>
1688              <h2 id="contribute">How do I contribute?</h2>
1689              <p><a href="https://github.com/wyuenho/backgrid/blob/gh-pages/CONTRIBUTING.md" title="Contributing">See Contributing.</a></p>
1690            </div>
1691          </div>
1692        </section>
1693        <section id="license">
1694          <div class="page-header">
1695            <h1>License</h1>
1696          </div>
1697          <p>Copyright &copy; 2013 Jimmy Yuen Ho Wong and
1698            Contributors.</p>
1699          <p>Licensed under the <a href="LICENSE-MIT">MIT license</a>.</p>
1700        </section>
1701      </div>
1702    </div>
1703    <script type="text/javascript">
1704      var _gaq = _gaq || [];
1705      _gaq.push(['_setAccount', 'UA-36403214-1']);
1706      _gaq.push(['_setDomainName', 'backgridjs.com']);
1707      _gaq.push(['_setAllowLinker', true]);
1708      _gaq.push(['_trackPageview']);
1709
1710      (function() {
1711        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
1712        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
1713        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
1714      })();
1715    </script>
1716    <script src="assets/js/scale.fix.js"></script>
1717    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
1718    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
1719    <script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
1720    <script src="//cdnjs.cloudflare.com/ajax/libs/backbone-pageable/1.2.2/backbone-pageable.min.js"></script>
1721    <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/bootstrap.min.js"></script>
1722    <script src="//cdnjs.cloudflare.com/ajax/libs/select2/3.3.2/select2.min.js"></script>
1723    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.0.0/moment.min.js"></script>
1724    <script src="//cdnjs.cloudflare.com/ajax/libs/lunr.js/0.3.0/lunr.min.js"></script>
1725    <script src="lib/backgrid.min.js"></script>
1726    <script src="lib/extensions/paginator/backgrid-paginator.min.js"></script>
1727    <script src="lib/extensions/text-cell/backgrid-text-cell.min.js"></script>
1728    <script src="lib/extensions/moment-cell/backgrid-moment-cell.min.js"></script>
1729    <script src="lib/extensions/select2-cell/backgrid-select2-cell.js"></script>
1730    <script src="lib/extensions/select-all/backgrid-select-all.min.js"></script>
1731    <script src="lib/extensions/filter/backgrid-filter.min.js"></script>
1732    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/codemirror.min.js"></script>
1733    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/formatting.min.js"></script>
1734    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/xml.min.js"></script>
1735    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/css.min.js"></script>
1736    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/javascript.min.js"></script>
1737    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/htmlmixed.min.js"></script>
1738    <script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/2.36.0/shell.min.js"></script>
1739    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.0.0/lang/zh-tw.min.js"></script>
1740    <script>
1741      (function () {
1742
1743        moment.lang("en");
1744
1745        $(document).ready(function () {
1746
1747          var codestr = '';
1748
1749          $("textarea.code-snippet").each(function (index, elm) {
1750            var $elm = $(elm);
1751
1752            var codemirror = CodeMirror.fromTextArea(elm, {
1753              mode: $elm.data("mode"),
1754              readOnly: true,
1755              lineNumbers: true,
1756              theme: "ambiance",
1757              tabindex: -1
1758            });
1759
1760            var start = { line: 0, ch: 0 };
1761            var end = codemirror.posFromIndex(codemirror.getValue().length - 1);
1762
1763            codemirror.autoIndentRange(start, end);
1764
1765            if ($elm.data("eval") === "yes") {
1766              if ($elm.data("mode") === "javascript") {
1767                codestr = codestr + "\n" + codemirror.getValue();
1768              }
1769            }
1770
1771            $elm.data("codemirror", codemirror);
1772          });
1773
1774          var scriptTag = document.createElement("script");
1775          scriptTag.innerHTML = codestr;
1776          document.body.appendChild(scriptTag);
1777        });
1778
1779        $(document).ready(function () {
1780          $("a[href^='#']").click(function (e) {
1781            e.preventDefault();
1782            var target = this.hash;
1783            if (target) {
1784              var $target = $(target);
1785              $("html, body").stop().animate({
1786                "scrollTop": $target.offset().top - 55
1787              }, 500, "swing", function() {
1788                window.location.hash = target;
1789              });
1790            }
1791          });
1792        });
1793
1794        $(document).ready(function () {
1795
1796          function nextChristmas() {
1797            var now = new Date();
1798            if (now.getMonth() < 11 || (now.getMonth() == 11 && now.getDate() < 24)) {
1799              return now.getFullYear() + "-12-24T00:00Z";
1800            }
1801
1802            if (now.getMonth() == 11 && now.getDate() >= 26) {
1803              return (now.getFullYear() + 1) + "-12-24T00:00Z";
1804            }
1805          }
1806
1807          var santa1 = new Backbone.Model({
1808            name: "Santa Clause",
1809            age: new Date().getFullYear() - 270,
1810            birthday: "0270-03-01",
1811            gender: "m",
1812            alive: true
1813          });
1814
1815          var santa2 = new Backbone.Model({
1816            url: "http://santaclaus.com",
1817            email: "santa@santaclaus.com",
1818            nextDeliveryTime: nextChristmas(),
1819            hisLocalTime: moment().format("YYYY-MM-DDTHH:mm:ss.SSS\\Z"),
1820            moneyInWallet: 10.7
1821          });
1822
1823          var columns = [{
1824            name: "name",
1825            cell: "string",
1826            label: "Name (StringCell)"
1827          }, {
1828            name: "age",
1829            cell: "integer",
1830            label: "Age (IntegerCell)"
1831          }, {
1832            name: "birthday",
1833            cell: "date",
1834            label: "Birthday (DateCell)"
1835          }, {
1836            name: "gender",
1837            cell: Backgrid.SelectCell.extend({
1838              optionValues: [["Male", "m"], ["Female", "f"]]
1839            }),
1840            label: "Gender (SelectCell)"
1841          }, {
1842            name: "alive",
1843            cell: "boolean",
1844            label: "Alive (BooleanCell)"
1845          }, {
1846            name: "url",
1847            cell: "uri",
1848            label: "URL (UriCell)"
1849          }, {
1850            name: "email",
1851            cell: "email",
1852            label: "Email (EmailCell)"
1853          }, {
1854            name: "nextDeliveryTime",
1855            cell: "datetime",
1856            label: "Next Delivery Time (DateTimeCell)"
1857          }, {
1858            name: "hisLocalTime", // His local time is your local time, Santa lives at the North Pole.
1859            cell: "time",
1860            label: "His Local Time (TimeCell)"
1861          }, {
1862            name: "moneyInWallet",
1863            cell: "number",
1864            label: "Change in Wallet (NumberCell)"
1865          }];
1866
1867          var cellDemoGrid1 = new Backgrid.Grid({
1868            columns: columns.slice(0, 5),
1869            collection: new Backbone.Collection([santa1])
1870          });
1871
1872          $("#cell-demo-grid-1").append(cellDemoGrid1.render().el);
1873
1874          var cellDemoGrid2 = new Backgrid.Grid({
1875            columns: columns.slice(5),
1876            collection: new Backbone.Collection([santa2])
1877          });
1878
1879          $("#cell-demo-grid-2").append(cellDemoGrid2.render().el);
1880        });
1881      }());
1882    </script>
1883    <script>
1884      // Google +1
1885      (function() {
1886        var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
1887        po.src = 'https://apis.google.com/js/plusone.js';
1888        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
1889      })();
1890
1891      // Tweet Button
1892      !function(d,s,id) {
1893        var js,fjs=d.getElementsByTagName(s)[0];
1894        if(!d.getElementById(id)){
1895          js=d.createElement(s);
1896          js.id=id;
1897          js.src="//platform.twitter.com/widgets.js";
1898          fjs.parentNode.insertBefore(js,fjs);
1899        }
1900      }(document,"script","twitter-wjs");
1901    </script>
1902  </body>
1903</html>