From 281b27fc5d0c60759eab71dafff110dc560040a7 Mon Sep 17 00:00:00 2001 From: Bruno Carriere Date: Mon, 18 Feb 2013 10:40:02 -0500 Subject: [PATCH 1/4] ellipsis not ellipses --- src/backgrid.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backgrid.css b/src/backgrid.css index c706a774..c86ba69e 100644 --- a/src/backgrid.css +++ b/src/backgrid.css @@ -35,7 +35,7 @@ overflow: hidden; line-height: 20px; text-align: left; - text-overflow: ellipses; + text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; border: 1px solid #DDD; From 4d6811a34300c60ab7c9f3cc9c9110db2ea15ced Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Wed, 20 Feb 2013 00:30:10 +0800 Subject: [PATCH 2/4] Version 0.1.4 --- CHANGELOG.md | 8 + ... data-50f15e8f0e127fae72c87af186ac8228.js} | 7 +- api/index.html | 2 +- api/output/Backgrid.Header.js | 2 +- api/output/Backgrid.HeaderRow.js | 17 +- api/output/Backgrid.Row.js | 17 +- lib/backgrid.css | 2 +- lib/backgrid.js | 156 +++++++----------- lib/backgrid.min.css | 2 +- lib/backgrid.min.js | 2 +- src/preamble.js | 2 +- 11 files changed, 100 insertions(+), 117 deletions(-) rename api/{data-3630b11dfabe7aa0e3c4a4817775cd6e.js => data-50f15e8f0e127fae72c87af186ac8228.js} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddf9755d..f9722ea7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +### 0.1.4 +- Fixed text-overflow: ellipsis in backgrid.css. + [Issue #57](https://github.com/wyuenho/backgrid/pull/57) +- Fixed bug where removing a hidden column removes the wrong column of + cells. [Issue #58](https://github.com/wyuenho/backgrid/issues/58) +- A hidden column is now hidden from the DOM instead of + detached. [Issue #60](https://github.com/wyuenho/backgrid/issues/60) + ### 0.1.3 - Fixed 2 security vulnerabilities in SelectCellEditor and TextareaCellEditor. diff --git a/api/data-3630b11dfabe7aa0e3c4a4817775cd6e.js b/api/data-50f15e8f0e127fae72c87af186ac8228.js similarity index 99% rename from api/data-3630b11dfabe7aa0e3c4a4817775cd6e.js rename to api/data-50f15e8f0e127fae72c87af186ac8228.js index 5c69b9b9..8453c59d 100644 --- a/api/data-3630b11dfabe7aa0e3c4a4817775cd6e.js +++ b/api/data-50f15e8f0e127fae72c87af186ac8228.js @@ -1875,11 +1875,12 @@ Docs = { "sort": 3 }, { - "name": "renderColumn", - "fullName": "Backgrid.Row.renderColumn", + "name": "makeCell", + "fullName": "Backgrid.Row.makeCell", "icon": "icon-method", - "url": "#!/api/Backgrid.Row-method-renderColumn", + "url": "#!/api/Backgrid.Row-method-makeCell", "meta": { + "protected": true }, "sort": 3 }, diff --git a/api/index.html b/api/index.html index 6795c6d2..09a43db4 100644 --- a/api/index.html +++ b/api/index.html @@ -12,7 +12,7 @@ - + diff --git a/api/output/Backgrid.Header.js b/api/output/Backgrid.Header.js index 957c0142..2c878d7a 100644 --- a/api/output/Backgrid.Header.js +++ b/api/output/Backgrid.Header.js @@ -77,7 +77,7 @@ Ext.data.JsonP.Backgrid_Header({ ] }, - "linenr": 269, + "linenr": 248, "files": [ { "filename": "header.js", diff --git a/api/output/Backgrid.HeaderRow.js b/api/output/Backgrid.HeaderRow.js index 39d0a8f1..d08b3836 100644 --- a/api/output/Backgrid.HeaderRow.js +++ b/api/output/Backgrid.HeaderRow.js @@ -49,30 +49,31 @@ Ext.data.JsonP.Backgrid_HeaderRow({ "id": "method-initialize" }, { - "name": "remove", + "name": "makeCell", "tagname": "method", "owner": "Backgrid.Row", "meta": { - "chainable": true + "protected": true }, - "id": "method-remove" + "id": "method-makeCell" }, { - "name": "render", + "name": "remove", "tagname": "method", "owner": "Backgrid.Row", "meta": { "chainable": true }, - "id": "method-render" + "id": "method-remove" }, { - "name": "renderColumn", + "name": "render", "tagname": "method", "owner": "Backgrid.Row", "meta": { + "chainable": true }, - "id": "method-renderColumn" + "id": "method-render" } ], "event": [ @@ -128,5 +129,5 @@ Ext.data.JsonP.Backgrid_HeaderRow({ "parentMixins": [ ], - "html": "

Hierarchy

Backbone.View
Backgrid.Row
Backgrid.HeaderRow

HeaderRow is a controller for a row of header cells.

\n
Defined By

Properties

...
\n

Defaults to: "tr"

Defined By

Methods

Backgrid.HeaderRow
( options )
Initializer. ...

Initializer.

\n

Parameters

  • options : Object
    \n
    • columns : Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>
    • headerCell : Backgrid.HeaderCell (optional)

      Customized default\nHeaderCell for all the columns. Supply a HeaderCell class or instance to a\nthe headerCell key in a column definition for column-specific header\nrendering.

      \n

Throws

  • TypeError

    If options.columns or options.collection is undefined.

    \n

Overrides: Backgrid.Row.initialize

Clean up this row and its cells. ...

Clean up this row and its cells.

\n

Returns

Renders a row of cells for this row's model. ...

Renders a row of cells for this row's model.

\n

Returns

( column, renderable )
Backbone event handler. ...

Backbone event handler. Insert a table cell to the right column in the row\nif renderable is true, detach otherwise.

\n

Parameters

" + "html": "

Hierarchy

Backbone.View
Backgrid.Row
Backgrid.HeaderRow

HeaderRow is a controller for a row of header cells.

\n
Defined By

Properties

...
\n

Defaults to: "tr"

Defined By

Methods

Backgrid.HeaderRow
( options )
Initializer. ...

Initializer.

\n

Parameters

  • options : Object
    \n
    • columns : Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>
    • headerCell : Backgrid.HeaderCell (optional)

      Customized default\nHeaderCell for all the columns. Supply a HeaderCell class or instance to a\nthe headerCell key in a column definition for column-specific header\nrendering.

      \n

Throws

  • TypeError

    If options.columns or options.collection is undefined.

    \n

Overrides: Backgrid.Row.initialize

( column, options ) : Backgrid.Cellprotected
Factory method for making a cell. ...

Factory method for making a cell. Used by initialize internally. Override\nthis to provide an appropriate cell instance for a custom Row subclass.

\n

Parameters

Returns

Clean up this row and its cells. ...

Clean up this row and its cells.

\n

Returns

Renders a row of cells for this row's model. ...

Renders a row of cells for this row's model.

\n

Returns

" }); \ No newline at end of file diff --git a/api/output/Backgrid.Row.js b/api/output/Backgrid.Row.js index 57996a32..49da5b28 100644 --- a/api/output/Backgrid.Row.js +++ b/api/output/Backgrid.Row.js @@ -49,30 +49,31 @@ Ext.data.JsonP.Backgrid_Row({ "id": "method-initialize" }, { - "name": "remove", + "name": "makeCell", "tagname": "method", "owner": "Backgrid.Row", "meta": { - "chainable": true + "protected": true }, - "id": "method-remove" + "id": "method-makeCell" }, { - "name": "render", + "name": "remove", "tagname": "method", "owner": "Backgrid.Row", "meta": { "chainable": true }, - "id": "method-render" + "id": "method-remove" }, { - "name": "renderColumn", + "name": "render", "tagname": "method", "owner": "Backgrid.Row", "meta": { + "chainable": true }, - "id": "method-renderColumn" + "id": "method-render" } ], "event": [ @@ -127,5 +128,5 @@ Ext.data.JsonP.Backgrid_Row({ "parentMixins": [ ], - "html": "

Hierarchy

Backbone.View
Backgrid.Row

Subclasses

Row is a simple container view that takes a model instance and a list of\ncolumn metadata describing how each of the model's attribute is to be\nrendered, and apply the appropriate cell to each attribute.

\n
Defined By

Properties

Backgrid.Row
: String
...
\n

Defaults to: "tr"

Defined By

Methods

Backgrid.Row
( options )
Initializes a row view instance. ...

Initializes a row view instance.

\n

Parameters

  • options : Object
    \n
    • columns : Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>

      Column metadata.

      \n
    • model : Backbone.Model

      The model instance to render.

      \n

Throws

  • TypeError

    If options.columns or options.model is undefined.

    \n
Backgrid.Row
( ) : Backgrid.Rowchainable
Clean up this row and its cells. ...

Clean up this row and its cells.

\n

Returns

Backgrid.Row
( ) : Backgrid.Rowchainable
Renders a row of cells for this row's model. ...

Renders a row of cells for this row's model.

\n

Returns

Backgrid.Row
( column, renderable )
Backbone event handler. ...

