PageRenderTime 61ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/index.html

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