backgridjs-rails 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +25 -0
  4. data/Rakefile +27 -0
  5. data/lib/backgridjs-rails.rb +5 -0
  6. data/lib/backgridjs-rails.rb~ +2 -0
  7. data/lib/backgridjs-rails/engine.rb +8 -0
  8. data/lib/backgridjs-rails/engine.rb~ +8 -0
  9. data/lib/backgridjs-rails/version.rb +3 -0
  10. data/lib/backgridjs-rails/version.rb~ +3 -0
  11. data/lib/tasks/backgridjs-rails_tasks.rake +4 -0
  12. data/vendor/assets/javascripts/backgrid-extensions/backgrid-filter.js +365 -0
  13. data/vendor/assets/javascripts/backgrid-extensions/backgrid-moment-cell.js +175 -0
  14. data/vendor/assets/javascripts/backgrid-extensions/backgrid-paginator.js +198 -0
  15. data/vendor/assets/javascripts/backgrid-extensions/backgrid-select-all.js +215 -0
  16. data/vendor/assets/javascripts/backgrid-extensions/backgrid-select2-cell.js +121 -0
  17. data/vendor/assets/javascripts/backgrid-extensions/backgrid-text-cell.js +159 -0
  18. data/vendor/assets/javascripts/backgrid.js +2531 -0
  19. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-filter.css +19 -0
  20. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-moment-cell.css +14 -0
  21. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-paginator.css +58 -0
  22. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-select-all.css +11 -0
  23. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-select2-cell.css +19 -0
  24. data/vendor/assets/stylesheets/backgrid-extensions/backgrid-text-cell.css +31 -0
  25. data/vendor/assets/stylesheets/backgrid.css +215 -0
  26. metadata +82 -0