Backbone event handler. Insert a table cell to the right column in the row\nif renderable is true, detach otherwise.

\n

Parameters

" + "html": "

Hierarchy

Backbone.View
Backgrid.Row

Subclasses

Row is a simple container view that takes a model instance and a list of\ncolumn metadata describing how each of the model's attribute is to be\nrendered, and apply the appropriate cell to each attribute.

\n
Defined By

Properties

Backgrid.Row
: String
...
\n

Defaults to: "tr"

Defined By

Methods

Backgrid.Row
( options )
Initializes a row view instance. ...

Initializes a row view instance.

\n

Parameters

  • options : Object
    \n
    • columns : Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>

      Column metadata.

      \n
    • model : Backbone.Model

      The model instance to render.

      \n

Throws

  • TypeError

    If options.columns or options.model is undefined.

    \n
Backgrid.Row
( column, options ) : Backgrid.Cellprotected
Factory method for making a cell. ...

Factory method for making a cell. Used by initialize internally. Override\nthis to provide an appropriate cell instance for a custom Row subclass.

\n

Parameters

Returns

Backgrid.Row
( ) : Backgrid.Rowchainable
Clean up this row and its cells. ...

Clean up this row and its cells.

\n

Returns

Backgrid.Row
( ) : Backgrid.Rowchainable
Renders a row of cells for this row's model. ...

Renders a row of cells for this row's model.

\n

Returns

