├── img ├── .gitignore ├── icons.png ├── icons@2x.png ├── backgrid-logo.ai └── backgrid-logo.png ├── CNAME ├── favicon.ico ├── icons ├── github.png ├── gittip.png ├── google+.png ├── twitter.png └── facebook.png ├── .gitignore ├── README.md ├── .jshintrc ├── .github └── workflows │ └── semgrep.yml ├── css ├── icons.css └── main.css ├── webpack.config.js ├── src ├── templates │ ├── misc │ │ ├── license.handlebars │ │ ├── styling.handlebars │ │ └── faq.handlebars │ └── ref │ │ ├── footer.handlebars │ │ ├── row.handlebars │ │ ├── body.handlebars │ │ ├── extensions │ │ ├── development.handlebars │ │ ├── text-cell.handlebars │ │ ├── moment-cell.handlebars │ │ ├── select-all.handlebars │ │ ├── paginator.handlebars │ │ ├── select2-cell.handlebars │ │ └── filter.handlebars │ │ ├── column.handlebars │ │ ├── header.handlebars │ │ ├── forewords.handlebars │ │ ├── grid.handlebars │ │ └── formatter.handlebars └── partials │ └── layout.html ├── package.json ├── js └── main.js ├── gulpfile.js ├── misc ├── license.html └── styling.html └── ref ├── footer.html ├── row.html ├── body.html ├── extensions ├── development.html └── text-cell.html └── column.html /img/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | backgridjs.com 2 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/favicon.ico -------------------------------------------------------------------------------- /img/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/img/icons.png -------------------------------------------------------------------------------- /icons/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/icons/github.png -------------------------------------------------------------------------------- /icons/gittip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/icons/gittip.png -------------------------------------------------------------------------------- /icons/google+.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/icons/google+.png -------------------------------------------------------------------------------- /icons/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/icons/twitter.png -------------------------------------------------------------------------------- /img/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/img/icons@2x.png -------------------------------------------------------------------------------- /icons/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/icons/facebook.png -------------------------------------------------------------------------------- /img/backgrid-logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/img/backgrid-logo.ai -------------------------------------------------------------------------------- /img/backgrid-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/backgridjs.com/master/img/backgrid-logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | node_modules 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Documentation site for [Backgrid.js](http://backgridjs.com/) 2 | 3 | 4 | How to build 5 | ============ 6 | 7 | ```sh 8 | # Build for developement 9 | $ npm run build 10 | 11 | # Start the Webpack dev server 12 | $ npm run build-dev 13 | 14 | # Build for production 15 | $ NODE_DEV=production npm run build 16 | ``` 17 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "camelcase": true, 3 | "immed": true, 4 | "latedef": true, 5 | "noarg": true, 6 | "trailing": true, 7 | "expr": true, 8 | "shadow": true, 9 | "supernew": true, 10 | "boss": true, 11 | "undef": true, 12 | "unused": true, 13 | "eqnull": true, 14 | "-W018": true, 15 | "-W085": true, 16 | "evil": true, 17 | 18 | "browser": true, 19 | "node": true, 20 | "devel": true, 21 | "jquery": true, 22 | "nonstandard": true 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | 2 | on: 3 | pull_request: {} 4 | workflow_dispatch: {} 5 | push: 6 | branches: 7 | - main 8 | - master 9 | name: Semgrep config 10 | jobs: 11 | semgrep: 12 | name: semgrep/ci 13 | runs-on: ubuntu-20.04 14 | env: 15 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 16 | SEMGREP_URL: https://cloudflare.semgrep.dev 17 | SEMGREP_APP_URL: https://cloudflare.semgrep.dev 18 | SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version 19 | container: 20 | image: returntocorp/semgrep 21 | steps: 22 | - uses: actions/checkout@v3 23 | - run: semgrep ci 24 | -------------------------------------------------------------------------------- /css/icons.css: -------------------------------------------------------------------------------- 1 | /* glue: 0.4 hash: 4bcd47ad34 */ 2 | .sprite-icons-twitter, 3 | .sprite-icons-google, 4 | .sprite-icons-gittip, 5 | .sprite-icons-github, 6 | .sprite-icons-facebook{background-image:url('../img/icons.png');background-repeat:no-repeat} 7 | .sprite-icons-twitter{background-position:0px 0px;width:32px;height:32px;} 8 | .sprite-icons-google{background-position:-32px 0px;width:32px;height:32px;} 9 | .sprite-icons-gittip{background-position:0px -32px;width:32px;height:32px;} 10 | .sprite-icons-github{background-position:-32px -32px;width:32px;height:32px;} 11 | .sprite-icons-facebook{background-position:-64px 0px;width:32px;height:32px;} 12 | @media only screen and (-webkit-min-device-pixel-ratio: 2.0), only screen and (min--moz-device-pixel-ratio: 2.0), only screen and (-o-min-device-pixel-ratio: 200/100), only screen and (min-device-pixel-ratio: 2.0) {.sprite-icons-twitter, 13 | .sprite-icons-google, 14 | .sprite-icons-gittip, 15 | .sprite-icons-github, 16 | .sprite-icons-facebook{background-image:url('../img/icons@2x.png');-webkit-background-size: 96px 64px;-moz-background-size: 96px 64px;background-size: 96px 64px;}} 17 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require("webpack"); 3 | 4 | var NODE_ENV = (process.env.NODE_ENV || '').trim().toLowerCase(); 5 | 6 | module.exports = { 7 | 8 | debug: NODE_ENV != "production", 9 | 10 | devtool: NODE_ENV != "production" ? "eval-source-map" : undefined, 11 | 12 | entry: ["./js/main.js"], 13 | 14 | module: { 15 | loaders: [{ 16 | test: require.resolve("jquery"), 17 | loader: "expose?$!expose?jQuery" 18 | }, { 19 | test: require.resolve("underscore"), 20 | loader: "expose?_" 21 | }, { 22 | test: require.resolve("backbone"), 23 | loader: "expose?Backbone" 24 | }, { 25 | test: require.resolve("backgrid"), 26 | loader: "expose?Backgrid" 27 | }, { 28 | test: require.resolve("moment"), 29 | loader: "expose?moment" 30 | }] 31 | }, 32 | 33 | output: { 34 | path: path.join(__dirname, "build"), 35 | filename: "bundle.js", 36 | publicPath: "/build/", 37 | pathinfo: NODE_ENV != "production" 38 | }, 39 | 40 | plugins: NODE_ENV == "production" ? [ 41 | new webpack.DefinePlugin({ 42 | "process.env": { 43 | "NODE_ENV": NODE_ENV 44 | } 45 | }), 46 | new webpack.optimize.DedupePlugin(), 47 | new webpack.optimize.UglifyJsPlugin(), 48 | ] : [] 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/templates/misc/license.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}License{{/content}} 3 | {{#content "content"}} 4 | 7 | 8 |

Copyright © 2013-present Cloudflare, Inc and contributors.

9 | 10 |

11 | Permission is hereby granted, free of charge, to any person 12 | obtaining a copy of this software and associated documentation 13 | files (the "Software"), to deal in the Software without 14 | restriction, including without limitation the rights to use, 15 | copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the 17 | Software is furnished to do so, subject to the following 18 | conditions: 19 |

20 | 21 |

22 | The above copyright notice and this permission notice shall be 23 | included in all copies or substantial portions of the Software. 24 |

25 | 26 |

27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 29 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 31 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 32 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 34 | OTHER DEALINGS IN THE SOFTWARE. 35 |

36 | {{/content}} 37 | {{/extend}} 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backgridjs.com", 3 | "version": "0.3.7", 4 | "author": "Cloudflare, Inc and contributors ", 5 | "description": "Documentation site for Backgrid", 6 | "homepage": "http://backgridjs.com/", 7 | "keywords": [ 8 | "backgrid", 9 | "backbone" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "http://github.com/wyuenho/backgridjs.com" 14 | }, 15 | "license": "MIT", 16 | "private": true, 17 | "scripts": { 18 | "clean": "gulp clean", 19 | "build": "gulp", 20 | "build-dev": "gulp dev" 21 | }, 22 | "devDependencies": { 23 | "cssnano": "^3.5.2", 24 | "del": "^2.2.0", 25 | "expose-loader": "^0.7.1", 26 | "gulp": "^3.9.1", 27 | "gulp-cli": "^1.2.1", 28 | "gulp-compile-handlebars": "^0.6.1", 29 | "gulp-cssnano": "^2.1.1", 30 | "gulp-postcss": "^6.1.0", 31 | "gulp-rename": "^1.2.2", 32 | "gulp-sourcemaps": "^1.6.0", 33 | "gulp-util": "^3.0.7", 34 | "handlebars": "^4.0.5", 35 | "handlebars-layouts": "^3.1.3", 36 | "postcss-assets-rebase": "^0.4.0", 37 | "postcss-import": "^8.1.0", 38 | "webpack": "^1.13.0" 39 | }, 40 | "dependencies": { 41 | "backbone": "^1.3.2", 42 | "backbone.paginator": "^2.0.3", 43 | "backgrid": "^0.3.7", 44 | "backgrid-filter": "^0.3.6", 45 | "backgrid-moment-cell": "^0.3.7", 46 | "backgrid-paginator": "^0.3.7", 47 | "backgrid-select-all": "^0.3.5", 48 | "backgrid-select2-cell": "^0.3.6", 49 | "backgrid-text-cell": "^0.3.6", 50 | "bootstrap": "^3.3.6", 51 | "codemirror": "^5.13.4", 52 | "jquery": "^2.2.1", 53 | "lunr": "^0.7.0", 54 | "moment": "^2.12.0", 55 | "underscore": "^1.8.3" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/templates/ref/footer.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Footer{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

Footer

7 | 10 |
11 |
12 |

13 | Putting Things at The End of a Table 18 |

19 |

The default Footer class is an abstract class that only defines 20 | a number of required constructor parameters. If you wish to 21 | append additional information to the end of a table you must 22 | subclass Footer and supply the class to the Grid 23 | constructor.

24 | 41 |
42 |
43 | {{/content}} 44 | {{/extend}} 45 | -------------------------------------------------------------------------------- /src/templates/ref/row.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Row{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Row 8 |

9 | 13 |
14 |
15 |

16 | Customizing Row 17 |

18 |

Advanced Usage

19 |

A row is simply an intermediary view class that constructs the 20 | appropriate Cell class instances for rendering the model 21 | columns.

22 |

If you would like to override how a row is rendered, you may 23 | define your own Row subclass and give it to the Grid constructor 24 | as an option:

25 | 48 |
49 |
50 | {{/content}} 51 | {{/extend}} 52 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | var $ = require("jquery"); 2 | require("bootstrap"); 3 | var CodeMirror = require("codemirror"); 4 | require("codemirror/mode/javascript/javascript"); 5 | require("codemirror/mode/css/css"); 6 | var _ = require("underscore"); 7 | var Backbone = require("backbone"); 8 | Backbone.$ = $; 9 | var Backgrid = require("backgrid"); 10 | require("backgrid-paginator"); 11 | require("backgrid-filter"); 12 | require("backgrid-select-all"); 13 | require("backgrid-select2-cell"); 14 | require("backgrid-moment-cell"); 15 | require("backgrid-text-cell"); 16 | 17 | function unpad (str) { 18 | var lines = str.split("\n"); 19 | var spaceCounts = []; 20 | var pat = /^\s+/; 21 | for (var i = 0, l = lines.length; i < l; i++) { 22 | var result = pat.exec(lines[i]); 23 | if (result == null) spaceCounts.push(0); 24 | else spaceCounts.push(result[0].length); 25 | } 26 | var longestCommonSpaceCount = Math.min.apply(this, _.filter(spaceCounts, function (c) { return c > 0; })); 27 | for (var i = 0, l = lines.length; i < l; i++) { 28 | lines[i] = lines[i].slice(longestCommonSpaceCount); 29 | } 30 | return lines.join("\n"); 31 | } 32 | 33 | function setUpCodeMirror() { 34 | 35 | $("textarea.code-snippet").each(function (index, elm) { 36 | var $elm = $(elm); 37 | 38 | var cm = CodeMirror.fromTextArea(elm, { 39 | mode: $elm.data("mode"), 40 | lineNumbers: true, 41 | readOnly: true, 42 | theme: "eclipse", 43 | tabindex: -1 44 | }); 45 | 46 | if ($elm.data("mode") === "javascript") { 47 | var value = $elm.val(); 48 | cm.setValue(unpad(value)); 49 | if ($elm.data("eval") === "yes") { 50 | if (window.execScript) window.execScript(value); 51 | else window.eval.call(window, value); 52 | } 53 | } 54 | else { 55 | var lineCount = cm.doc.lineCount(); 56 | for (var i = 0; i < lineCount; i++) { 57 | cm.indentLine(i); 58 | } 59 | } 60 | 61 | $elm.data("codemirror", cm); 62 | }); 63 | } 64 | 65 | $(document).ready(function () { 66 | setUpCodeMirror(); 67 | 68 | $("a[href^='/#'], a[href^='#']").click(function (e) { 69 | e.preventDefault(); 70 | var target = this.hash; 71 | if (target) { 72 | var $target = $(target); 73 | $("html, body").stop().animate({ 74 | "scrollTop": $target.offset().top - 55 75 | }, 500, "swing", function() { 76 | window.location.hash = target; 77 | }); 78 | } 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /src/templates/ref/body.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Body{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Body 8 |

9 | 12 |

13 | Events 14 |

15 | 20 |
21 |
22 |

23 | Customizing Body 24 |

25 |

Truely Advanced Hacking

26 |

Body is the intermediary view that coordinates between the various 27 | parts of the grid. Specifically, the default implementation is 28 | responsible for re-rendering the rows when any model is inserted into, 29 | removed from, or reordered in the underlying collection, including 30 | sorting. See the JSDoc for 31 | details.

32 | 45 |
46 |
47 | {{/content}} 48 | {{/extend}} 49 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var _ = require("underscore"); 2 | var fs = require("fs"); 3 | var gulp = require("gulp"); 4 | var gutil = require("gulp-util"); 5 | var del = require("del"); 6 | var handlebars = require("gulp-compile-handlebars"); 7 | var handlebarsLayout = require("handlebars-layouts")(require("handlebars")); 8 | var rename = require("gulp-rename"); 9 | var postcss = require("gulp-postcss"); 10 | var atImport = require("postcss-import"); 11 | var assetsRebase = require("postcss-assets-rebase"); 12 | var cssnano = require("gulp-cssnano"); 13 | var sourcemaps = require("gulp-sourcemaps"); 14 | var webpack = require("webpack"); 15 | var webpackConfig = require("./webpack.config.js"); 16 | 17 | var NODE_ENV = (process.env.NODE_ENV || '').trim().toLowerCase(); 18 | 19 | gulp.task("clean", function () { 20 | return del(["build", "index.html", "misc", "ref"]); 21 | }); 22 | 23 | gulp.task("handlebars", function () { 24 | return gulp.src("src/templates/**/*.handlebars") 25 | .pipe(handlebars({}, { 26 | batch: ["src/partials"], 27 | helpers: handlebarsLayout 28 | })) 29 | .pipe(rename({ 30 | extname: ".html" 31 | })) 32 | .pipe(gulp.dest(".")); 33 | }); 34 | 35 | gulp.task("postcss", function () { 36 | var stream = gulp.src("css/main.css"); 37 | 38 | if (NODE_ENV != "production") { 39 | stream = stream.pipe(sourcemaps.init()); 40 | } 41 | 42 | stream = stream.pipe(postcss([ 43 | atImport(), 44 | assetsRebase({assetsPath: "build", keepStructure: false}) 45 | ])); 46 | 47 | if (NODE_ENV == "production") { 48 | stream = stream.pipe(cssnano()); 49 | } 50 | 51 | stream = stream.pipe(rename({ 52 | basename: "bundle" 53 | })); 54 | 55 | if (NODE_ENV != "production") { 56 | stream = stream.pipe(sourcemaps.write(".")); 57 | } 58 | 59 | return stream.pipe(gulp.dest("build")) 60 | }); 61 | 62 | gulp.task("webpack", function (done) { 63 | webpack(webpackConfig, function (err, stats) { 64 | if (err) throw new gutil.PluginError("webpack", err); 65 | gutil.log("[webpack]", stats.toString({ 66 | colors: true 67 | })); 68 | done(); 69 | }) 70 | }); 71 | 72 | gulp.task("dev", ["clean", "handlebars", "postcss"], function (done) { 73 | gulp.watch("src/**/*.handlebars", ["handlebars"]) 74 | .on("change", function (event) { 75 | gutil.log(event.path, "was changed"); 76 | }); 77 | 78 | gulp.watch("css/**/*.css", ["postcss"]) 79 | .on("change", function (event) { 80 | gutil.log(event.path, "was changed"); 81 | }); 82 | 83 | var compiler = webpack(webpackConfig); 84 | compiler.watch(null, function (err, stats) { 85 | if (err) throw new gutil.PluginError("webpack", err); 86 | gutil.log("[webpack]", stats.toString({ 87 | colors: true 88 | })); 89 | }); 90 | 91 | done(); 92 | }); 93 | 94 | gulp.task("default", ["clean", "handlebars", "postcss", "webpack"]); 95 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/development.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Extension Development{{/content}} 3 | {{#content "content"}} 4 | 48 | {{/content}} 49 | {{/extend}} 50 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/text-cell.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Text Cell{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | TextCell 8 |

9 | 13 |
14 |

15 | Best Used On 16 |

17 |
    18 |
  • Desktop
  • 19 |
  • Mobile
  • 20 |
21 | Download 22 |
23 |
24 |

25 | When to Use 26 |

27 |

TextCell is a string cell type that renders a form with a text 28 | area in a modal dialog instead of 29 | an <input type="text" /> editor. It 30 | is best suited for entering a large body of text.

31 |

32 | Prerequisites 33 |

34 |

TextCell requires bootstrap-modal.js to render 37 | it's modal dialog. TextCell is tested against Bootstrap 38 | version 3.0.3.

39 | 59 |

60 | Result 61 |

62 |
63 |
64 |
65 | {{/content}} 66 | {{/extend}} 67 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | @import 'bootstrap'; 2 | @import 'codemirror/lib/codemirror.css'; 3 | @import 'codemirror/theme/eclipse.css'; 4 | @import 'backgrid/lib/backgrid.css'; 5 | @import 'backgrid-filter/backgrid-filter.css'; 6 | @import 'backgrid-moment-cell/backgrid-moment-cell.css'; 7 | @import 'backgrid-paginator/backgrid-paginator.css'; 8 | @import 'backgrid-select-all/backgrid-select-all.css'; 9 | @import 'backgrid-select2-cell/backgrid-select2-cell.css'; 10 | @import 'backgrid-text-cell/backgrid-text-cell.css'; 11 | @import './icons.css'; 12 | 13 | 14 | .desktop-logo { 15 | width: 90%; 16 | } 17 | 18 | .mobile-logo { 19 | width: 100px; 20 | margin-right: 20px; 21 | display: inline-block!important; 22 | } 23 | 24 | .jumbotron h1 { 25 | margin-top: 0px; 26 | margin-bottom: 20px; 27 | } 28 | 29 | #social-media { 30 | line-height: 50px; 31 | height: 50px; 32 | overflow: hidden; 33 | } 34 | 35 | #social-media > li { 36 | padding-top: 10px; 37 | margin-right: 1em; 38 | } 39 | 40 | #social-media > li:last-child { 41 | margin-right: 15px; 42 | } 43 | 44 | #social-media > li > a { 45 | padding: 0; 46 | margin: 0; 47 | display: inline-block; 48 | } 49 | 50 | .page-header { 51 | margin: 30px 0; 52 | } 53 | 54 | h1,h2,h3,h4,h5,h6,.navbar-brand { 55 | font-family: 'Hoefler Text', Baskerville, Times, Georgia, 'Times New Roman', serif; 56 | font-weight: normal; 57 | } 58 | 59 | a.section { 60 | color: inherit; 61 | text-decoration: none; 62 | } 63 | 64 | a.section:hover:after { 65 | content: " §"; 66 | vertical-align: middle; 67 | color: lightgray; 68 | } 69 | 70 | h1 > a.section:hover:after { 71 | font-size: 22px; 72 | } 73 | 74 | h2 > a.section:hover:after { 75 | font-size: 20px; 76 | } 77 | 78 | h3 > a.section:hover:after { 79 | font-size: 18px; 80 | } 81 | 82 | h4 > a.section:hover:after { 83 | font-size: 16px; 84 | } 85 | 86 | .note { 87 | color: #777; 88 | font-style: italic; 89 | font-family: Baskerville, serif; 90 | font-size: 15px; 91 | } 92 | 93 | .note h1, 94 | .note h2, 95 | .note h3, 96 | .note h4, 97 | .note h5, 98 | .note h6 { 99 | font-size: 15px; 100 | margin: 20px 0 0; 101 | } 102 | 103 | html, 104 | body { 105 | height: 100%; 106 | } 107 | 108 | #main { 109 | min-height: 100%; 110 | height: auto; 111 | margin: 0 auto -80px; 112 | padding: 50px 0 60px; 113 | } 114 | 115 | #layout-footer { 116 | margin-top: 20px; 117 | height: 60px; 118 | line-height: 60px; 119 | background-color: #f5f5f5; 120 | text-align: center; 121 | } 122 | 123 | #layout-footer p { 124 | margin-bottom: 0; 125 | } 126 | 127 | .nav.nav-stacked > li > a { 128 | padding: 0; 129 | } 130 | 131 | .backgrid-container { 132 | margin-bottom: 20px; 133 | } 134 | 135 | .CodeMirror { 136 | border: 1px solid #ddd; 137 | -webkit-border-radius: 4px; 138 | -moz-border-radius: 4px; 139 | border-radius: 4px; 140 | margin-bottom: 10px; 141 | height: auto; 142 | } 143 | 144 | .CodeMirror-scroll { 145 | overflow-y: hidden; 146 | overflow-x: auto; 147 | } 148 | 149 | @media (max-width: 991px) { 150 | .jumbotron .logo.hidden-md.hidden-lg { 151 | display: inline-block!important; 152 | height: 63px; 153 | margin-right: 20px; 154 | } 155 | } 156 | 157 | @media (max-width: 767px) { 158 | .navbar.navbar-fixed-top { 159 | margin-left: 0; 160 | margin-right: 0; 161 | } 162 | 163 | .jumbotron h1 { 164 | font-size: 48px; 165 | } 166 | 167 | #layout-footer { 168 | height: 154px; 169 | } 170 | 171 | #layout-footer p { 172 | padding: 50px 0; 173 | line-height: 1.3em; 174 | } 175 | 176 | #main { 177 | margin: 0 auto -140px; 178 | padding: 50px 0 120px; 179 | } 180 | } 181 | 182 | @media (max-width: 479px) { 183 | .jumbotron h1 { 184 | text-align: center; 185 | } 186 | .jumbotron .mobile-logo { 187 | margin: 0 auto 20px; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/templates/ref/column.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Column{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Columns 8 |

9 | 13 |
14 |
15 |

16 | Column Defaults 17 |

18 |

Column defaults and required parameters are defined in 19 | the Backgrid.Column.prototype.defaults 21 | hash.

22 |

23 | Column Definition 24 |

25 |

A Column is a placeholder for a column definition.

26 |

You usually don't need to create an instance of this class 27 | yourself, as a collection of column instances will be created for 28 | you from a list of column object literals you provide to the 29 | Backgrid view class constructors.

30 |

Internally, columns are stored as a collection in the form of 31 | Backgrid.Columns. In addition, all parent views will convert the 32 | column definition into 33 | a Backgrid.Columns 34 | collection and pass a reference to any subviews that require 35 | it.

36 |

37 | Listening to Column Attribute Changes 39 |

40 |

Occasionally, you may want to listen to column attribute change 41 | events. In that case, you can choose to initialize a 42 | Backgrid.Columns collection and listen to events from the 43 | individual models.

44 | 62 |

63 | Getting the Column Definitions from the Server 68 |

69 |

Since Backgrid.Columns is also a Backbone.Collection, you can 70 | dynamically load and store your column definition via your server.

71 | 85 |
86 |
87 | {{/content}} 88 | {{/extend}} 89 | -------------------------------------------------------------------------------- /src/templates/misc/styling.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Styling{{/content}} 3 | {{#content "content"}} 4 | 9 |
10 |
11 |

Out of the box, Backgrid.js generates simple semantic HTML 12 | table elements that you can style with pure CSS. This section is 13 | only going to briefly describe some of the more important 14 | classes, and things that you should be aware of when 15 | styling.

16 | 17 |
18 |
19 |

20 | .backgrid-container 21 |

22 |

This is the class that you should put into any container 23 | element that will hold the generated table. By default, it 24 | has a fixed maximum height and 100% width with no borders 25 | and paddings. It also serves as a positioned 26 | element so if you need to absolutely position any elements 27 | inside your custom table element classes, you can position 28 | them against this container.

29 |
30 |
31 |

 

32 | 43 |
44 |
45 |
46 |
47 |

48 | .backgrid 49 |

50 |

This is the class that will be applied to every Backgrid.js 51 | generated table. All other Backgrid.js default styles on 52 | table elements will only apply to descendents 53 | of tables of this class.

54 | 66 |
67 |
68 |

 

69 |

Although usually unnecessary, if you want to completely 70 | remove all Backgrid.js styles, you can supply 71 | a className attribute to 72 | the Backgrid.Grid constructor:

73 | 78 |
79 |
80 |
81 |
82 |

83 | .backgrid .*-cell 84 |

85 |

Every cell class Backgrid.js defines has a CSS class 86 | applied to them of the same, but dasherized name. The 87 | default styles apply a text-align: left to text 88 | cells and text-align: right to numeric and 89 | datetime cells. 90 |

See the relevant cell classes for 91 | details.

92 |
93 |
94 |
95 |
96 | {{/content}} 97 | {{/extend}} 98 | -------------------------------------------------------------------------------- /src/templates/ref/header.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Header{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Header 8 |

9 | 14 |

15 | Events 16 |

17 | 20 |
21 |
22 |

23 | Understanding the Default Header 28 |

29 |

Backgrid comes with a default header section, a header row and a 30 | header cell implementation that renders a sorter if the column is 31 | sortable. The text inside the header cells comes from the column 32 | definitions. If a label is not defined in a 33 | column definition, its name is used as the label instead.

34 |

The default header cell implementation supports sorting in ascending 35 | or descending order, using the column's natural ordering. The 36 | sorter will also allow cycling back to the table's default 37 | sorting order, which is sorting by the model client IDs.

39 |

40 | Customizing the Header 45 |

46 |

If you want to change the default sort behavior to only toggle 47 | between sorting in ascending or descending order, you do this by 48 | passing sortType: "toggle" as part of your column 49 | definition.

50 | 64 |

Advanced Usage

65 |

You are allow to use a different header cell class on 66 | columns. There is no restriction on what a header cell must do. In fact, 67 | any Backbone.View class can be 69 | used. However, if you wish to modify how the sorter behaves, you 70 | must implement the sorting protocol. See 71 | the JSDoc for details.

73 | 90 |
91 |
92 | {{/content}} 93 | {{/extend}} 94 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/moment-cell.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Moment Cell{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | MomentCell 8 |

9 | 13 |
14 |

15 | Best Used On 16 |

17 |
    18 |
  • Desktop
  • 19 |
  • Mobile
  • 20 |
21 | Download 22 |
23 |
24 |

25 | When to Use 26 |

27 |

While the core DatetimeCell is light-weight and does the job of 28 | formatting IS0-8601 datetime strings fairly well, it may not be 29 | well suited when the datatime strings are not in ISO 30 | format.

31 |

32 | Prerequisites 33 |

34 |

MomentCell uses Moment.js to render a very powerful 36 | datetime cell. MomentCell is tested against Moment.js version 37 | 2.5.0.

38 |

39 | Usage 40 |

41 |

The default MomentCell acts just like DatetimeCell, so if you 42 | have a column with datetime values, the default MomentCell is 43 | almost a drop-in replacement, with the only difference being 44 | that an offset is always present in the output.

45 |

In addition to the ability to read and write ISO-8601 datetime 46 | strings. By specifying the model and display formats, MomentCell 47 | can convert and validated any datetime values moment.js 48 | understands. 49 |

Like the core cell types, you can configure MomentCell 50 | simply by extending it.

51 | 93 |

94 | Result 95 |

96 |
97 |
98 |
99 | {{/content}} 100 | {{/extend}} 101 | -------------------------------------------------------------------------------- /src/templates/ref/forewords.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Core{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 | 11 |

Backgrid aims to be a highly modular and flexible library that aims 12 | to provide you with a set of basic building blocks for creating all 13 | kinds of data grids.

14 |

15 | Architecture 16 |

17 |

Backgrid is primarily comprised of a set of highly reusable Backbone.View subclasses and a number of 20 | internal models and helper classes. In 22 | practical terms, this architecture ensures that if you are already 23 | familiar with Backbone, you can carry that knowledge over and apply to 24 | Backgrid directly.

25 |

26 | Laying out Components 27 |

28 |

Backgrid's View components are, borrowing from Marionette's 30 | parlance, primarily CollectionView and ItemView 31 | components, which means the components are to be layed out 32 | sequentially. However, the Grid's root element itself can be inserted 33 | to any where in the DOM.

34 | 39 |

40 | Event Handling 41 |

42 |

Another notable architectural choice Backgrid has made involves how 43 | it handles events. Backgrid takes advantage of the fact that every 44 | Backbone class implements the Backbone.Events interface. Internally, 45 | every Backgrid object shares one or more of Columns, Column, 46 | Collection and Model, Backgrid simply treats them as "event buses" to 47 | enable cross-component communication without requiring every Backgrid 48 | component to know of the existence and implementation of each other. 49 |

50 |

Since all Model events will bubble up to the collection, interested 51 | components can simply treat the Columns and Collection instances as 52 | "event queues" and "subscribe" to the Backgrid events. All Backgrid 53 | events are effectively notifications of state changes, any objects 54 | that mixes in Backbone.Events can react to these state changes. You 55 | can find a list of relevant events in this document.

56 |

57 | Customization 58 |

59 |

If you are coming from a jQuery background, you'd notice that most of 60 | the jQuery plugins, no matter how "good" that are, for some measure of 61 | "goodness", are extremely difficult to customize. Most jQuery plugins 62 | with a modicum of complexity will give you at least dozens of 63 | options. The general rule of thumb is, if it doesn't work the way you 64 | want it, ask the author to throw more options at the problem. Failing 65 | that, spend an inordinate amount of time to source for another similar 66 | plugin. If all else failed, you have to roll your own plugin.

67 |

Your laziness has backfired, but that doesn't have to be the case.

68 |

The inherant problem with the jQuery plugin model is that it doesn't 69 | offer you any help other than giving you a namespace, and the combined 70 | laziness of plugin authors and users have created an ecosystem full of 71 | opaque plugins that produce DOM structures that are hard to 72 | comprehend, hard to style and behaviors impossible to alter, no matter 73 | how trivial they should be.

74 |

75 | Backgrid offers 3 levels of customization: 76 |

77 |
    78 |
  • 79 | Options to the Grid constructor - Used for required parameters and 80 | generic behavior provide by Backgrid that you want to switch on or 81 | off. 82 |
  • 83 |
  • 84 | Styling via CSS - Backgrid's generated DOM structure consists 85 | solely of your plain old <table> HTML elements, 86 | just style them as such. 87 |
  • 88 |
  • 89 | Inheritance - Subclass a Backgrid component, give it your 90 | preferred behavior, give the new class to the Grid constructor and 91 | voila. 92 |
  • 93 |
94 |

Go on to the Core API reference to find out more:

95 | 105 |
106 |
107 | {{/content}} 108 | {{/extend}} 109 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/select-all.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Select All{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | SelectAll 8 |

9 | 13 |

14 | Events 15 |

16 | 21 |
22 |

23 | Best Used On 24 |

25 |
    26 |
  • Desktop
  • 27 |
  • Mobile
  • 28 |
29 | Download 30 |
31 |
32 |

33 | When to Use 34 |

35 |

When you want to select multiple models at a time for batch operations.

36 |

37 | Usage 38 |

39 |

To enable the SelectAll extension, you simply have to add a new 40 | column to your column definition like so:

41 | 72 |
73 |
74 |
75 |
76 |

Result

77 |
78 |
79 |
80 |
81 |
82 |

You can also use this extension in concert with Backbone.PageableCollection. In 85 | which case SelectAll will select across all pages by default, whether 86 | the PageableCollection is in server, client or infinite mode. See this 87 | example.

88 |
89 |
90 |
91 |
92 |

93 | Manipulating Selections Programatically 98 |

99 |

At any point during the lifetime of your program, if you'd like 100 | to get an array of the currently selected models after you've 101 | rendered your grid, you can easily do so:

102 | 114 |
115 |
116 |
117 |
118 |

Pro Tip

119 |

Each SelectRowCell will trigger a backgrid:selected 120 | event directly from the selected models when its checkbox value 121 | changes, so if you want to react to those events, you can attach 122 | your event handlers on the collection.

123 |

See the API 125 | documentation for details.

126 |
127 |
128 | {{/content}} 129 | {{/extend}} 130 | -------------------------------------------------------------------------------- /src/templates/ref/grid.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Grid{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Grid 8 |

9 | 12 |

13 | Events 14 |

15 | 18 |
19 |
20 |

21 | How to Use the Grid 22 |

23 |

As described in the examples, a basic 24 | grid needs only a collection and a list of column definitions.

25 |

To display the grid, you will need to render the grid and insert the 26 | grid's root element to the DOM in order to display it.

27 | 38 |

39 | Manipulating Columns and Rows 40 |

41 |

It is very easy to insert or remove a row in a grid, you just 42 | have to pass a model reference 43 | to Grid#insertRow 44 | or Grid#removeRow.

45 | 56 |

Inserting and remove columns is similarly easy. You just need 57 | to pass some definitions 58 | to Grid#insertColumn 59 | or 60 | Grid#removeColumn.

61 | 87 |

88 | Sorting Programmatically 89 |

90 |

Sometimes, you might want to set the grid to a sorted state before 91 | displaying it, you can do that by calling Grid#sort() 92 | with a column name and a direction:

93 | 100 |

Sometime you may want to render a grid in a sorted state, probably 101 | based on a previously saved sorting state. You can supply a 102 | direction to a column definition and a sorted collection to 103 | a grid's constructor before you render it:

104 | 121 |

122 | Empty Message 123 |

124 |

If you want to display a message when the grid is empty. You can pass 125 | anemptyText string to the options object 126 | to the Grid's constructor.

127 | 133 |
134 |
135 | {{/content}} 136 | {{/extend}} 137 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/paginator.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Paginator{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Paginator 8 |

9 | 13 |
14 |

15 | Best Used On 16 |

17 |
    18 |
  • Desktop
  • 19 |
  • Mobile
  • 20 |
21 | Download 22 |
23 |
24 |

25 | When to Use 26 |

27 |

When you have more data than your grid can fit, you can use 28 | Paginator to break the display of your data into pages.

29 |

30 | Prerequisites 31 |

32 |

Backgrid.Extension.Paginator needs a Backbone.Collection 33 | subclass that supports pagination. Luckily, there is already one 34 | available specially written for this purpose 35 | - Backbone.PageableCollection.

37 |

Backbone.PageableCollection is a strict superset of the vanilla 38 | Backbone.Collection with additional pagination and sorting 39 | functionality. If you like, you can use 40 | Backbone.PageableCollection throughout your application and it 41 | will work exactly the same as Backbone.Collection.

42 |

43 | Backbone.PageableCollection 48 |

49 |

Out of the box, Backbone.PageableCollection works with RESTful 50 | APIs that accept Ruby's will_paginate pagination query 51 | parameters but you are able to configure the query string 52 | mapping anyway you like. The following example works with 53 | Github's API:

55 | 88 |

89 | Configuring Backgrid.Extension.Paginator 94 |

95 |

Backgrid.Extension.Paginator supports a number of configuration 96 | options to adjust to the size of the result set. You can control the 97 | default window size, how many pages to slide an whether the grid 98 | should go back to the first page after sorting.

99 | 148 |

149 | Result 150 |

151 | 158 |
159 |

Advanced Usage

160 |

You can control how the control and page handles are rendered, you 161 | can even control how the sliding window algorithm works. Please refer 162 | to the JSDoc for details.

165 |
166 |
167 | {{/content}} 168 | {{/extend}} 169 | -------------------------------------------------------------------------------- /src/templates/ref/formatter.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Formatter{{/content}} 3 | {{#content "content"}} 4 |
5 | 19 |
20 |

21 | Introduction 22 |

23 |

In Backgrid, cell formatters serves the purpose of converting values 24 | between JSON value types and strings, and validation. Writing 25 | formatters for value conversion and validation is easy as you only 26 | have to conform to a very simple protocol.

27 |

Pro Tip

28 |

Formatters are used for string formatting, not manipulating 29 | the DOM and styling. Use render for that.

31 |

32 | Custom Formatters 33 |

34 |

Any formatters must have the following two methods defined:

35 | 42 |

fromRaw() is called by Backgrid.Cell and its 43 | subclasses whenever a raw model value needs to be formatted into 44 | a humanized form for display.

45 |

toRaw() is called by Backgrid.CellEditor and its 46 | subclasses whenever a user input string needs to be converted back 47 | to a raw JSON value for model persistence.

48 |

The model parameter is not used by any built-in 49 | formatters, but sometimes you may want to decide how to format your 50 | values depending on the other values in the model. You can use it in 51 | your custom formatters if that's the case.

52 |

53 | Validation 54 |

55 |

In addition to user input conversion, toRaw() also 56 | validates the user input during conversion. If the user input is 57 | invalid or cannot be converted to a JSON value, 58 | toRaw()MUST return 59 | undefined instead of throwing an Error.

60 |

In addition to using formatters to do simple yes or no 61 | validations, if your model class has 62 | a validate() method defined, 64 | it will also be used for validation after trying with the 65 | formatter.

66 |

67 | SelectFormatter 68 |

69 |

The most common formatter you'll override is probably 70 | SelectFormatter. Suppose your column expects an integer, due to a 71 | limitation of the DOM, the default toRaw() implementation 72 | will simply return the selected value from the DOM, which is always a 73 | string.

74 |

If you need to store a different type, you should override the 75 | formatter to provide a toRaw() implementation that returns a 76 | correct type:

77 | 84 |

If you want to use a SelectCell with multiple select, and if the type 85 | of your model value is not string, you have to override 86 | toRaw to return an array of values:

87 | 96 |

97 | Using Custom Formatters 98 |

99 |

A custom formatter supplied to a column definition will be used 100 | instead of the cell's default:

101 | 114 |

To make your custom cell and custom formatter reuseable, you can 115 | package them up together and give your custom cell to a column 116 | definition:

117 | 136 |
137 |
138 | {{/content}} 139 | {{/extend}} 140 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/select2-cell.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Select2 Cell{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Select2Cell 8 |

9 | 13 |
14 |

15 | Best Used On 16 |

17 |
    18 |
  • Desktop
  • 19 |
  • Mobile
  • 20 |
21 | Download 22 |
23 |
24 |

25 | When to Use 26 |

27 |

When you have a relatively large number of available options 28 | for a column, or want to use a select box with autocomplete 29 | capability.

30 |

31 | Prerequisites 32 |

33 |

Select2Cell uses the Select2 jQuery plugin to render its select 36 | box. Select2Cell is tested with Select2 version 3.4.5.

37 |

38 | Usage 39 |

40 |

Select2Cell is a very simple extension of the default SelectCell. You can configure individual 43 | instances by supplying a select2Options object hash 44 | during extension, in addition to the options SelectCell supports.

45 | 86 |

87 | Result 88 |

89 |
90 |

91 | Getting data for optionValues 96 |

97 |

The Select2Cell and its superclass SelectCell assumes that the data for the select 100 | box will have been loaded before the grid is rendered. As a 101 | consequence of this design decision, select's ability to load its 102 | options dynamically is rendered useless.

103 |

The reason for this design is when the cell is in display mode, it 104 | needs to render a label, not its database ID value, so the data will 105 | have been already loaded even before the Select2CellEditor goes into 106 | effect.

107 |

To keep your optionValues fresh, you can try one of the following 108 | approaches:

109 | 171 |
172 |
173 | {{/content}} 174 | {{/extend}} 175 | -------------------------------------------------------------------------------- /src/partials/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - {{#block "title"}}{{/block}} 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 | {{#block "content"}}{{/block}} 146 |
147 |
148 | 159 | {{#block "endscripts"}} 160 | 173 | 174 | {{/block}} 175 | 176 | 177 | -------------------------------------------------------------------------------- /misc/license.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - License 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 | 148 | 149 |

Copyright © 2013-present Cloudflare, Inc and contributors.

150 | 151 |

152 | Permission is hereby granted, free of charge, to any person 153 | obtaining a copy of this software and associated documentation 154 | files (the "Software"), to deal in the Software without 155 | restriction, including without limitation the rights to use, 156 | copy, modify, merge, publish, distribute, sublicense, and/or sell 157 | copies of the Software, and to permit persons to whom the 158 | Software is furnished to do so, subject to the following 159 | conditions: 160 |

161 | 162 |

163 | The above copyright notice and this permission notice shall be 164 | included in all copies or substantial portions of the Software. 165 |

166 | 167 |

168 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 169 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 170 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 171 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 172 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 173 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 174 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 175 | OTHER DEALINGS IN THE SOFTWARE. 176 |

177 | 178 |
179 |
180 | 191 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /ref/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Footer 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 |
146 |
147 |

Footer

148 | 151 |
152 |
153 |

154 | Putting Things at The End of a Table 159 |

160 |

The default Footer class is an abstract class that only defines 161 | a number of required constructor parameters. If you wish to 162 | append additional information to the end of a table you must 163 | subclass Footer and supply the class to the Grid 164 | constructor.

165 | 182 |
183 |
184 | 185 |
186 |
187 | 198 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /ref/row.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Row 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 |
146 |
147 |

148 | Row 149 |

150 | 154 |
155 |
156 |

157 | Customizing Row 158 |

159 |

Advanced Usage

160 |

A row is simply an intermediary view class that constructs the 161 | appropriate Cell class instances for rendering the model 162 | columns.

163 |

If you would like to override how a row is rendered, you may 164 | define your own Row subclass and give it to the Grid constructor 165 | as an option:

166 | 189 |
190 |
191 | 192 |
193 |
194 | 205 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /ref/body.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Body 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 |
146 |
147 |

148 | Body 149 |

150 | 153 |

154 | Events 155 |

156 | 161 |
162 |
163 |

164 | Customizing Body 165 |

166 |

Truely Advanced Hacking

167 |

Body is the intermediary view that coordinates between the various 168 | parts of the grid. Specifically, the default implementation is 169 | responsible for re-rendering the rows when any model is inserted into, 170 | removed from, or reordered in the underlying collection, including 171 | sorting. See the JSDoc for 172 | details.

173 | 186 |
187 |
188 | 189 |
190 |
191 | 202 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /ref/extensions/development.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Extension Development 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 | 189 | 190 |
191 |
192 | 203 | 216 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /src/templates/misc/faq.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}FAQ{{/content}} 3 | {{#content "content"}} 4 | 13 |
14 |
15 |

How do I write a cell that renders a button?

19 |

It is quite common to want to use a cell that acts on an entire 20 | row. You may want to pop up a modal, delete the row, or toggle 21 | editibility for all the columns. The possibilities are endless. For 22 | those cases, you can write a custom ActionCell, and then 23 | pass it to the column definition.

24 | 49 |

50 | How do I add a column of computed values? 55 |

56 |

The easiest way to do it is to extend your models from a 57 | Backbone.Model subclass that supports computed 58 | properties and accessing them via the same get/set 59 | interface. There are a number of Backbone plugins readily available for 68 | this. Should all else failed, you can roll your own fairly 71 | easily.

72 |

73 | How do I add or remove a row? 78 |

79 |

You can either use Backbone.Collection#add or Grid#insertRow for 83 | insertion. Similarly, use Backbone.Collection#remove 86 | or Grid#removeRow 87 | to remove rows.

88 |

89 | How do I put the grid in a default sorted state? 94 |

95 |

See the sorting 97 | programmatically section.

98 |

99 | How do I validate user input? 104 |

105 |

See the validation section on Formatter.

106 |

107 | How do I save my row changes to the server immediately? 112 |

113 | 123 |

124 | Where do I go to ask questions? 129 |

130 |

131 | Finding an answer to your question about Backgrid is a simple 4-step process: 132 |

133 |
    134 |
  1. Ponder about the wisdom of your question and the answer you seek.
  2. 135 |
  3. Search this document for the keywords you are looking for.
  4. 136 |
  5. Pay your tribute to the almighty Google.
  6. 137 |
  7. 138 | Go to StackOverflow 139 | or as a last resort, Github. 140 |
  8. 141 |
142 |

143 | Does Backgrid.js support adaptive scrolling? 148 |

149 |

Some data grid widgets out there support a technique 150 | called adaptive scrolling, meaning the DOM elements will be 151 | swapped out of a viewport and new ones appended as the 152 | models are loaded from the server, thus keeping the memory 153 | more or less constant while providing an illusion to 154 | end-users that there's no limit to the number of rows the 155 | data grid can handle.

156 |

Backgrid.js has something better and achieves the same 157 | effect with much cleaner code - 158 | paginator extension, which 159 | uses backbone.paginator. The paginator 161 | supports both paging on the server-side, or preloading all the 162 | models and paging purely through the browser. Paginated 163 | Backgrid.Grid instances only render one page of DOM nodes at a 164 | time to save memory and keep your web page responsive.

165 |

166 | Does Backgrid.js support function aggregates? 171 |

172 |

No, because it is not the goal of this project to produce a 173 | full-fledged web-based spreadsheet. However, doing aggregation is 174 | trivial using Underscore.js methods.

175 | 180 |

If you use a Backbone plugin that supports computed values, you may also treat the 182 | computed values as a column as well.

183 |

184 | Does Backgrid.js support multi-user editing? 189 |

190 |

Inside a Backgrid grid, every cell listens to the change event 191 | for its model value. The cells will rerender themselves during 192 | display mode upon changes in the model values. However, this 193 | functionality is only meant for synchronizing data automatically 194 | across multiple grids on the same page. If you are attempting to 195 | synchronize data changes across multiple processes, you will 196 | need some kind of a locking mechanism for the individual cells, 197 | Backgrid.js provides no help for that and you have to do this 198 | yourself. Implementing such web-based spreadsheet-like broker 199 | system is outside of the scope of this project, pull requests 200 | are welcome however.

201 |

202 | Does Backgrid.js support feature (X)? 207 |

208 |

If the feature you have in mind isn't found here in this 209 | Backgrid.js version, it could either be in the works or under 210 | consideration.

211 |

See the list 212 | of tasks and enhancements.

214 |

215 | How to build Backgrid.js? 216 |

217 |

See Building.

218 |

219 | How do I contribute? 220 |

221 |

See Contributing.

222 |
223 |
224 | {{/content}} 225 | {{/extend}} 226 | -------------------------------------------------------------------------------- /ref/extensions/text-cell.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Text Cell 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 |
146 |
147 |

148 | TextCell 149 |

150 | 154 |
155 |

156 | Best Used On 157 |

158 |
    159 |
  • Desktop
  • 160 |
  • Mobile
  • 161 |
162 | Download 163 |
164 |
165 |

166 | When to Use 167 |

168 |

TextCell is a string cell type that renders a form with a text 169 | area in a modal dialog instead of 170 | an <input type="text" /> editor. It 171 | is best suited for entering a large body of text.

172 |

173 | Prerequisites 174 |

175 |

TextCell requires bootstrap-modal.js to render 178 | it's modal dialog. TextCell is tested against Bootstrap 179 | version 3.0.3.

180 | 200 |

201 | Result 202 |

203 |
204 |
205 |
206 | 207 |
208 |
209 | 220 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /ref/column.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Column 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 |
146 |
147 |

148 | Columns 149 |

150 | 154 |
155 |
156 |

157 | Column Defaults 158 |

159 |

Column defaults and required parameters are defined in 160 | the Backgrid.Column.prototype.defaults 162 | hash.

163 |

164 | Column Definition 165 |

166 |

A Column is a placeholder for a column definition.

167 |

You usually don't need to create an instance of this class 168 | yourself, as a collection of column instances will be created for 169 | you from a list of column object literals you provide to the 170 | Backgrid view class constructors.

171 |

Internally, columns are stored as a collection in the form of 172 | Backgrid.Columns. In addition, all parent views will convert the 173 | column definition into 174 | a Backgrid.Columns 175 | collection and pass a reference to any subviews that require 176 | it.

177 |

178 | Listening to Column Attribute Changes 180 |

181 |

Occasionally, you may want to listen to column attribute change 182 | events. In that case, you can choose to initialize a 183 | Backgrid.Columns collection and listen to events from the 184 | individual models.

185 | 203 |

204 | Getting the Column Definitions from the Server 209 |

210 |

Since Backgrid.Columns is also a Backbone.Collection, you can 211 | dynamically load and store your column definition via your server.

212 | 226 |
227 |
228 | 229 |
230 |
231 | 242 | 255 | 256 | 257 | 258 | -------------------------------------------------------------------------------- /src/templates/ref/extensions/filter.handlebars: -------------------------------------------------------------------------------- 1 | {{#extend "layout"}} 2 | {{#content "title"}}Filters{{/content}} 3 | {{#content "content"}} 4 |
5 |
6 |

7 | Filter 8 |

9 | 14 |
15 |

16 | Best Used On 17 |

18 |
    19 |
  • Desktop
  • 20 |
  • Mobile
  • 21 |
22 | Download 23 |
24 |
25 |

26 | When to Use 27 |

28 |

When you have lots of rows with lots of text, and you just want 29 | to quickly get to the row that only contain certain keywords.

30 |

31 | Prerequisites 32 |

33 |

There are no extra dependencies for ServerSideFilter and 34 | ClientSideFilter.

35 |

For LunrFilter, it has a hard dependency on lunr.js for 37 | full-text searching.

38 |

39 | ServerSideFilter 40 |

41 |

ServerSideFilter is suitable if you have a server where you send the 42 | search queries to get back a result. The follow example will create a 43 | collection that uses Github's excellent API to search for Github 44 | users. See here for the valid search terms 47 | to use.

48 | 84 | 94 |
95 | 102 |

103 | Tip 104 | Github Search User API 105 |

106 |
107 |
108 |

109 | ClientSideFilter 110 |

111 | 125 |
126 |
127 |
128 |

129 | LunrFilter 130 |

131 | 147 |
148 |
149 |
150 |

Pro Tip

151 |

ClientSideFilter and LunrFilter won't work unless the collection 152 | contains all the data for filtering at the time the filters are 153 | initialized. If you are fetching data after the filters were 154 | initialized and using Backbone 1.0.0+, you should pass {remove: 155 | true} or {reset: true} to 156 | Collection#fetch() due to the change to 157 | Collection#set() after fetching. 160 |

161 |
162 | {{/content}} 163 | {{#content "endscripts" mode="append"}} 164 | 334 | {{/content}} 335 | {{/extend}} 336 | -------------------------------------------------------------------------------- /misc/styling.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Backgrid.js - Styling 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 |
34 |
35 | 143 |
144 |
145 | 150 |
151 |
152 |

Out of the box, Backgrid.js generates simple semantic HTML 153 | table elements that you can style with pure CSS. This section is 154 | only going to briefly describe some of the more important 155 | classes, and things that you should be aware of when 156 | styling.

157 | 158 |
159 |
160 |

161 | .backgrid-container 162 |

163 |

This is the class that you should put into any container 164 | element that will hold the generated table. By default, it 165 | has a fixed maximum height and 100% width with no borders 166 | and paddings. It also serves as a positioned 167 | element so if you need to absolutely position any elements 168 | inside your custom table element classes, you can position 169 | them against this container.

170 |
171 |
172 |

 

173 | 184 |
185 |
186 |
187 |
188 |

189 | .backgrid 190 |

191 |

This is the class that will be applied to every Backgrid.js 192 | generated table. All other Backgrid.js default styles on 193 | table elements will only apply to descendents 194 | of tables of this class.

195 | 207 |
208 |
209 |

 

210 |

Although usually unnecessary, if you want to completely 211 | remove all Backgrid.js styles, you can supply 212 | a className attribute to 213 | the Backgrid.Grid constructor:

214 | 219 |
220 |
221 |
222 |
223 |

224 | .backgrid .*-cell 225 |

226 |

Every cell class Backgrid.js defines has a CSS class 227 | applied to them of the same, but dasherized name. The 228 | default styles apply a text-align: left to text 229 | cells and text-align: right to numeric and 230 | datetime cells. 231 |

See the relevant cell classes for 232 | details.

233 |
234 |
235 |
236 |
237 | 238 |
239 |
240 | 251 | 264 | 265 | 266 | 267 | --------------------------------------------------------------------------------