@@ -0,0 +1,175 @@
1
+ /*
2
+ backgrid-moment-cell
3
+ http://github.com/wyuenho/backgrid
4
+
5
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
6
+ Licensed under the MIT @license.
7
+ */
8
+ (function ($, _, Backbone, Backgrid, moment) {
9
+
10
+ /**
11
+ MomentFormatter converts bi-directionally any datetime values in any format
12
+ supported by [moment()](http://momentjs.com/docs/#/parsing/) to any
13
+ datetime format
14
+ [moment.fn.format()](http://momentjs.com/docs/#/displaying/format/)
15
+ supports.
16
+
17
+ @class Backgrid.Extension.MomentFormatter
18
+ @extends Backgrid.CellFormatter
19
+ @constructor
20
+ */
21
+ var MomentFormatter = Backgrid.Extension.MomentFormatter = function (options) {
22
+ _.extend(this, this.defaults, options);
23
+ };
24
+ MomentFormatter.prototype = new Backgrid.CellFormatter;
25
+ _.extend(MomentFormatter.prototype, {
26
+
27
+ /**
28
+ @cfg {Object} options
29
+
30
+ @cfg {boolean} [options.modelInUnixOffset=false] Whether the model values
31
+ should be read/written as the number of milliseconds since UNIX Epoch.
32
+
33
+ @cfg {boolean} [options.modelInUnixTimestamp=false] Whether the model
34
+ values should be read/written as the number of seconds since UNIX Epoch.
35
+
36
+ @cfg {boolean} [options.modelInUTC=true] Whether the model values should
37
+ be read/written in UTC mode or local mode.
38
+
39
+ @cfg {string} [options.modelLang=moment.lang()] The locale the model
40
+ values should be read/written in.
41
+
42
+ @cfg {string} [options.modelFormat=moment.defaultFormat] The format this
43
+ moment formatter should use to read/write model values. Only meaningful if
44
+ the values are strings.
45
+
46
+ @cfg {boolean} [options.displayInUnixOffset=false] Whether the display
47
+ values should be read/written as the number of milliseconds since UNIX
48
+ Epoch.
49
+
50
+ @cfg {boolean} [options.displayInUnixTimestamp=false] Whether the display
51
+ values should be read/written as the number of seconds since UNIX Epoch.
52
+
53
+ @cfg {boolean} [options.displayInUTC=true] Whether the display values
54
+ should be read/written in UTC mode or local mode.
55
+
56
+ @cfg {string} [options.displayLang=moment.lang()] The locale the display
57
+ values should be read/written in.
58
+
59
+ @cfg {string} [options.displayFormat=moment.defaultFormat] The format
60
+ this moment formatter should use to read/write dislay values.
61
+ */
62
+ defaults: {
63
+ modelInUnixOffset: false,
64
+ modelInUnixTimestamp: false,
65
+ modelInUTC: true,
66
+ modelLang: moment.lang(),
67
+ modelFormat: moment.defaultFormat,
68
+ displayInUnixOffset: false,
69
+ displayInUnixTimestamp: false,
70
+ displayInUTC: true,
71
+ displayLang: moment.lang(),
72
+ displayFormat: moment.defaultFormat
73
+ },
74
+
75
+ /**
76
+ Converts datetime values from the model for display.
77
+
78
+ @member Backgrid.Extension.MomentFormatter
79
+ @param {*} rawData
80
+ @return {string}
81
+ */
82
+ fromRaw: function (rawData) {
83
+ if (rawData == null) return '';
84
+
85
+ var m = this.modelInUnixOffset ? moment(rawData) :
86
+ this.modelInUnixTimestamp ? moment.unix(rawData) :
87
+ this.modelInUTC ?
88
+ moment.utc(rawData, this.modelFormat, this.modelLang) :
89
+ moment(rawData, this.modelFormat, this.modelLang);
90
+
91
+ if (this.displayInUnixOffset) return +m;
92
+
93
+ if (this.displayInUnixTimestamp) return m.unix();
94
+
95
+ if (this.displayLang) m.lang(this.displayLang);
96
+
97
+ if (this.displayInUTC) m.utc(); else m.local();
98
+
99
+ return m.format(this.displayFormat);
100
+ },
101
+
102
+ /**
103
+ Converts datetime values from user input to model values.
104
+
105
+ @member Backgrid.Extension.MomentFormatter
106
+ @param {string} formattedData
107
+ @return {string}
108
+ */
109
+ toRaw: function (formattedData) {
110
+
111
+ var m = this.displayInUnixOffset ? moment(+formattedData) :
112
+ this.displayInUnixTimestamp ? moment.unix(+formattedData) :
113
+ this.displayInUTC ?
114
+ moment.utc(formattedData, this.displayFormat, this.displayLang) :
115
+ moment(formattedData, this.displayFormat, this.displayLang);
116
+
117
+ if (!m || !m.isValid()) return;
118
+
119
+ if (this.modelInUnixOffset) return +m;
120
+
121
+ if (this.modelInUnixTimestamp) return m.unix();
122
+
123
+ if (this.modelLang) m.lang(this.modelLang);
124
+
125
+ if (this.modelInUTC) m.utc(); else m.local();
126
+
127
+ return m.format(this.modelFormat);
128
+ }
129
+
130
+ });
131
+
132
+ /**
133
+ Renders a datetime cell that uses a Backgrid.Extension.MomentFormatter to
134
+ convert and validate values.
135
+
136
+ @class Backgrid.Extension.MomentCell
137
+ @extends Backgrid.Cell
138
+ */
139
+ var MomentCell = Backgrid.Extension.MomentCell = Backgrid.Cell.extend({
140
+
141
+ editor: Backgrid.InputCellEditor,
142
+
143
+ /** @property */
144
+ className: "moment-cell",
145
+
146
+ /** @property {Backgrid.CellFormatter} [formatter=Backgrid.Extension.MomentFormatter] */
147
+ formatter: MomentFormatter,
148
+
149
+ /**
150
+ Initializer. Accept Backgrid.Extension.MomentFormatter.options and
151
+ Backgrid.Cell.initialize required parameters.
152
+ */
153
+ initialize: function (options) {
154
+
155
+ Backgrid.Cell.prototype.initialize.apply(this, arguments);
156
+
157
+ var formatterDefaults = MomentFormatter.prototype.defaults;
158
+ var formatterDefaultKeys = _.keys(formatterDefaults);
159
+ var classAttrs = _.pick(this, formatterDefaultKeys);
160
+ var formatterOptions = _.pick(options, formatterDefaultKeys);
161
+
162
+ this.formatter = new this.formatter(_.extend({}, formatterDefaults, classAttrs, formatterOptions));
163
+
164
+ this.editor = this.editor.extend({
165
+ attributes: _.extend({}, this.editor.prototype.attributes || this.editor.attributes || {}, {
166
+ placeholder: this.formatter.displayFormat
167
+ })
168
+ });
169
+ }
170
+
171
+ });
172
+
173
+ _.extend(MomentCell.prototype, MomentFormatter.prototype.defaults);
174
+
175
+ }(jQuery, _, Backbone, Backgrid, moment));
@@ -0,0 +1,198 @@
1
+ /*
2
+ backgrid-paginator
3
+ http://github.com/wyuenho/backgrid
4
+
5
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
6
+ Licensed under the MIT @license.
7
+ */
8
+
9
+ (function ($, _, Backbone, Backgrid) {
10
+
11
+ "use strict";
12
+
13
+ /**
14
+ Paginator is a Backgrid extension that renders a series of configurable
15
+ pagination handles. This extension is best used for splitting a large data
16
+ set across multiple pages. If the number of pages is larger then a
17
+ threshold, which is set to 10 by default, the page handles are rendered
18
+ within a sliding window, plus the fast forward, fast backward, previous and
19
+ next page handles. The fast forward, fast backward, previous and next page
20
+ handles can be turned off.
21
+
22
+ @class Backgrid.Extension.Paginator
23
+ */
24
+ Backgrid.Extension.Paginator = Backbone.View.extend({
25
+
26
+ /** @property */
27
+ className: "backgrid-paginator",
28
+
29
+ /** @property */
30
+ windowSize: 10,
31
+
32
+ /**
33
+ @property {Object} fastForwardHandleLabels You can disable specific
34
+ handles by setting its value to `null`.
35
+ */
36
+ fastForwardHandleLabels: {
37
+ first: "《",
38
+ prev: "〈",
39
+ next: "〉",
40
+ last: "》"
41
+ },
42
+
43
+ /** @property */
44
+ template: _.template('<ul><% _.each(handles, function (handle) { %><li <% if (handle.className) { %>class="<%= handle.className %>"<% } %>><a href="#" <% if (handle.title) {%> title="<%= handle.title %>"<% } %>><%= handle.label %></a></li><% }); %></ul>'),
45
+
46
+ /** @property */
47
+ events: {
48
+ "click a": "changePage"
49
+ },
50
+
51
+ /**
52
+ Initializer.
53
+
54
+ @param {Object} options
55
+ @param {Backbone.Collection} options.collection
56
+ @param {boolean} [options.fastForwardHandleLabels] Whether to render fast forward buttons.
57
+ */
58
+ initialize: function (options) {
59
+ Backgrid.requireOptions(options, ["collection"]);
60
+
61
+ var collection = this.collection;
62
+ var fullCollection = collection.fullCollection;
63
+ if (fullCollection) {
64
+ this.listenTo(fullCollection, "add", this.render);
65
+ this.listenTo(fullCollection, "remove", this.render);
66
+ this.listenTo(fullCollection, "reset", this.render);
67
+ }
68
+ else {
69
+ this.listenTo(collection, "add", this.render);
70
+ this.listenTo(collection, "remove", this.render);
71
+ this.listenTo(collection, "reset", this.render);
72
+ }
73
+ },
74
+
75
+ /**
76
+ jQuery event handler for the page handlers. Goes to the right page upon
77
+ clicking.
78
+
79
+ @param {Event} e
80
+ */
81
+ changePage: function (e) {
82
+ e.preventDefault();
83
+
84
+ var $li = $(e.target).parent();
85
+ if (!$li.hasClass("active") && !$li.hasClass("disabled")) {
86
+
87
+ var label = $(e.target).text();
88
+ var ffLabels = this.fastForwardHandleLabels;
89
+
90
+ var collection = this.collection;
91
+
92
+ if (ffLabels) {
93
+ switch (label) {
94
+ case ffLabels.first:
95
+ collection.getFirstPage();
96
+ return;
97
+ case ffLabels.prev:
98
+ collection.getPreviousPage();
99
+ return;
100
+ case ffLabels.next:
101
+ collection.getNextPage();
102
+ return;
103
+ case ffLabels.last:
104
+ collection.getLastPage();
105
+ return;
106
+ }
107
+ }
108
+
109
+ var state = collection.state;
110
+ var pageIndex = +label;
111
+ collection.getPage(state.firstPage === 0 ? pageIndex - 1 : pageIndex);
112
+ }
113
+ },
114
+
115
+ /**
116
+ Internal method to create a list of page handle objects for the template
117
+ to render them.
118
+
119
+ @return {Array.<Object>} an array of page handle objects hashes
120
+ */
121
+ makeHandles: function () {
122
+
123
+ var handles = [];
124
+ var collection = this.collection;
125
+ var state = collection.state;
126
+
127
+ // convert all indices to 0-based here
128
+ var firstPage = state.firstPage;
129
+ var lastPage = +state.lastPage;
130
+ lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage);
131
+ var currentPage = Math.max(state.currentPage, state.firstPage);
132
+ currentPage = firstPage ? currentPage - 1 : currentPage;
133
+ var windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize;
134
+ var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize);
135
+
136
+ if (collection.mode !== "infinite") {
137
+ for (var i = windowStart; i < windowEnd; i++) {
138
+ handles.push({
139
+ label: i + 1,
140
+ title: "No. " + (i + 1),
141
+ className: currentPage === i ? "active" : undefined
142
+ });
143
+ }
144
+ }
145
+
146
+ var ffLabels = this.fastForwardHandleLabels;
147
+ if (ffLabels) {
148
+
149
+ if (ffLabels.prev) {
150
+ handles.unshift({
151
+ label: ffLabels.prev,
152
+ className: collection.hasPrevious() ? void 0 : "disabled"
153
+ });
154
+ }
155
+
156
+ if (ffLabels.first) {
157
+ handles.unshift({
158
+ label: ffLabels.first,
159
+ className: collection.hasPrevious() ? void 0 : "disabled"
160
+ });
161
+ }
162
+
163
+ if (ffLabels.next) {
164
+ handles.push({
165
+ label: ffLabels.next,
166
+ className: collection.hasNext() ? void 0 : "disabled"
167
+ });
168
+ }
169
+
170
+ if (ffLabels.last) {
171
+ handles.push({
172
+ label: ffLabels.last,
173
+ className: collection.hasNext() ? void 0 : "disabled"
174
+ });
175
+ }
176
+ }
177
+
178
+ return handles;
179
+ },
180
+
181
+ /**
182
+ Render the paginator handles inside an unordered list.
183
+ */
184
+ render: function () {
185
+ this.$el.empty();
186
+
187
+ this.$el.append(this.template({
188
+ handles: this.makeHandles()
189
+ }));
190
+
191
+ this.delegateEvents();
192
+
193
+ return this;
194
+ }
195
+
196
+ });
197
+
198
+ }(jQuery, _, Backbone, Backgrid));
@@ -0,0 +1,215 @@
1
+ /*
2
+ backgrid-select-all
3
+ http://github.com/wyuenho/backgrid
4
+
5
+ Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
6
+ Licensed under the MIT @license.
7
+ */
8
+ (function (window, $, _, Backbone, Backgrid) {
9
+
10
+ /**
11
+ Renders a checkbox for row selection.
12
+
13
+ @class Backgrid.Extension.SelectRowCell
14
+ @extends Backbone.View
15
+ */
16
+ var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({
17
+
18
+ /** @property */
19
+ className: "select-row-cell",
20
+
21
+ /** @property */
22
+ tagName: "td",
23
+
24
+ /** @property */
25
+ events: {
26
+ "keydown :checkbox": "onKeydown",
27
+ "change :checkbox": "onChange",
28
+ "click :checkbox": "enterEditMode"
29
+ },
30
+
31
+ /**
32
+ Initializer. If the underlying model triggers a `select` event, this cell
33
+ will change its checked value according to the event's `selected` value.
34
+
35
+ @param {Object} options
36
+ @param {Backgrid.Column} options.column
37
+ @param {Backbone.Model} options.model
38
+ */
39
+ initialize: function (options) {
40
+ Backgrid.requireOptions(options, ["model", "column"]);
41
+
42
+ this.column = options.column;
43
+ if (!(this.column instanceof Backgrid.Column)) {
44
+ this.column = new Backgrid.Column(this.column);
45
+ }
46
+
47
+ this.listenTo(this.model, "backgrid:select", function (model, selected) {
48
+ this.$el.find(":checkbox").prop("checked", selected).change();
49
+ });
50
+
51
+ },
52
+
53
+ /**
54
+ Focuses the checkbox.
55
+ */
56
+ enterEditMode: function () {
57
+ this.$el.find(":checkbox").focus();
58
+ },
59
+
60
+ /**
61
+ Unfocuses the checkbox.
62
+ */
63
+ exitEditMode: function () {
64
+ this.$el.find(":checkbox").blur();
65
+ },
66
+
67
+ /**
68
+ Process keyboard navigation.
69
+ */
70
+ onKeydown: function (e) {
71
+ var command = new Backgrid.Command(e);
72
+ if (command.passThru()) return true; // skip ahead to `change`
73
+ if (command.cancel()) {
74
+ e.stopPropagation();
75
+ this.$el.find(":checkbox").blur();
76
+ }
77
+ else if (command.save() || command.moveLeft() || command.moveRight() ||
78
+ command.moveUp() || command.moveDown()) {
79
+ e.preventDefault();
80
+ e.stopPropagation();
81
+ this.model.trigger("backgrid:edited", this.model, this.column, command);
82
+ }
83
+ },
84
+
85
+ /**
86
+ When the checkbox's value changes, this method will trigger a Backbone
87
+ `backgrid:selected` event with a reference of the model and the
88
+ checkbox's `checked` value.
89
+ */
90
+ onChange: function (e) {
91
+ this.model.trigger("backgrid:selected", this.model, $(e.target).prop("checked"));
92
+ },
93
+
94
+ /**
95
+ Renders a checkbox in a table cell.
96
+ */
97
+ render: function () {
98
+ this.$el.empty().append('<input tabindex="-1" type="checkbox" />');
99
+ this.delegateEvents();
100
+ return this;
101
+ }
102
+
103
+ });
104
+
105
+ /**
106
+ Renders a checkbox to select all rows on the current page.
107
+
108
+ @class Backgrid.Extension.SelectAllHeaderCell
109
+ @extends Backgrid.Extension.SelectRowCell
110
+ */
111
+ var SelectAllHeaderCell = Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({
112
+
113
+ /** @property */
114
+ className: "select-all-header-cell",
115
+
116
+ /** @property */
117
+ tagName: "th",
118
+
119
+ /**
120
+ Initializer. When this cell's checkbox is checked, a Backbone
121
+ `backgrid:select` event will be triggered for each model for the current
122
+ page in the underlying collection. If a `SelectRowCell` instance exists
123
+ for the rows representing the models, they will check themselves. If any
124
+ of the SelectRowCell instances trigger a Backbone `backgrid:selected`
125
+ event with a `false` value, this cell will uncheck its checkbox. In the
126
+ event of a Backbone `backgrid:refresh` event, which is triggered when the
127
+ body refreshes its rows, which can happen under a number of conditions
128
+ such as paging or the columns were reset, this cell will still remember
129
+ the previously selected models and trigger a Backbone `backgrid:select`
130
+ event on them such that the SelectRowCells can recheck themselves upon
131
+ refreshing.
132
+
133
+ @param {Object} options
134
+ @param {Backgrid.Column} options.column
135
+ @param {Backbone.Collection} options.collection
136
+ */
137
+ initialize: function (options) {
138
+ Backgrid.requireOptions(options, ["column", "collection"]);
139
+
140
+ this.column = options.column;
141
+ if (!(this.column instanceof Backgrid.Column)) {
142
+ this.column = new Backgrid.Column(this.column);
143
+ }
144
+
145
+ var collection = this.collection;
146
+ var selectedModels = this.selectedModels = {};
147
+ this.listenTo(collection, "backgrid:selected", function (model, selected) {
148
+ if (selected) selectedModels[model.id || model.cid] = model;
149
+ else {
150
+ delete selectedModels[model.id || model.cid];
151
+ this.$el.find(":checkbox").prop("checked", false);
152
+ }
153
+ });
154
+
155
+ this.listenTo(collection, "remove", function (model) {
156
+ delete selectedModels[model.cid];
157
+ });
158
+
159
+ this.listenTo(collection, "backgrid:refresh", function () {
160
+ this.$el.find(":checkbox").prop("checked", false);
161
+ for (var i = 0; i < collection.length; i++) {
162
+ var model = collection.at(i);
163
+ if (selectedModels[model.id || model.cid]) {
164
+ model.trigger('backgrid:select', model, true);
165
+ }
166
+ }
167
+ });
168
+ },
169
+
170
+ /**
171
+ Progagates the checked value of this checkbox to all the models of the
172
+ underlying collection by triggering a Backbone `backgrid:select` event on
173
+ the models themselves, passing each model and the current `checked` value
174
+ of the checkbox in each event.
175
+ */
176
+ onChange: function (e) {
177
+ var checked = $(e.target).prop("checked");
178
+
179
+ var collection = this.collection;
180
+ collection.each(function (model) {
181
+ model.trigger("backgrid:select", model, checked);
182
+ });
183
+ }
184
+
185
+ });
186
+
187
+ /**
188
+ Convenient method to retrieve a list of selected models. This method only
189
+ exists when the `SelectAll` extension has been included.
190
+
191
+ @member Backgrid.Grid
192
+ @return {Array.<Backbone.Model>}
193
+ */
194
+ Backgrid.Grid.prototype.getSelectedModels = function () {
195
+ var selectAllHeaderCell;
196
+ var headerCells = this.header.row.cells;
197
+ for (var i = 0, l = headerCells.length; i < l; i++) {
198
+ var headerCell = headerCells[i];
199
+ if (headerCell instanceof SelectAllHeaderCell) {
200
+ selectAllHeaderCell = headerCell;
201
+ break;
202
+ }
203
+ }
204
+
205
+ var result = [];
206
+ if (selectAllHeaderCell) {
207
+ for (var modelId in selectAllHeaderCell.selectedModels) {
208
+ result.push(this.collection.get(modelId));
209
+ }
210
+ }
211
+
212
+ return result;
213
+ };
214
+
215
+ }(window, jQuery, _, Backbone, Backgrid));