" }); \ No newline at end of file diff --git a/lib/backgrid.css b/lib/backgrid.css index c706a774..c86ba69e 100644 --- a/lib/backgrid.css +++ b/lib/backgrid.css @@ -35,7 +35,7 @@ overflow: hidden; line-height: 20px; text-align: left; - text-overflow: ellipses; + text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; border: 1px solid #DDD; diff --git a/lib/backgrid.js b/lib/backgrid.js index 60a0d740..2d4be52c 100644 --- a/lib/backgrid.js +++ b/lib/backgrid.js @@ -20,7 +20,7 @@ var window = root; var Backgrid = root.Backgrid = { - VERSION: "0.1.3", + VERSION: "0.1.4", Extension: {} }; @@ -1304,6 +1304,8 @@ var Row = Backgrid.Row = Backbone.View.extend({ /** @property */ tagName: "tr", + initOptionRequires: ["columns", "model"], + /** Initializes a row view instance. @@ -1315,74 +1317,68 @@ var Row = Backgrid.Row = Backbone.View.extend({ */ initialize: function (options) { - requireOptions(options, ["columns", "model"]); + requireOptions(options, this.initOptionRequires); var columns = this.columns = options.columns; if (!(columns instanceof Backbone.Collection)) { columns = this.columns = new Columns(columns); } - this.listenTo(columns, "change:renderable", this.renderColumn); var cells = this.cells = []; for (var i = 0; i < columns.length; i++) { - var column = columns.at(i); - cells.push(new (column.get("cell"))({ - column: column, - model: this.model - })); + cells.push(this.makeCell(columns.at(i), options)); } - this.listenTo(columns, "add", function (column, columns, options) { - options = _.defaults(options || {}, {render: true}); - var at = columns.indexOf(column); - var cell = new (column.get("cell"))({ - column: column, - model: this.model - }); - cells.splice(at, 0, cell); - this.renderColumn(column, column.get("renderable") && options.render); + this.listenTo(columns, "change:renderable", function (column, renderable) { + for (var i = 0; i < cells.length; i++) { + var cell = cells[i]; + if (cell.column.get("name") == column.get("name")) { + if (renderable) cell.$el.show(); else cell.$el.hide(); + } + } + }); + + this.listenTo(columns, "add", function (column, columns) { + var i = columns.indexOf(column); + var cell = this.makeCell(column, options); + cells.splice(i, 0, cell); + + if (!cell.column.get("renderable")) cell.$el.hide(); + + var $el = this.$el; + if (i === 0) { + $el.prepend(cell.render().$el); + } + else if (i === columns.length - 1) { + $el.append(cell.render().$el); + } + else { + $el.children().eq(i).before(cell.render().$el); + } }); - this.listenTo(columns, "remove", function (column) { - this.renderColumn(column, false); + + this.listenTo(columns, "remove", function (column, columns, opts) { + cells[opts.index].remove(); + cells.splice(opts.index, 1); }); }, /** - Backbone event handler. Insert a table cell to the right column in the row - if renderable is true, detach otherwise. + Factory method for making a cell. Used by #initialize internally. Override + this to provide an appropriate cell instance for a custom Row subclass. + + @protected @param {Backgrid.Column} column - @param {boolean} renderable + @param {Object} options The options passed to #initialize. + + @return {Backgrid.Cell} */ - renderColumn: function (column, renderable) { - var cells = this.cells; - var columns = this.columns; - var spliceIndex = -1; - for (var i = 0; i < cells.length; i++) { - var cell = cells[i]; - if (cell.column.get("name") == column.get("name")) { - spliceIndex = i; - break; - } - } - if (spliceIndex != -1) { - var $el = this.$el; - if (renderable) { - var cell = cells[spliceIndex]; - if (spliceIndex === 0) { - $el.prepend(cell.render().$el); - } - else if (spliceIndex === columns.length - 1) { - $el.append(cell.render().$el); - } - else { - $el.children().eq(spliceIndex).before(cell.render().$el); - } - } - else { - $el.children().eq(spliceIndex).detach(); - } - } + makeCell: function (column) { + return new (column.get("cell"))({ + column: column, + model: this.model + }); }, /** @@ -1395,9 +1391,8 @@ var Row = Backgrid.Row = Backbone.View.extend({ for (var i = 0; i < this.cells.length; i++) { var cell = this.cells[i]; - if (cell.column.get("renderable")) { - fragment.appendChild(cell.render().el); - } + fragment.appendChild(cell.render().el); + if (!cell.column.get("renderable")) cell.$el.hide(); } this.el.appendChild(fragment); @@ -1637,6 +1632,8 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({ */ var HeaderRow = Backgrid.HeaderRow = Backgrid.Row.extend({ + initOptionRequires: ["columns", "collection"], + /** Initializer. @@ -1649,40 +1646,17 @@ var HeaderRow = Backgrid.HeaderRow = Backgrid.Row.extend({ @throws {TypeError} If options.columns or options.collection is undefined. */ - initialize: function (options) { - - requireOptions(options, ["columns", "collection"]); - - var columns = this.columns = options.columns; - if (!(columns instanceof Backbone.Collection)) { - columns = this.columns = new Columns(columns); - } - this.listenTo(columns, "change:renderable", this.renderColumn); - - var cells = this.cells = []; - for (var i = 0; i < columns.length; i++) { - var column = columns.at(i); - var headerCell = column.get("headerCell") || options.headerCell || HeaderCell; - cells.push(new headerCell({ - column: column, - collection: this.collection - })); - } + initialize: function () { + Backgrid.Row.prototype.initialize.apply(this, arguments); + }, - this.listenTo(columns, "add", function (column, columns, opts) { - opts = _.defaults(opts || {}, {render: true}); - var at = columns.indexOf(column); - var headerCell = column.get("headerCell") || options.headerCell || HeaderCell; - headerCell = new headerCell({ - column: column, - collection: this.collection - }); - cells.splice(at, 0, headerCell); - this.renderColumn(column, column.get("renderable") && opts.render); - }); - this.listenTo(columns, "remove", function (column) { - this.renderColumn(column, false); + makeCell: function (column, options) { + var headerCell = column.get("headerCell") || options.headerCell || HeaderCell; + headerCell = new headerCell({ + column: column, + collection: this.collection }); + return headerCell; } }); @@ -2134,10 +2108,9 @@ var Grid = Backgrid.Grid = Backbone.View.extend({ @chainable */ insertColumn: function (column, options) { - var self = this; options = options || {render: true}; - self.columns.add(column, options); - return self; + this.columns.add(column, options); + return this; }, /** @@ -2150,9 +2123,8 @@ var Grid = Backgrid.Grid = Backbone.View.extend({ @chainable */ removeColumn: function (column, options) { - var self = this; - self.columns.remove(column, options); - return self; + this.columns.remove(column, options); + return this; }, /** diff --git a/lib/backgrid.min.css b/lib/backgrid.min.css index 01ef2c5c..144920e3 100644 --- a/lib/backgrid.min.css +++ b/lib/backgrid.min.css @@ -5,4 +5,4 @@ Copyright (c) 2013 Jimmy Yuen Ho Wong Licensed under the MIT @license. */ -.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border:1px solid #DDD;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipses;white-space:nowrap;vertical-align:middle;border:1px solid #DDD}.backgrid th{font-weight:bold;cursor:pointer}.backgrid th a{white-space:nowrap}.backgrid thead th{vertical-align:bottom}.backgrid tbody tr:nth-child(odd) td,.backgrid tbody tr:nth-child(odd) th{background-color:#f9f9f9}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor.error,.backgrid tbody tr:nth-child(odd) td.editor.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}.backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} +.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border:1px solid #DDD;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border:1px solid #DDD}.backgrid th{font-weight:bold;cursor:pointer}.backgrid th a{white-space:nowrap}.backgrid thead th{vertical-align:bottom}.backgrid tbody tr:nth-child(odd) td,.backgrid tbody tr:nth-child(odd) th{background-color:#f9f9f9}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor.error,.backgrid tbody tr:nth-child(odd) td.editor.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}.backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} diff --git a/lib/backgrid.min.js b/lib/backgrid.min.js index ee406db5..6d60cb9e 100644 --- a/lib/backgrid.min.js +++ b/lib/backgrid.min.js @@ -5,4 +5,4 @@ Copyright (c) 2013 Jimmy Yuen Ho Wong Licensed under the MIT @license. */ -(function(e,t,i,r){"use strict";function n(e){return String.fromCharCode(e.charCodeAt(0)-32)+e.slice(1)}function o(e,t,i){var r=t-(e+"").length;r=0>r?0:r;for(var n="",o=0;r>o;o++)n+=i;return n+e}function s(e,t){for(var r=0;t.length>r;r++){var n=t[r];if(i.isUndefined(e[n]))throw new TypeError("'"+n+"' is required")}}function l(e,t){if(i.isString(e)){var r=n(e)+t,o=c[r]||c.Extension[r];if(i.isUndefined(o))throw new ReferenceError("Class '"+r+"' not found");return o}return e}var a=e,c=e.Backgrid={VERSION:"0.1.3",Extension:{}},h=" \n \f\r   ᠎              \u2028\u2029";if(!String.prototype.trim||h.trim()){h="["+h+"]";var d=RegExp("^"+h+h+"*"),u=RegExp(h+h+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return(this+"").replace(d,"").replace(u,"")}}var m=c.CellFormatter=function(){};i.extend(m.prototype,{fromRaw:function(e){return e},toRaw:function(e){return e}});var f=c.NumberFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),0>this.decimals||this.decimals>20)throw new RangeError("decimals must be between 0 and 20")};f.prototype=new m,i.extend(f.prototype,{defaults:{decimals:2,decimalSeparator:".",orderSeparator:","},HUMANIZED_NUM_RE:/(\d)(?=(?:\d{3})+$)/g,fromRaw:function(e){if(isNaN(e)||null===e)return"";e=e.toFixed(~~this.decimals);var t=e.split("."),i=t[0],r=t[1]?(this.decimalSeparator||".")+t[1]:"";return i.replace(this.HUMANIZED_NUM_RE,"$1"+this.orderSeparator)+r},toRaw:function(e){for(var t="",r=e.trim().split(this.orderSeparator),n=0;r.length>n;n++)t+=r[n];var o=t.split(this.decimalSeparator);t="";for(var n=0;o.length>n;n++)t=t+o[n]+".";"."===t[t.length-1]&&(t=t.slice(0,t.length-1));var s=1*(1*t).toFixed(~~this.decimals);return i.isNumber(s)&&!i.isNaN(s)?s:void 0}});var p=c.DatetimeFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),!this.includeDate&&!this.includeTime)throw Error("Either includeDate or includeTime must be true")};p.prototype=new m,i.extend(p.prototype,{defaults:{includeDate:!0,includeTime:!0,includeMilli:!1},DATE_RE:/^([+\-]?\d{4})-(\d{2})-(\d{2})$/,TIME_RE:/^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/,ISO_SPLITTER_RE:/T|Z| +/,_convert:function(e,t){if(i.isNull(e)||i.isUndefined(e))return e;e=e.trim();var r=e.split(this.ISO_SPLITTER_RE)||[],n=this.DATE_RE.test(r[0])?r[0]:"",s=n&&r[1]?r[1]:this.TIME_RE.test(r[0])?r[0]:"",l=this.DATE_RE.exec(n)||[],a=this.TIME_RE.exec(s)||[];if(t){if(this.includeDate&&i.isUndefined(l[0]))return;if(this.includeTime&&i.isUndefined(a[0]))return;if(!this.includeDate&&n)return;if(!this.includeTime&&s)return}var c=new Date(Date.UTC(1*l[1]||0,1*l[2]-1||0,1*l[3]||0,1*a[1]||null,1*a[2]||null,1*a[3]||null,1*a[5]||null)),h="";return this.includeDate&&(h=o(c.getUTCFullYear(),4,0)+"-"+o(c.getUTCMonth()+1,2,0)+"-"+o(c.getUTCDate(),2,0)),this.includeTime&&(h=h+(this.includeDate?"T":"")+o(c.getUTCHours(),2,0)+":"+o(c.getUTCMinutes(),2,0)+":"+o(c.getUTCSeconds(),2,0),this.includeMilli&&(h=h+"."+o(c.getUTCMilliseconds(),3,0))),this.includeDate&&this.includeTime&&(h+="Z"),h},fromRaw:function(e){return this._convert(e)},toRaw:function(e){return this._convert(e,!0)}});var v=c.CellEditor=r.View.extend({initialize:function(e){s(e,["formatter","column","model"]),this.parent=e.parent,this.formatter=e.formatter,this.column=e.column,this.column instanceof E||(this.column=new E(this.column)),this.parent&&i.isFunction(this.parent.on)&&this.listenTo(this.parent,"editing",this.postRender)},postRender:function(){return this.$el.focus(),this}}),g=c.InputCellEditor=v.extend({tagName:"input",attributes:{type:"text"},events:{blur:"saveOrCancel",keydown:"saveOrCancel"},initialize:function(e){v.prototype.initialize.apply(this,arguments),e.placeholder&&this.$el.attr("placeholder",e.placeholder),this.listenTo(this,"done",this.remove)},render:function(){return this.$el.val(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this},saveOrCancel:function(e){if("keydown"===e.type)if(13===e.keyCode||9===e.keyCode){e.preventDefault();var t=this.formatter.toRaw(this.$el.val());i.isUndefined(t)||!this.model.set(this.column.get("name"),t,{validate:!0})?this.trigger("error"):this.trigger("done")}else 27===e.keyCode&&(e.stopPropagation(),this.trigger("done"));else if("blur"===e.type)if(this.formatter.fromRaw(this.model.get(this.column.get("name")))===this.$el.val())this.trigger("done");else var r=this,n=a.setTimeout(function(){r.$el.focus(),a.clearTimeout(n)},1)},postRender:function(){if("right"===this.$el.css("text-align")){var e=this.$el.val();this.$el.focus().val(null).val(e)}else this.$el.focus();return this}}),w=c.Cell=r.View.extend({tagName:"td",formatter:new m,editor:g,events:{click:"enterEditMode"},initialize:function(e){s(e,["model","column"]),this.column=e.column,this.column instanceof E||(this.column=new E(this.column)),this.formatter=l(this.formatter,"Formatter"),this.editor=l(this.editor,"CellEditor"),this.listenTo(this.model,"change:"+this.column.get("name"),function(){this.$el.hasClass("editor")||this.render()})},render:function(){return this.$el.empty().text(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this},enterEditMode:function(){this.column.get("editable")&&(this.currentEditor=new this.editor({parent:this,column:this.column,model:this.model,formatter:this.formatter}),this.trigger("edit",this,this.currentEditor),this.listenTo(this.currentEditor,"done",this.exitEditMode),this.listenTo(this.currentEditor,"error",this.renderError),this.$el.empty(),this.undelegateEvents(),this.$el.append(this.currentEditor.$el),this.currentEditor.render(),this.$el.addClass("editor"),this.trigger("editing",this,this.currentEditor))},renderError:function(){this.$el.addClass("error")},exitEditMode:function(){this.$el.removeClass("error"),this.currentEditor.off(null,null,this),this.currentEditor.remove(),delete this.currentEditor,this.$el.removeClass("editor"),this.render(),this.delegateEvents()},remove:function(){return this.currentEditor&&(this.currentEditor.remove.apply(this,arguments),delete this.currentEditor),r.View.prototype.remove.apply(this,arguments)}});c.StringCell=w.extend({className:"string-cell"}),c.UriCell=w.extend({className:"uri-cell",formatter:{fromRaw:function(e){return e},toRaw:function(e){var t=encodeURI(e);return"undefined"===t?void 0:t}},render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:e,title:e,target:"_blank"}).text(e)),this}}),c.EmailCell=w.extend({className:"email-cell",formatter:{fromRaw:function(e){return e},toRaw:function(e){var t=e.split("@");return 2===t.length&&i.all(t)?e:void 0}},render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:"mailto:"+e,title:e}).text(e)),this}});var y=c.NumberCell=w.extend({className:"number-cell",decimals:f.prototype.defaults.decimals,decimalSeparator:f.prototype.defaults.decimalSeparator,orderSeparator:f.prototype.defaults.orderSeparator,formatter:f,initialize:function(){w.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({decimals:this.decimals,decimalSeparator:this.decimalSeparator,orderSeparator:this.orderSeparator})}});c.IntegerCell=y.extend({className:"integer-cell",decimals:0});var C=c.DatetimeCell=w.extend({className:"datetime-cell",includeDate:p.prototype.defaults.includeDate,includeTime:p.prototype.defaults.includeTime,includeMilli:p.prototype.defaults.includeMilli,formatter:p,initialize:function(){w.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({includeDate:this.includeDate,includeTime:this.includeTime,includeMilli:this.includeMilli});var e=this.includeDate?"YYYY-MM-DD":"";e+=this.includeDate&&this.includeTime?"T":"",e+=this.includeTime?"HH:mm:ss":"",e+=this.includeTime&&this.includeMilli?".SSS":"",this.editor=this.editor.extend({attributes:i.extend({},this.editor.prototype.attributes,this.editor.attributes,{placeholder:e})})}});c.DateCell=C.extend({className:"date-cell",includeTime:!1}),c.TimeCell=C.extend({className:"time-cell",includeDate:!1}),c.BooleanCell=w.extend({className:"boolean-cell",editor:i.template(" />'"),events:{click:"enterEditMode","blur input[type=checkbox]":"exitEditMode","change input[type=checkbox]":"save"},render:function(){return this.$el.empty(),this.currentEditor=t(this.editor({checked:this.formatter.fromRaw(this.model.get(this.column.get("name")))})),this.$el.append(this.currentEditor),this},enterEditMode:function(){this.$el.addClass("editor"),this.currentEditor.focus()},exitEditMode:function(){this.$el.removeClass("editor")},save:function(){var e=this.formatter.toRaw(this.currentEditor.prop("checked"));this.model.set(this.column.get("name"),e)}});var b=c.SelectCellEditor=v.extend({tagName:"select",events:{change:"save",blur:"save"},template:i.template(''),setOptionValues:function(e){this.optionValues=e},_renderOptions:function(e,t){for(var i="",r=0;e.length>r;r++)i+=this.template({text:e[r][0],value:e[r][1],selected:t==e[r][1]});return i},render:function(){this.$el.empty();var e=i.result(this,"optionValues"),r=this.model.get(this.column.get("name"));if(!i.isArray(e))throw TypeError("optionValues must be an array");for(var n=null,o=null,n=null,s=null,l=null,a=0;e.length>a;a++){var n=e[a];if(i.isArray(n))o=n[0],n=n[1],this.$el.append(this.template({text:o,value:n,selected:n==r}));else{if(!i.isObject(n))throw TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");s=n.name,l=t("",{label:s}),l.append(this._renderOptions(n.values,r)),this.$el.append(l)}}return this},save:function(){this.model.set(this.column.get("name"),this.formatter.toRaw(this.$el.val())),this.trigger("done")}});c.SelectCell=w.extend({className:"select-cell",editor:b,optionValues:void 0,initialize:function(){w.prototype.initialize.apply(this,arguments),s(this,["optionValues"]),this.optionValues=i.result(this,"optionValues"),this.listenTo(this,"edit",this.setOptionValues)},setOptionValues:function(e,t){t.setOptionValues(this.optionValues)},render:function(){this.$el.empty();var e=this.optionValues,t=this.formatter.fromRaw(this.model.get(this.column.get("name")));try{if(!i.isArray(e)||i.isEmpty(e))throw new TypeError;for(var r=0;e.length>r;r++){var n=e[r];if(i.isArray(n)){var o=n[0],n=n[1];if(n==t){this.$el.append(o);break}}else{if(!i.isObject(n))throw new TypeError;for(var s=n.values,l=0;s.length>l;l++){var a=s[l];if(a[1]==t){this.$el.append(a[0]);break}}}}}catch(c){if(c instanceof TypeError)throw TypeError("'optionValues' must be of type {Array.|Array.<{name: string, values: Array.}>}");throw c}return this}});var E=c.Column=r.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,cell:void 0,headerCell:void 0},initialize:function(e){s(e,["cell","name"]),this.has("label")||this.set({label:this.get("name")},{silent:!0});var t=l(this.get("cell"),"Cell");this.set({cell:t},{silent:!0})}}),T=c.Columns=r.Collection.extend({model:E}),$=c.Row=r.View.extend({tagName:"tr",initialize:function(e){s(e,["columns","model"]);var t=this.columns=e.columns;t instanceof r.Collection||(t=this.columns=new T(t)),this.listenTo(t,"change:renderable",this.renderColumn);for(var n=this.cells=[],o=0;t.length>o;o++){var l=t.at(o);n.push(new(l.get("cell"))({column:l,model:this.model}))}this.listenTo(t,"add",function(e,t,r){r=i.defaults(r||{},{render:!0});var o=t.indexOf(e),s=new(e.get("cell"))({column:e,model:this.model});n.splice(o,0,s),this.renderColumn(e,e.get("renderable")&&r.render)}),this.listenTo(t,"remove",function(e){this.renderColumn(e,!1)})},renderColumn:function(e,t){for(var i=this.cells,r=this.columns,n=-1,o=0;i.length>o;o++){var s=i[o];if(s.column.get("name")==e.get("name")){n=o;break}}if(-1!=n){var l=this.$el;if(t){var s=i[n];0===n?l.prepend(s.render().$el):n===r.length-1?l.append(s.render().$el):l.children().eq(n).before(s.render().$el)}else l.children().eq(n).detach()}},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.cells.length>t;t++){var i=this.cells[t];i.column.get("renderable")&&e.appendChild(i.render().el)}return this.el.appendChild(e),this},remove:function(){for(var e=0;this.cells.length>e;e++){var t=this.cells[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}}),x=c.HeaderCell=r.View.extend({tagName:"th",events:{"click a":"onClick"},_direction:null,initialize:function(e){s(e,["column","collection"]),this.column=e.column,this.column instanceof E||(this.column=new E(this.column)),this.listenTo(r,"backgrid:sort",this._resetCellDirection)},direction:function(e){return arguments.length&&(this._direction&&this.$el.removeClass(this._direction),e&&this.$el.addClass(e),this._direction=e),this._direction},_resetCellDirection:function(e,t,i,r){r==this.collection&&(e!==this.column.get("name")?this.direction(null):this.direction(t))},onClick:function(e){e.preventDefault();var t=this.column.get("name");this.column.get("sortable")&&("ascending"===this.direction()?this.sort(t,"descending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:r>n?-1:1}):"descending"===this.direction()?this.sort(t,null):this.sort(t,"ascending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:n>r?-1:1}))},sort:function(e,t,i){i=i||this._cidComparator;var n=this.collection;if(r.PageableCollection&&n instanceof r.PageableCollection){var o;o="ascending"===t?-1:"descending"===t?1:null,n.setSorting(o?e:null,o),"client"==n.mode?(n.fullCollection.comparator||(n.fullCollection.comparator=i),n.fullCollection.sort()):n.fetch()}else n.comparator=i,n.sort();r.trigger("backgrid:sort",e,t,i,this.collection)},_cidComparator:function(e,t){var r=e.cid,n=t.cid;if(!i.isUndefined(r)&&!i.isUndefined(n)){if(r=1*r.slice(1),n=1*n.slice(1),n>r)return-1;if(r>n)return 1}return 0},render:function(){this.$el.empty();var e=t("").text(this.column.get("label")).append("");return this.$el.append(e),this}});c.HeaderRow=c.Row.extend({initialize:function(e){s(e,["columns","collection"]);var t=this.columns=e.columns;t instanceof r.Collection||(t=this.columns=new T(t)),this.listenTo(t,"change:renderable",this.renderColumn);for(var n=this.cells=[],o=0;t.length>o;o++){var l=t.at(o),a=l.get("headerCell")||e.headerCell||x;n.push(new a({column:l,collection:this.collection}))}this.listenTo(t,"add",function(t,r,o){o=i.defaults(o||{},{render:!0});var s=r.indexOf(t),l=t.get("headerCell")||e.headerCell||x;l=new l({column:t,collection:this.collection}),n.splice(s,0,l),this.renderColumn(t,t.get("renderable")&&o.render)}),this.listenTo(t,"remove",function(e){this.renderColumn(e,!1)})}});var R=c.Header=r.View.extend({tagName:"thead",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new T(this.columns)),this.row=new c.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this},remove:function(){return this.row.remove.apply(this.row,arguments),r.View.prototype.remove.apply(this,arguments)}}),D=c.Body=r.View.extend({tagName:"tbody",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new T(this.columns)),this.row=e.row||$,this.rows=this.collection.map(function(e){var t=new this.row({columns:this.columns,model:e});return t},this);var t=this.collection;this.listenTo(t,"add",this.insertRow),this.listenTo(t,"remove",this.removeRow),this.listenTo(t,"sort",this.refresh),this.listenTo(t,"reset",this.refresh)},insertRow:function(e,t,n){if(!(t instanceof r.Collection||n))return this.collection.add(e,n=t),void 0;n=i.extend({render:!0},n||{});var o=new this.row({columns:this.columns,model:e}),s=t.indexOf(e);this.rows.splice(s,0,o);var l=this.$el,a=l.children(),c=o.render().$el;n.render&&(s>=a.length?l.append(c):a.eq(s).before(c))},removeRow:function(e,t,r){return r?((i.isUndefined(r.render)||r.render)&&this.rows[r.index].remove(),this.rows.splice(r.index,1),void 0):(this.collection.remove(e,r=t),void 0)},refresh:function(){var e=this;return i.each(e.rows,function(e){e.remove()}),e.rows=e.collection.map(function(t){var i=new e.row({columns:e.columns,model:t});return i}),e.render(),r.trigger("backgrid:refresh"),e},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.rows.length>t;t++){var i=this.rows[t];e.appendChild(i.render().el)}return this.el.appendChild(e),this},remove:function(){for(var e=0;this.rows.length>e;e++){var t=this.rows[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}});c.Footer=r.View.extend({tagName:"tfoot",initialize:function(e){s(e,["columns","collection"]),this.parent=e.parent,this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new c.Columns(this.columns))}}),c.Grid=r.View.extend({tagName:"table",className:"backgrid",header:R,body:D,footer:null,initialize:function(e){s(e,["columns","collection"]),e.columns instanceof r.Collection||(e.columns=new T(e.columns)),this.columns=e.columns,this.header=e.header||this.header,this.header=new this.header(e),this.body=e.body||this.body,this.body=new this.body(e),this.footer=e.footer||this.footer,this.footer&&(this.footer=new this.footer(e)),this.listenTo(this.columns,"reset",function(){this.header=new(this.header.remove().constructor)(e),this.body=new(this.body.remove().constructor)(e),this.footer&&(this.footer=new(this.footer.remove().constructor)(e)),this.render()})},insertRow:function(e,t,i){return this.body.insertRow(e,t,i)},removeRow:function(e,t,i){return this.body.removeRow(e,t,i)},insertColumn:function(e,t){var i=this;return t=t||{render:!0},i.columns.add(e,t),i},removeColumn:function(e,t){var i=this;return i.columns.remove(e,t),i},render:function(){return this.$el.empty(),this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.trigger("rendered"),this},remove:function(){return this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),r.View.prototype.remove.apply(this,arguments)}})})(this,$,_,Backbone); \ No newline at end of file +(function(e,t,i,r){"use strict";function n(e){return String.fromCharCode(e.charCodeAt(0)-32)+e.slice(1)}function o(e,t,i){var r=t-(e+"").length;r=0>r?0:r;for(var n="",o=0;r>o;o++)n+=i;return n+e}function s(e,t){for(var r=0;t.length>r;r++){var n=t[r];if(i.isUndefined(e[n]))throw new TypeError("'"+n+"' is required")}}function l(e,t){if(i.isString(e)){var r=n(e)+t,o=c[r]||c.Extension[r];if(i.isUndefined(o))throw new ReferenceError("Class '"+r+"' not found");return o}return e}var a=e,c=e.Backgrid={VERSION:"0.1.4",Extension:{}},h=" \n \f\r   ᠎              \u2028\u2029";if(!String.prototype.trim||h.trim()){h="["+h+"]";var d=RegExp("^"+h+h+"*"),u=RegExp(h+h+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return(this+"").replace(d,"").replace(u,"")}}var m=c.CellFormatter=function(){};i.extend(m.prototype,{fromRaw:function(e){return e},toRaw:function(e){return e}});var f=c.NumberFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),0>this.decimals||this.decimals>20)throw new RangeError("decimals must be between 0 and 20")};f.prototype=new m,i.extend(f.prototype,{defaults:{decimals:2,decimalSeparator:".",orderSeparator:","},HUMANIZED_NUM_RE:/(\d)(?=(?:\d{3})+$)/g,fromRaw:function(e){if(isNaN(e)||null===e)return"";e=e.toFixed(~~this.decimals);var t=e.split("."),i=t[0],r=t[1]?(this.decimalSeparator||".")+t[1]:"";return i.replace(this.HUMANIZED_NUM_RE,"$1"+this.orderSeparator)+r},toRaw:function(e){for(var t="",r=e.trim().split(this.orderSeparator),n=0;r.length>n;n++)t+=r[n];var o=t.split(this.decimalSeparator);t="";for(var n=0;o.length>n;n++)t=t+o[n]+".";"."===t[t.length-1]&&(t=t.slice(0,t.length-1));var s=1*(1*t).toFixed(~~this.decimals);return i.isNumber(s)&&!i.isNaN(s)?s:void 0}});var p=c.DatetimeFormatter=function(e){if(e=e?i.clone(e):{},i.extend(this,this.defaults,e),!this.includeDate&&!this.includeTime)throw Error("Either includeDate or includeTime must be true")};p.prototype=new m,i.extend(p.prototype,{defaults:{includeDate:!0,includeTime:!0,includeMilli:!1},DATE_RE:/^([+\-]?\d{4})-(\d{2})-(\d{2})$/,TIME_RE:/^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/,ISO_SPLITTER_RE:/T|Z| +/,_convert:function(e,t){if(i.isNull(e)||i.isUndefined(e))return e;e=e.trim();var r=e.split(this.ISO_SPLITTER_RE)||[],n=this.DATE_RE.test(r[0])?r[0]:"",s=n&&r[1]?r[1]:this.TIME_RE.test(r[0])?r[0]:"",l=this.DATE_RE.exec(n)||[],a=this.TIME_RE.exec(s)||[];if(t){if(this.includeDate&&i.isUndefined(l[0]))return;if(this.includeTime&&i.isUndefined(a[0]))return;if(!this.includeDate&&n)return;if(!this.includeTime&&s)return}var c=new Date(Date.UTC(1*l[1]||0,1*l[2]-1||0,1*l[3]||0,1*a[1]||null,1*a[2]||null,1*a[3]||null,1*a[5]||null)),h="";return this.includeDate&&(h=o(c.getUTCFullYear(),4,0)+"-"+o(c.getUTCMonth()+1,2,0)+"-"+o(c.getUTCDate(),2,0)),this.includeTime&&(h=h+(this.includeDate?"T":"")+o(c.getUTCHours(),2,0)+":"+o(c.getUTCMinutes(),2,0)+":"+o(c.getUTCSeconds(),2,0),this.includeMilli&&(h=h+"."+o(c.getUTCMilliseconds(),3,0))),this.includeDate&&this.includeTime&&(h+="Z"),h},fromRaw:function(e){return this._convert(e)},toRaw:function(e){return this._convert(e,!0)}});var v=c.CellEditor=r.View.extend({initialize:function(e){s(e,["formatter","column","model"]),this.parent=e.parent,this.formatter=e.formatter,this.column=e.column,this.column instanceof b||(this.column=new b(this.column)),this.parent&&i.isFunction(this.parent.on)&&this.listenTo(this.parent,"editing",this.postRender)},postRender:function(){return this.$el.focus(),this}}),g=c.InputCellEditor=v.extend({tagName:"input",attributes:{type:"text"},events:{blur:"saveOrCancel",keydown:"saveOrCancel"},initialize:function(e){v.prototype.initialize.apply(this,arguments),e.placeholder&&this.$el.attr("placeholder",e.placeholder),this.listenTo(this,"done",this.remove)},render:function(){return this.$el.val(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this},saveOrCancel:function(e){if("keydown"===e.type)if(13===e.keyCode||9===e.keyCode){e.preventDefault();var t=this.formatter.toRaw(this.$el.val());i.isUndefined(t)||!this.model.set(this.column.get("name"),t,{validate:!0})?this.trigger("error"):this.trigger("done")}else 27===e.keyCode&&(e.stopPropagation(),this.trigger("done"));else if("blur"===e.type)if(this.formatter.fromRaw(this.model.get(this.column.get("name")))===this.$el.val())this.trigger("done");else var r=this,n=a.setTimeout(function(){r.$el.focus(),a.clearTimeout(n)},1)},postRender:function(){if("right"===this.$el.css("text-align")){var e=this.$el.val();this.$el.focus().val(null).val(e)}else this.$el.focus();return this}}),w=c.Cell=r.View.extend({tagName:"td",formatter:new m,editor:g,events:{click:"enterEditMode"},initialize:function(e){s(e,["model","column"]),this.column=e.column,this.column instanceof b||(this.column=new b(this.column)),this.formatter=l(this.formatter,"Formatter"),this.editor=l(this.editor,"CellEditor"),this.listenTo(this.model,"change:"+this.column.get("name"),function(){this.$el.hasClass("editor")||this.render()})},render:function(){return this.$el.empty().text(this.formatter.fromRaw(this.model.get(this.column.get("name")))),this},enterEditMode:function(){this.column.get("editable")&&(this.currentEditor=new this.editor({parent:this,column:this.column,model:this.model,formatter:this.formatter}),this.trigger("edit",this,this.currentEditor),this.listenTo(this.currentEditor,"done",this.exitEditMode),this.listenTo(this.currentEditor,"error",this.renderError),this.$el.empty(),this.undelegateEvents(),this.$el.append(this.currentEditor.$el),this.currentEditor.render(),this.$el.addClass("editor"),this.trigger("editing",this,this.currentEditor))},renderError:function(){this.$el.addClass("error")},exitEditMode:function(){this.$el.removeClass("error"),this.currentEditor.off(null,null,this),this.currentEditor.remove(),delete this.currentEditor,this.$el.removeClass("editor"),this.render(),this.delegateEvents()},remove:function(){return this.currentEditor&&(this.currentEditor.remove.apply(this,arguments),delete this.currentEditor),r.View.prototype.remove.apply(this,arguments)}});c.StringCell=w.extend({className:"string-cell"}),c.UriCell=w.extend({className:"uri-cell",formatter:{fromRaw:function(e){return e},toRaw:function(e){var t=encodeURI(e);return"undefined"===t?void 0:t}},render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:e,title:e,target:"_blank"}).text(e)),this}}),c.EmailCell=w.extend({className:"email-cell",formatter:{fromRaw:function(e){return e},toRaw:function(e){var t=e.split("@");return 2===t.length&&i.all(t)?e:void 0}},render:function(){this.$el.empty();var e=this.formatter.fromRaw(this.model.get(this.column.get("name")));return this.$el.append(t("",{href:"mailto:"+e,title:e}).text(e)),this}});var y=c.NumberCell=w.extend({className:"number-cell",decimals:f.prototype.defaults.decimals,decimalSeparator:f.prototype.defaults.decimalSeparator,orderSeparator:f.prototype.defaults.orderSeparator,formatter:f,initialize:function(){w.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({decimals:this.decimals,decimalSeparator:this.decimalSeparator,orderSeparator:this.orderSeparator})}});c.IntegerCell=y.extend({className:"integer-cell",decimals:0});var C=c.DatetimeCell=w.extend({className:"datetime-cell",includeDate:p.prototype.defaults.includeDate,includeTime:p.prototype.defaults.includeTime,includeMilli:p.prototype.defaults.includeMilli,formatter:p,initialize:function(){w.prototype.initialize.apply(this,arguments),this.formatter=new this.formatter({includeDate:this.includeDate,includeTime:this.includeTime,includeMilli:this.includeMilli});var e=this.includeDate?"YYYY-MM-DD":"";e+=this.includeDate&&this.includeTime?"T":"",e+=this.includeTime?"HH:mm:ss":"",e+=this.includeTime&&this.includeMilli?".SSS":"",this.editor=this.editor.extend({attributes:i.extend({},this.editor.prototype.attributes,this.editor.attributes,{placeholder:e})})}});c.DateCell=C.extend({className:"date-cell",includeTime:!1}),c.TimeCell=C.extend({className:"time-cell",includeDate:!1}),c.BooleanCell=w.extend({className:"boolean-cell",editor:i.template(" />'"),events:{click:"enterEditMode","blur input[type=checkbox]":"exitEditMode","change input[type=checkbox]":"save"},render:function(){return this.$el.empty(),this.currentEditor=t(this.editor({checked:this.formatter.fromRaw(this.model.get(this.column.get("name")))})),this.$el.append(this.currentEditor),this},enterEditMode:function(){this.$el.addClass("editor"),this.currentEditor.focus()},exitEditMode:function(){this.$el.removeClass("editor")},save:function(){var e=this.formatter.toRaw(this.currentEditor.prop("checked"));this.model.set(this.column.get("name"),e)}});var E=c.SelectCellEditor=v.extend({tagName:"select",events:{change:"save",blur:"save"},template:i.template(''),setOptionValues:function(e){this.optionValues=e},_renderOptions:function(e,t){for(var i="",r=0;e.length>r;r++)i+=this.template({text:e[r][0],value:e[r][1],selected:t==e[r][1]});return i},render:function(){this.$el.empty();var e=i.result(this,"optionValues"),r=this.model.get(this.column.get("name"));if(!i.isArray(e))throw TypeError("optionValues must be an array");for(var n=null,o=null,n=null,s=null,l=null,a=0;e.length>a;a++){var n=e[a];if(i.isArray(n))o=n[0],n=n[1],this.$el.append(this.template({text:o,value:n,selected:n==r}));else{if(!i.isObject(n))throw TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");s=n.name,l=t("",{label:s}),l.append(this._renderOptions(n.values,r)),this.$el.append(l)}}return this},save:function(){this.model.set(this.column.get("name"),this.formatter.toRaw(this.$el.val())),this.trigger("done")}});c.SelectCell=w.extend({className:"select-cell",editor:E,optionValues:void 0,initialize:function(){w.prototype.initialize.apply(this,arguments),s(this,["optionValues"]),this.optionValues=i.result(this,"optionValues"),this.listenTo(this,"edit",this.setOptionValues)},setOptionValues:function(e,t){t.setOptionValues(this.optionValues)},render:function(){this.$el.empty();var e=this.optionValues,t=this.formatter.fromRaw(this.model.get(this.column.get("name")));try{if(!i.isArray(e)||i.isEmpty(e))throw new TypeError;for(var r=0;e.length>r;r++){var n=e[r];if(i.isArray(n)){var o=n[0],n=n[1];if(n==t){this.$el.append(o);break}}else{if(!i.isObject(n))throw new TypeError;for(var s=n.values,l=0;s.length>l;l++){var a=s[l];if(a[1]==t){this.$el.append(a[0]);break}}}}}catch(c){if(c instanceof TypeError)throw TypeError("'optionValues' must be of type {Array.|Array.<{name: string, values: Array.}>}");throw c}return this}});var b=c.Column=r.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,cell:void 0,headerCell:void 0},initialize:function(e){s(e,["cell","name"]),this.has("label")||this.set({label:this.get("name")},{silent:!0});var t=l(this.get("cell"),"Cell");this.set({cell:t},{silent:!0})}}),$=c.Columns=r.Collection.extend({model:b}),T=c.Row=r.View.extend({tagName:"tr",initOptionRequires:["columns","model"],initialize:function(e){s(e,this.initOptionRequires);var t=this.columns=e.columns;t instanceof r.Collection||(t=this.columns=new $(t));for(var i=this.cells=[],n=0;t.length>n;n++)i.push(this.makeCell(t.at(n),e));this.listenTo(t,"change:renderable",function(e,t){for(var r=0;i.length>r;r++){var n=i[r];n.column.get("name")==e.get("name")&&(t?n.$el.show():n.$el.hide())}}),this.listenTo(t,"add",function(t,r){var n=r.indexOf(t),o=this.makeCell(t,e);i.splice(n,0,o),o.column.get("renderable")||o.$el.hide();var s=this.$el;0===n?s.prepend(o.render().$el):n===r.length-1?s.append(o.render().$el):s.children().eq(n).before(o.render().$el)}),this.listenTo(t,"remove",function(e,t,r){i[r.index].remove(),i.splice(r.index,1)})},makeCell:function(e){return new(e.get("cell"))({column:e,model:this.model})},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.cells.length>t;t++){var i=this.cells[t];e.appendChild(i.render().el),i.column.get("renderable")||i.$el.hide()}return this.el.appendChild(e),this},remove:function(){for(var e=0;this.cells.length>e;e++){var t=this.cells[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}}),x=c.HeaderCell=r.View.extend({tagName:"th",events:{"click a":"onClick"},_direction:null,initialize:function(e){s(e,["column","collection"]),this.column=e.column,this.column instanceof b||(this.column=new b(this.column)),this.listenTo(r,"backgrid:sort",this._resetCellDirection)},direction:function(e){return arguments.length&&(this._direction&&this.$el.removeClass(this._direction),e&&this.$el.addClass(e),this._direction=e),this._direction},_resetCellDirection:function(e,t,i,r){r==this.collection&&(e!==this.column.get("name")?this.direction(null):this.direction(t))},onClick:function(e){e.preventDefault();var t=this.column.get("name");this.column.get("sortable")&&("ascending"===this.direction()?this.sort(t,"descending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:r>n?-1:1}):"descending"===this.direction()?this.sort(t,null):this.sort(t,"ascending",function(e,i){var r=e.get(t),n=i.get(t);return r===n?0:n>r?-1:1}))},sort:function(e,t,i){i=i||this._cidComparator;var n=this.collection;if(r.PageableCollection&&n instanceof r.PageableCollection){var o;o="ascending"===t?-1:"descending"===t?1:null,n.setSorting(o?e:null,o),"client"==n.mode?(n.fullCollection.comparator||(n.fullCollection.comparator=i),n.fullCollection.sort()):n.fetch()}else n.comparator=i,n.sort();r.trigger("backgrid:sort",e,t,i,this.collection)},_cidComparator:function(e,t){var r=e.cid,n=t.cid;if(!i.isUndefined(r)&&!i.isUndefined(n)){if(r=1*r.slice(1),n=1*n.slice(1),n>r)return-1;if(r>n)return 1}return 0},render:function(){this.$el.empty();var e=t("").text(this.column.get("label")).append("");return this.$el.append(e),this}});c.HeaderRow=c.Row.extend({initOptionRequires:["columns","collection"],initialize:function(){c.Row.prototype.initialize.apply(this,arguments)},makeCell:function(e,t){var i=e.get("headerCell")||t.headerCell||x;return i=new i({column:e,collection:this.collection})}});var R=c.Header=r.View.extend({tagName:"thead",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new $(this.columns)),this.row=new c.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this},remove:function(){return this.row.remove.apply(this.row,arguments),r.View.prototype.remove.apply(this,arguments)}}),D=c.Body=r.View.extend({tagName:"tbody",initialize:function(e){s(e,["columns","collection"]),this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new $(this.columns)),this.row=e.row||T,this.rows=this.collection.map(function(e){var t=new this.row({columns:this.columns,model:e});return t},this);var t=this.collection;this.listenTo(t,"add",this.insertRow),this.listenTo(t,"remove",this.removeRow),this.listenTo(t,"sort",this.refresh),this.listenTo(t,"reset",this.refresh)},insertRow:function(e,t,n){if(!(t instanceof r.Collection||n))return this.collection.add(e,n=t),void 0;n=i.extend({render:!0},n||{});var o=new this.row({columns:this.columns,model:e}),s=t.indexOf(e);this.rows.splice(s,0,o);var l=this.$el,a=l.children(),c=o.render().$el;n.render&&(s>=a.length?l.append(c):a.eq(s).before(c))},removeRow:function(e,t,r){return r?((i.isUndefined(r.render)||r.render)&&this.rows[r.index].remove(),this.rows.splice(r.index,1),void 0):(this.collection.remove(e,r=t),void 0)},refresh:function(){var e=this;return i.each(e.rows,function(e){e.remove()}),e.rows=e.collection.map(function(t){var i=new e.row({columns:e.columns,model:t});return i}),e.render(),r.trigger("backgrid:refresh"),e},render:function(){this.$el.empty();for(var e=document.createDocumentFragment(),t=0;this.rows.length>t;t++){var i=this.rows[t];e.appendChild(i.render().el)}return this.el.appendChild(e),this},remove:function(){for(var e=0;this.rows.length>e;e++){var t=this.rows[e];t.remove.apply(t,arguments)}return r.View.prototype.remove.apply(this,arguments)}});c.Footer=r.View.extend({tagName:"tfoot",initialize:function(e){s(e,["columns","collection"]),this.parent=e.parent,this.columns=e.columns,this.columns instanceof r.Collection||(this.columns=new c.Columns(this.columns))}}),c.Grid=r.View.extend({tagName:"table",className:"backgrid",header:R,body:D,footer:null,initialize:function(e){s(e,["columns","collection"]),e.columns instanceof r.Collection||(e.columns=new $(e.columns)),this.columns=e.columns,this.header=e.header||this.header,this.header=new this.header(e),this.body=e.body||this.body,this.body=new this.body(e),this.footer=e.footer||this.footer,this.footer&&(this.footer=new this.footer(e)),this.listenTo(this.columns,"reset",function(){this.header=new(this.header.remove().constructor)(e),this.body=new(this.body.remove().constructor)(e),this.footer&&(this.footer=new(this.footer.remove().constructor)(e)),this.render()})},insertRow:function(e,t,i){return this.body.insertRow(e,t,i)},removeRow:function(e,t,i){return this.body.removeRow(e,t,i)},insertColumn:function(e,t){return t=t||{render:!0},this.columns.add(e,t),this},removeColumn:function(e,t){return this.columns.remove(e,t),this},render:function(){return this.$el.empty(),this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.trigger("rendered"),this},remove:function(){return this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),r.View.prototype.remove.apply(this,arguments)}})})(this,$,_,Backbone); \ No newline at end of file diff --git a/src/preamble.js b/src/preamble.js index 1800546e..4889342e 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -9,7 +9,7 @@ var window = root; var Backgrid = root.Backgrid = { - VERSION: "0.1.3", + VERSION: "0.1.4", Extension: {} }; From ac3a37d37b50651b9fcfc313943f8bb48e4dc0a6 Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Wed, 20 Feb 2013 00:35:20 +0800 Subject: [PATCH 3/4] Upgrade backbone-pageable to 1.1.6 --- assets/js/backbone-pageable.js | 191 ++++++++++++++++----------------- 1 file changed, 93 insertions(+), 98 deletions(-) diff --git a/assets/js/backbone-pageable.js b/assets/js/backbone-pageable.js index e30b888d..f585345e 100644 --- a/assets/js/backbone-pageable.js +++ b/assets/js/backbone-pageable.js @@ -2,7 +2,7 @@ backbone-pageable http://github.com/wyuenho/backbone-pageable - Copyright (c) 2012 Jimmy Yuen Ho Wong + Copyright (c) 2013 Jimmy Yuen Ho Wong Licensed under the MIT @license. */ @@ -282,20 +282,19 @@ options = options || {}; - var self = this; - var mode = self.mode = options.mode || self.mode || PageableProto.mode; + var mode = this.mode = options.mode || this.mode || PageableProto.mode; - var queryParams = _extend({}, PageableProto.queryParams, self.queryParams, + var queryParams = _extend({}, PageableProto.queryParams, this.queryParams, options.queryParams || {}); queryParams.directions = _extend({}, PageableProto.queryParams.directions, - self.queryParams.directions, + this.queryParams.directions, queryParams.directions || {}); - self.queryParams = queryParams; + this.queryParams = queryParams; - var state = self.state = _extend({}, PageableProto.state, self.state, + var state = this.state = _extend({}, PageableProto.state, this.state, options.state || {}); state.currentPage = state.currentPage == null ? @@ -306,21 +305,21 @@ state.totalRecords = models.length; } - self.switchMode(mode, _extend({fetch: false, + this.switchMode(mode, _extend({fetch: false, resetState: false, models: models}, options)); var comparator = options.comparator; if (state.sortKey && !comparator) { - self.setSorting(state.sortKey, state.order, options); + this.setSorting(state.sortKey, state.order, options); } if (mode != "server") { if (comparator && options.full) { - delete self.comparator; - var fullCollection = self.fullCollection; + delete this.comparator; + var fullCollection = this.fullCollection; fullCollection.comparator = comparator; fullCollection.sort(); } @@ -328,12 +327,12 @@ // make sure the models in the current page and full collection have the // same references if (models && !_isEmpty(models)) { - self.getPage(state.currentPage); - models.splice.apply(models, [0, models.length].concat(self.models)); + this.getPage(state.currentPage); + models.splice.apply(models, [0, models.length].concat(this.models)); } } - self._initState = _clone(self.state); + this._initState = _clone(this.state); }, /** @@ -346,9 +345,8 @@ */ _makeFullCollection: function (models, options) { - var self = this; var properties = ["url", "model", "sync", "comparator"]; - var thisProto = self.constructor.prototype; + var thisProto = this.constructor.prototype; var i, length, prop; var proto = {}; @@ -363,7 +361,7 @@ for (i = 0, length = properties.length; i < length; i++) { prop = properties[i]; - if (self[prop] !== thisProto[prop]) { + if (this[prop] !== thisProto[prop]) { fullCollection[prop] = prop; } } @@ -404,29 +402,34 @@ var pageStart = currentPage * pageSize, pageEnd = pageStart + pageSize; if (event == "add") { - var fullIndex, addAt, colToAdd, options = options || {}; + var pageIndex, fullIndex, addAt, colToAdd, options = options || {}; if (collection == fullCol) { fullIndex = fullCol.indexOf(model); if (fullIndex >= pageStart && fullIndex < pageEnd) { colToAdd = pageCol; - addAt = fullIndex - pageStart; + pageIndex = addAt = fullIndex - pageStart; } } else { - fullIndex = pageStart + pageCol.indexOf(model); + pageIndex = pageCol.indexOf(model); + fullIndex = pageStart + pageIndex; colToAdd = fullCol; - var addAt = options && !_.isUndefined(options.at) ? + var addAt = !_isUndefined(options.at) ? options.at + pageStart : fullIndex; } - ++state.totalRecords; pageCol.state = pageCol._checkState(state); if (colToAdd) { colToAdd.add(model, _extend({}, options || {}, {at: addAt})); - if (pageCol.length > pageSize) { + var modelToRemove = pageIndex >= pageSize ? + model : + !_isUndefined(options.at) && addAt < pageEnd && pageCol.length > pageSize ? + pageCol.at(pageSize) : + null; + if (modelToRemove) { var addHandlers = collection._events.add, popOptions = {onAdd: true}; if (addHandlers.length) { @@ -435,14 +438,14 @@ lastAddHandler.callback = function () { try { oldCallback.apply(this, arguments); - pageCol.pop(popOptions); + pageCol.remove(modelToRemove, popOptions); } finally { lastAddHandler.callback = oldCallback; } }; } - else pageCol.pop(popOptions); + else pageCol.remove(modelToRemove, popOptions); } } } @@ -531,9 +534,8 @@ */ _checkState: function (state) { - var self = this; - var mode = self.mode; - var links = self.links; + var mode = this.mode; + var links = this.links; var totalRecords = state.totalRecords; var pageSize = state.pageSize; var currentPage = state.currentPage; @@ -603,18 +605,16 @@ from fetch or this. */ setPageSize: function (pageSize, options) { - var self = this; - pageSize = finiteInt(pageSize, "pageSize"); options = options || {}; - self.state = self._checkState(_extend({}, self.state, { + this.state = this._checkState(_extend({}, this.state, { pageSize: pageSize, - totalPages: ceil(self.state.totalRecords / pageSize) + totalPages: ceil(this.state.totalRecords / pageSize) })); - return self.getPage(self.state.currentPage, options); + return this.getPage(this.state.currentPage, options); }, /** @@ -649,33 +649,32 @@ */ switchMode: function (mode, options) { - var self = this; - if (!_contains(["server", "client", "infinite"], mode)) { throw new TypeError('`mode` must be one of "server", "client" or "infinite"'); } options = options || {fetch: true, resetState: true}; - var state = self.state = options.resetState ? - _clone(self._initState) : - self._checkState(_extend({}, self.state)); + var state = this.state = options.resetState ? + _clone(this._initState) : + this._checkState(_extend({}, this.state)); - self.mode = mode; + this.mode = mode; - var fullCollection = self.fullCollection; - var handlers = self._handlers = self._handlers || {}, handler; + var self = this; + var fullCollection = this.fullCollection; + var handlers = this._handlers = this._handlers || {}, handler; if (mode != "server" && !fullCollection) { - fullCollection = self._makeFullCollection(options.models || []); - fullCollection.pageableCollection = self; - self.fullCollection = fullCollection; - var allHandler = self._makeCollectionEventHandler(self, fullCollection); + fullCollection = this._makeFullCollection(options.models || []); + fullCollection.pageableCollection = this; + this.fullCollection = fullCollection; + var allHandler = this._makeCollectionEventHandler(this, fullCollection); _each(["add", "remove", "reset", "sort"], function (event) { handlers[event] = handler = _.bind(allHandler, {}, event); self.on(event, handler); fullCollection.on(event, handler); }); - fullCollection.comparator = self._fullComparator; + fullCollection.comparator = this._fullComparator; } else if (mode == "server" && fullCollection) { _each(_keys(handlers), function (event) { @@ -683,25 +682,25 @@ self.off(event, handler); fullCollection.off(event, handler); }); - delete self._handlers; - self._fullComparator = fullCollection.comparator; - delete self.fullCollection; + delete this._handlers; + this._fullComparator = fullCollection.comparator; + delete this.fullCollection; } if (mode == "infinite") { - var links = self.links = {}; + var links = this.links = {}; var firstPage = state.firstPage; var totalPages = ceil(state.totalRecords / state.pageSize); var lastPage = firstPage === 0 ? totalPages - 1 : totalPages || firstPage; for (var i = state.firstPage; i <= lastPage; i++) { - links[i] = self.url; + links[i] = this.url; } } - else if (self.links) delete self.links; + else if (this.links) delete this.links; return options.fetch ? - self.fetch(_omit(options, "fetch", "resetState")) : - self; + this.fetch(_omit(options, "fetch", "resetState")) : + this; }, /** @@ -709,10 +708,10 @@ otherwise. */ hasPrevious: function () { - var self = this, state = self.state; + var state = this.state; var currentPage = state.currentPage; - if (self.mode != "infinite") return currentPage > state.firstPage; - return !!self.links[currentPage - 1]; + if (this.mode != "infinite") return currentPage > state.firstPage; + return !!this.links[currentPage - 1]; }, /** @@ -720,10 +719,10 @@ otherwise. */ hasNext: function () { - var self = this, state = self.state; - var currentPage = self.state.currentPage; - if (self.mode != "infinite") return currentPage < state.lastPage; - return !!self.links[currentPage + 1]; + var state = this.state; + var currentPage = this.state.currentPage; + if (this.mode != "infinite") return currentPage < state.lastPage; + return !!this.links[currentPage + 1]; }, /** @@ -812,11 +811,11 @@ */ getPage: function (index, options) { - var self = this, mode = self.mode, fullCollection = self.fullCollection; + var mode = this.mode, fullCollection = this.fullCollection; options = options || {fetch: false}; - var state = self.state, + var state = this.state, firstPage = state.firstPage, currentPage = state.currentPage, lastPage = state.lastPage, @@ -831,7 +830,7 @@ default: pageNum = finiteInt(index, "index"); } - self.state = self._checkState(_extend({}, state, {currentPage: pageNum})); + this.state = this._checkState(_extend({}, state, {currentPage: pageNum})); var pageStart = (firstPage === 0 ? pageNum : pageNum - 1) * pageSize; var pageModels = fullCollection && fullCollection.length ? @@ -839,12 +838,12 @@ []; if ((mode == "client" || (mode == "infinite" && !_isEmpty(pageModels))) && !options.fetch) { - return resetQuickly(self, pageModels, _omit(options, "fetch")); + return resetQuickly(this, pageModels, _omit(options, "fetch")); } - if (mode == "infinite") options.url = self.links[pageNum]; + if (mode == "infinite") options.url = this.links[pageNum]; - return self.fetch(_omit(options, "fetch")); + return this.fetch(_omit(options, "fetch")); }, /** @@ -900,7 +899,6 @@ @return {Object} */ parseLinks: function (resp, options) { - var self = this; var linkHeader = options.xhr.getResponseHeader("Link"); var relations = ["first", "prev", "previous", "next", "last"]; var links = {}; @@ -923,8 +921,8 @@ if (qs = (qsi = last.indexOf('?')) ? last.slice(qsi + 1) : '') { var params = queryStringToParams(qs); - var state = _.clone(self.state); - var queryParams = self.queryParams; + var state = _clone(this.state); + var queryParams = this.queryParams; var pageSize = state.pageSize; var totalRecords = params[queryParams.totalRecords] * 1; @@ -940,7 +938,7 @@ if (totalRecords) state.totalRecords = totalRecords; - self.state = self._checkState(state); + this.state = this._checkState(state); } delete links.last; @@ -980,16 +978,14 @@ */ parse: function (resp) { - var self = this; - if (!_isArray(resp)) { return new TypeError("The server response must be an array"); } if (resp.length === 2 && _.isObject(resp[0]) && _isArray(resp[1])) { - var queryParams = self.queryParams; - var newState = _clone(self.state); + var queryParams = this.queryParams; + var newState = _clone(this.state); var serverState = resp[0]; _each(_pairs(_omit(queryParams, "directions")), function (kvp) { @@ -1001,7 +997,7 @@ newState.order = _invert(queryParams.directions)[serverState.order] * 1; } - self.state = self._checkState(newState); + this.state = this._checkState(newState); return resp[1]; } @@ -1026,22 +1022,20 @@ */ fetch: function (options) { - var self = this; - options = options || {}; - var state = self._checkState(self.state); + var state = this._checkState(this.state); - var mode = self.mode; + var mode = this.mode; if (mode == "infinite" && !options.url) { - options.url = self.links[state.currentPage]; + options.url = this.links[state.currentPage]; } var data = options.data || {}; // dedup query params - var url = options.url || _.result(self, "url") || ''; + var url = options.url || _.result(this, "url") || ''; var qsi = url.indexOf('?'); if (qsi != -1) { _extend(data, queryStringToParams(url.slice(qsi + 1))); @@ -1052,12 +1046,12 @@ options.data = data; // map params except directions - var queryParams = self.mode == "client" ? - _pick(self.queryParams, "sortKey", "order") : - _omit(_pick(self.queryParams, _keys(PageableProto.queryParams)), + var queryParams = this.mode == "client" ? + _pick(this.queryParams, "sortKey", "order") : + _omit(_pick(this.queryParams, _keys(PageableProto.queryParams)), "directions"); - var i, kvp, k, v, kvps = _pairs(queryParams), thisCopy = _clone(self); + var i, kvp, k, v, kvps = _pairs(queryParams), thisCopy = _clone(this); for (i = 0; i < kvps.length; i++) { kvp = kvps[i], k = kvp[0], v = kvp[1]; v = _isFunction(v) ? v.call(thisCopy) : v; @@ -1068,12 +1062,12 @@ // fix up sorting parameters if (state.sortKey && state.order) { - data[queryParams.order] = self.queryParams.directions[state.order + ""]; + data[queryParams.order] = this.queryParams.directions[state.order + ""]; } else if (!state.sortKey) delete data[queryParams.order]; // map extra query parameters - var extraKvps = _pairs(_omit(self.queryParams, + var extraKvps = _pairs(_omit(this.queryParams, _keys(PageableProto.queryParams))); for (i = 0; i < extraKvps.length; i++) { kvp = extraKvps[i]; @@ -1082,10 +1076,11 @@ data[kvp[0]] = v; } - var fullCollection = self.fullCollection, links = self.links; + var fullCollection = this.fullCollection, links = this.links; if (mode != "server") { + var self = this; var success = options.success; options.success = function (col, resp, opts) { @@ -1125,7 +1120,7 @@ return BBColProto.fetch.call(self, _extend({}, options, {silent: true})); } - return BBColProto.fetch.call(self, options); + return BBColProto.fetch.call(this, options); }, /** @@ -1194,22 +1189,22 @@ */ setSorting: function (sortKey, order, options) { - var self = this, state = self.state; + var state = this.state; state.sortKey = sortKey; state.order = order = order || state.order; - var fullCollection = self.fullCollection; + var fullCollection = this.fullCollection; var delComp = false, delFullComp = false; if (!sortKey) delComp = delFullComp = true; - var mode = self.mode; + var mode = this.mode; options = _extend({side: mode == "client" ? mode : "server", full: true}, options); - var comparator = self._makeComparator(sortKey, order); + var comparator = this._makeComparator(sortKey, order); var full = options.full, side = options.side; @@ -1219,18 +1214,18 @@ delComp = true; } else { - self.comparator = comparator; + this.comparator = comparator; delFullComp = true; } } else if (side == "server" && !full) { - self.comparator = comparator; + this.comparator = comparator; } - if (delComp) delete self.comparator; + if (delComp) delete this.comparator; if (delFullComp && fullCollection) delete fullCollection.comparator; - return self; + return this; } }); From 59bbc26e75a6d4244be57301facc29f0c2026975 Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Wed, 20 Feb 2013 00:45:22 +0800 Subject: [PATCH 4/4] Update download version --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 8b2a6f9a..3b91b10f 100644 --- a/index.html +++ b/index.html @@ -135,7 +135,7 @@

Backgrid.js

See Examples Download v0.1.3 + target="_blank">Download v0.1.4