tableling-rails 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/lib/tableling-rails/version.rb +1 -1
- data/spec/dummy/app/assets/javascripts/application.js +6 -1
- data/spec/dummy/app/assets/javascripts/books.js +6 -4
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/log/development.log +5136 -4946
- data/spec/dummy/tmp/cache/assets/BF1/770/sprockets%2F8228a53c539c582499241527570aa216 +0 -0
- data/spec/dummy/tmp/cache/assets/C3F/0C0/sprockets%2F4643701467ac62c314510c8dd021916f +0 -0
- data/spec/dummy/tmp/cache/assets/C53/AD0/sprockets%2F712078516a81502575c831cb0a8e898e +0 -0
- data/spec/dummy/tmp/cache/assets/C59/0F0/sprockets%2F099f4e84a443568245ff0674030f6e05 +0 -0
- data/spec/dummy/tmp/cache/assets/C60/CF0/sprockets%2F32a45292ee67867d8715952f3072ad84 +0 -0
- data/spec/dummy/tmp/cache/assets/C6F/0E0/sprockets%2F82372776487d948ef7666d304d6fb345 +0 -0
- data/spec/dummy/tmp/cache/assets/C80/840/sprockets%2F562c2d168da585f80579347d10790a0a +0 -0
- data/spec/dummy/tmp/cache/assets/C82/F20/sprockets%2F117015d65237e3682f5b21c87d58ab95 +0 -0
- data/spec/dummy/tmp/cache/assets/C86/280/sprockets%2F1345c9947753f018f45371ec5083fa2d +0 -0
- data/spec/dummy/tmp/cache/assets/C91/350/sprockets%2F6864c49a10954375948d9f306db308fb +0 -0
- data/spec/dummy/tmp/cache/assets/C9A/900/sprockets%2Fc1b5b7611d7c10e124512724f29f241d +0 -0
- data/spec/dummy/tmp/cache/assets/CAF/540/sprockets%2F8f42e689b84f0b25c0180046467adf31 +0 -0
- data/spec/dummy/tmp/cache/assets/CB1/9A0/sprockets%2F57805dfa396248a9665cb4a0c85116d0 +0 -0
- data/spec/dummy/tmp/cache/assets/CC1/4E0/sprockets%2F6ef77414c793c84a437244d7d965ba90 +0 -0
- data/spec/dummy/tmp/cache/assets/CC3/B10/sprockets%2F0a2c59284c7a5d99581883a9763b5ad8 +0 -0
- data/spec/dummy/tmp/cache/assets/CC9/940/sprockets%2F8128c279185cf97dba7914278ce838b4 +0 -0
- data/spec/dummy/tmp/cache/assets/CCA/0C0/sprockets%2F6c3e053393afe303432ca73f1b41490b +0 -0
- data/spec/dummy/tmp/cache/assets/CD5/2C0/sprockets%2F166c056119ebdfb8b7104c97b424b423 +0 -0
- data/spec/dummy/tmp/cache/assets/CDB/610/sprockets%2F7adf20860b018477a95cdb8321b49d16 +0 -0
- data/spec/dummy/tmp/cache/assets/CDD/F50/sprockets%2F7353f31f80f1139aade47728a62af336 +0 -0
- data/spec/dummy/tmp/cache/assets/CE9/760/sprockets%2F5ae7fab601683996918936cad21fc244 +0 -0
- data/spec/dummy/tmp/cache/assets/CE9/B90/sprockets%2Fea2eb066933b1d8b5949972c3c79353a +0 -0
- data/spec/dummy/tmp/cache/assets/CF1/AF0/sprockets%2F14dc9633b61024231ebec0c1a4a0259f +0 -0
- data/spec/dummy/tmp/cache/assets/D02/340/sprockets%2Fae58ed66f72137a594b0912bab600e03 +0 -0
- data/spec/dummy/tmp/cache/assets/D0A/AC0/sprockets%2Fc154991d0a7564e15c0fb4a555c5c73d +0 -0
- data/spec/dummy/tmp/cache/assets/D0B/190/sprockets%2F68cb0d1054ca546fc473274c4ac8737c +0 -0
- data/spec/dummy/tmp/cache/assets/D11/530/sprockets%2F13bc8c66140adef2e97648630866aae3 +0 -0
- data/spec/dummy/tmp/cache/assets/D16/AA0/sprockets%2Ff181e659a47e2cf9c257f32d80452bd3 +0 -0
- data/spec/dummy/tmp/cache/assets/D18/840/sprockets%2F50c1885539f61359c48af74fcae1df31 +0 -0
- data/spec/dummy/tmp/cache/assets/D1B/940/sprockets%2F7c4819d1dd9b64a22941d8c7bd1e6954 +0 -0
- data/spec/dummy/tmp/cache/assets/D2B/1F0/sprockets%2F6a4c116e8316d082bb0ffae02e94b107 +0 -0
- data/spec/dummy/tmp/cache/assets/D3C/E20/sprockets%2Ffc6c44ec250bc532c55649e5292b5c1f +0 -0
- data/spec/dummy/tmp/cache/assets/D4B/C30/sprockets%2Fe8aa746e637d69ff0ac1e71e528c5292 +0 -0
- data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/D5A/E20/sprockets%2Febf23d670481ba70b341aa2eb6e37b08 +0 -0
- data/spec/dummy/tmp/cache/assets/D5C/1F0/sprockets%2F2d3f2cfd98bf787168fb59f84ab24784 +0 -0
- data/spec/dummy/tmp/cache/assets/D5D/C60/sprockets%2Ffa0336b42d01aa9173d9d4c12fc4e82d +0 -0
- data/spec/dummy/tmp/cache/assets/D65/DD0/sprockets%2Fed4503679ef66f0e597bfc738bc9e698 +0 -0
- data/spec/dummy/tmp/cache/assets/D68/930/sprockets%2F5a15e52e84502f9fceb7ea04020f65fc +0 -0
- data/spec/dummy/tmp/cache/assets/D8C/140/sprockets%2F2afdbb3902a1be5d2f045cfc837903a3 +0 -0
- data/spec/dummy/tmp/cache/assets/D8E/660/sprockets%2F3a3eed926bdf64000ccacb36022f78d4 +0 -0
- data/spec/dummy/tmp/cache/assets/D95/690/sprockets%2Fe4d19a04705ee5d72c7fa64dc2070ddb +0 -0
- data/spec/dummy/tmp/cache/assets/DA4/EC0/sprockets%2F8da2289e16c1d0cac94aa825ee18d99d +0 -0
- data/spec/dummy/tmp/cache/assets/DA6/120/sprockets%2Fc5880aca76ccbb51f9388362e8afc1e6 +0 -0
- data/spec/dummy/tmp/cache/assets/DA7/390/sprockets%2F25e744cd1b6f8f7ce1d52c1e86a8f19a +0 -0
- data/spec/dummy/tmp/cache/assets/DAB/3E0/sprockets%2F63d2fa621beec4fe878f9eb2884426ab +0 -0
- data/spec/dummy/tmp/cache/assets/DAB/660/sprockets%2F9a8c36769afcc7027b4b6ee0c3e77ce5 +0 -0
- data/spec/dummy/tmp/cache/assets/DBF/EB0/sprockets%2F2afcec323c8ba12a2b7c852f23aa589e +0 -0
- data/spec/dummy/tmp/cache/assets/DCE/9F0/sprockets%2F8fa8c08ea8da97c06cd6c32fe3e613b0 +0 -0
- data/spec/dummy/tmp/cache/assets/DCF/E50/sprockets%2Fc39ff2ed4e1fb4269c39d415acf0d90b +0 -0
- data/spec/dummy/tmp/cache/assets/DD8/0A0/sprockets%2Fb2c3097effcd6084ec75e1f745d1d7dd +0 -0
- data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/DF0/040/sprockets%2F04bbbe1ee5ca914173cd90cf6e8a4e0b +0 -0
- data/spec/dummy/tmp/cache/assets/DF7/C80/sprockets%2Ff503b3666caf04beb7cfe54cbdb0575e +0 -0
- data/spec/dummy/tmp/cache/assets/DFA/B70/sprockets%2F262fb95d3f7cfc16febb0f0128ac38ce +0 -0
- data/spec/dummy/tmp/cache/assets/E03/260/sprockets%2Fd1fcfea59ff53c32557ffcd93016cb2e +0 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/E0A/510/sprockets%2F8efee416ba436e75bea85d4d367faea7 +0 -0
- data/spec/dummy/tmp/cache/assets/E43/810/sprockets%2F79b0ef75ceb26a9c8fca797db3efba96 +0 -0
- data/spec/dummy/tmp/cache/assets/E96/1B0/sprockets%2F6d5fe51f9c1a3d2f898becd0bcddef3e +0 -0
- data/spec/dummy/tmp/cache/assets/ED4/410/sprockets%2F082adbb8e2abd8a21c8b34aebbbfbfad +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/vendor/assets/javascripts/tableling.js +3 -543
- data/vendor/assets/javascripts/tableling/bootstrap.js +230 -0
- data/vendor/assets/javascripts/tableling/core.js +321 -0
- metadata +11 -99
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +0 -78
- data/spec/dummy/tmp/cache/assets/C20/C20/sprockets%2F932e86665765e61017be1015b249d270 +0 -0
- data/spec/dummy/tmp/cache/assets/C98/B70/sprockets%2F64db420a3a172209bf0b734312a4888a +0 -0
- data/spec/dummy/tmp/cache/assets/CC1/B50/sprockets%2F13559b77aaaf524896e427719ef5d354 +0 -0
- data/spec/dummy/tmp/cache/assets/CD4/420/sprockets%2F19b3d492932dc6a59093dfb1aa852101 +0 -0
- data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/CD8/520/sprockets%2F89128ce416ae74c4148c5c1f281e111c +0 -0
- data/spec/dummy/tmp/cache/assets/CDA/600/sprockets%2F98ab7e75433ba5d503533fb00b488c80 +0 -0
- data/spec/dummy/tmp/cache/assets/CE1/0F0/sprockets%2F92d30845fe3923e231cfe7e056a654b4 +0 -0
- data/spec/dummy/tmp/cache/assets/CE2/E70/sprockets%2Fd569808c7b411447dec0137e4d1ee707 +0 -0
- data/spec/dummy/tmp/cache/assets/D0A/780/sprockets%2F3d727e58c55c30009bbaf1462e466d4d +0 -0
- data/spec/dummy/tmp/cache/assets/D21/890/sprockets%2F73f9cd97cac4382d565e7b835709a2e3 +0 -0
- data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/D3A/720/sprockets%2F0e2516c1cac22716289bfc87d5ea9a26 +0 -0
- data/spec/dummy/tmp/cache/assets/D4B/BF0/sprockets%2Fdf124de0072e308f8e157eae77b85d88 +0 -0
- data/spec/dummy/tmp/cache/assets/D54/910/sprockets%2F787b6a4c2386b5edf98f90508b85cc3d +0 -0
- data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/D63/170/sprockets%2Fb5b73c3b0862ee59b701a6819b2aa4cd +0 -0
- data/spec/dummy/tmp/cache/assets/D66/580/sprockets%2Ffe6bb9bb5ef9c54f501650b1365c1b05 +0 -0
- data/spec/dummy/tmp/cache/assets/D6A/F40/sprockets%2F53fdbea64f1803eebb72f426f74110d8 +0 -0
- data/spec/dummy/tmp/cache/assets/D6B/D30/sprockets%2Faeb25572f539ffdbb122e9de1218572a +0 -0
- data/spec/dummy/tmp/cache/assets/D6F/110/sprockets%2F2c8c9177efb7e5be1a7055bb0d44792a +0 -0
- data/spec/dummy/tmp/cache/assets/D76/3F0/sprockets%2Fbb569c97f9cc01af670906b40c6be9e2 +0 -0
- data/spec/dummy/tmp/cache/assets/D81/510/sprockets%2F3e6bd5a2d6d0d88f61f5b616f7d879b5 +0 -0
- data/spec/dummy/tmp/cache/assets/D82/940/sprockets%2F29cd0ae31066baa6f2cb92b5c6305aa2 +0 -0
- data/spec/dummy/tmp/cache/assets/D85/D20/sprockets%2F7f7f398c298ca8a1e812b6c9832bcf6e +0 -0
- data/spec/dummy/tmp/cache/assets/D97/230/sprockets%2F0f46cb65e018de57d2c8b480a0ec5dd3 +0 -0
- data/spec/dummy/tmp/cache/assets/DA1/F00/sprockets%2F7b23e35dd61e9d734a59179e2d2aebea +0 -0
- data/spec/dummy/tmp/cache/assets/DA3/950/sprockets%2F38737f6fa54dbda0dfe3ce4c51710e79 +0 -0
- data/spec/dummy/tmp/cache/assets/DB4/7A0/sprockets%2F900105aaabba7938ce23f1e0aade71e5 +0 -0
- data/spec/dummy/tmp/cache/assets/DB4/F90/sprockets%2Fcf5e68e329cedb58b84f445f2b8e37b5 +0 -0
- data/spec/dummy/tmp/cache/assets/DE2/6D0/sprockets%2Fdcaa7d2b2814413aa75d3ba6ada3c6b5 +0 -0
- data/spec/dummy/tmp/cache/assets/DF0/D60/sprockets%2F5a54a1ecc1db271edfc0727bfcb8d912 +0 -0
- data/spec/dummy/tmp/cache/assets/DFE/E10/sprockets%2F9a19dfdd7eb0bf5262919a0207ecfdbf +0 -0
- data/spec/dummy/tmp/cache/assets/E33/8F0/sprockets%2F4933e07f8ef2da7eb5bee9a6fcac3d41 +0 -0
- data/spec/dummy/tmp/cache/assets/E67/730/sprockets%2Fadd4efdfa7661cc60e8ea63cef1f0f98 +0 -0
- data/vendor/assets/javascripts/tableling.backbone.js +0 -3638
- data/vendor/assets/javascripts/tableling.world.js +0 -14768
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
10135
|
@@ -1,543 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
* Distributed under MIT license
|
5
|
-
* https://github.com/AlphaHydrae/tableling
|
6
|
-
*/
|
7
|
-
Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
8
|
-
|
9
|
-
var Tableling = {
|
10
|
-
version : "0.0.9"
|
11
|
-
};
|
12
|
-
|
13
|
-
// Tableling
|
14
|
-
// ---------
|
15
|
-
//
|
16
|
-
// A tableling table is a Marionette layout which fetches data
|
17
|
-
// from a Backbone collection. It is controlled with an EventAggregator.
|
18
|
-
Tableling.Table = Backbone.Marionette.Layout.extend({
|
19
|
-
|
20
|
-
className: 'tableling',
|
21
|
-
|
22
|
-
// Default table options can be overriden by subclasses.
|
23
|
-
tableling : {
|
24
|
-
page : 1,
|
25
|
-
pageSize : 15
|
26
|
-
},
|
27
|
-
|
28
|
-
initialize : function(options) {
|
29
|
-
options = options || {};
|
30
|
-
|
31
|
-
// Table options can also be overriden for each instance at construction.
|
32
|
-
this.tableling = _.extend(_.clone(this.tableling), this.filterConfig(options));
|
33
|
-
|
34
|
-
// We use an event aggregator to manage the layout and its components.
|
35
|
-
// You can use your own by passing a `vent` option.
|
36
|
-
this.vent = options.vent || new Backbone.Marionette.EventAggregator();
|
37
|
-
|
38
|
-
this.fetchOptions = _.extend(_.clone(this.fetchOptions || {}), options.fetchOptions || {});
|
39
|
-
|
40
|
-
// Components should trigger the `table:update` event to update
|
41
|
-
// the table (e.g. change page size, sort) and fetch the new data.
|
42
|
-
this.vent.on('table:update', this.update, this);
|
43
|
-
|
44
|
-
this.on('render', this.setup, this);
|
45
|
-
},
|
46
|
-
|
47
|
-
// Called once rendering is complete. By default, it updates the table.
|
48
|
-
setup : function() {
|
49
|
-
this.vent.trigger('table:setup', this.filterConfig(this.tableling, true));
|
50
|
-
this.vent.trigger('table:update');
|
51
|
-
},
|
52
|
-
|
53
|
-
// Subclasses must return the Backbone.Collection used to fetch data.
|
54
|
-
getCollection : function() {
|
55
|
-
throw new Error('#getCollection not implemented. It should return the Backbone.Collection instance used to fetch data.');
|
56
|
-
},
|
57
|
-
|
58
|
-
// ### Refreshing the table
|
59
|
-
update : function(config, options) {
|
60
|
-
|
61
|
-
_.each(this.filterConfig(config || {}), _.bind(this.updateValue, this));
|
62
|
-
|
63
|
-
// Set the `refresh` option to false to update the table configuration
|
64
|
-
// without refreshing.
|
65
|
-
if (!options || typeof(options.refresh) == 'undefined' || options.refresh) {
|
66
|
-
this.refresh();
|
67
|
-
}
|
68
|
-
},
|
69
|
-
|
70
|
-
updateValue : function(value, key) {
|
71
|
-
if (value && value.toString().length) {
|
72
|
-
this.tableling[key] = value;
|
73
|
-
} else {
|
74
|
-
// Blank values are deleted to avoid sending them in ajax requests.
|
75
|
-
delete this.tableling[key];
|
76
|
-
}
|
77
|
-
},
|
78
|
-
|
79
|
-
refresh : function() {
|
80
|
-
|
81
|
-
// You can provide `fetchOptions` to add properties to the
|
82
|
-
// fetch request.
|
83
|
-
//
|
84
|
-
// var MyTable = Tableling.Table.extend({
|
85
|
-
// fetchOptions : {
|
86
|
-
// type : 'POST' // fetch data with POST
|
87
|
-
// }
|
88
|
-
// });
|
89
|
-
//
|
90
|
-
// // You can also override for each instance.
|
91
|
-
// new MyTable({
|
92
|
-
// fetchOptions : {
|
93
|
-
// type : 'GET'
|
94
|
-
// }
|
95
|
-
// });
|
96
|
-
var options = _.clone(this.fetchOptions);
|
97
|
-
options.data = this.requestData();
|
98
|
-
options.success = _.bind(this.processResponse, this);
|
99
|
-
|
100
|
-
// `table:refreshing` is triggered every time new data is being fetched.
|
101
|
-
// The first argument is the request data.
|
102
|
-
this.ventTrigger('table:refreshing', options.data);
|
103
|
-
|
104
|
-
this.getCollection().fetch(options);
|
105
|
-
},
|
106
|
-
|
107
|
-
// ### Request
|
108
|
-
requestData : function() {
|
109
|
-
return this.filterConfig(this.tableling);
|
110
|
-
},
|
111
|
-
|
112
|
-
// ### Response
|
113
|
-
processResponse : function(collection, response) {
|
114
|
-
|
115
|
-
this.tableling.length = collection.length;
|
116
|
-
|
117
|
-
// Tableling expects the response from a fetch to have a `total` property
|
118
|
-
// which is the total number of items (not just in the current page).
|
119
|
-
this.tableling.total = response.total;
|
120
|
-
|
121
|
-
// `tableling:refreshed` is triggered after every refresh. The first argument
|
122
|
-
// is the current table configuration with the following additional meta data:
|
123
|
-
//
|
124
|
-
// * `total` - the total number of items
|
125
|
-
// * `length` - the number of items in the current page
|
126
|
-
this.ventTrigger('table:refreshed', this.filterConfig(this.tableling, true));
|
127
|
-
},
|
128
|
-
|
129
|
-
// ### Utilities
|
130
|
-
// Whitelists the given configuration to contain only table configuration properties.
|
131
|
-
// Pass `true` as the second argument to include meta data (i.e. total & length).
|
132
|
-
filterConfig : function(config, all) {
|
133
|
-
if (all) {
|
134
|
-
return _.pick(config, 'page', 'pageSize', 'quickSearch', 'sort', 'length', 'total');
|
135
|
-
} else {
|
136
|
-
return _.pick(config, 'page', 'pageSize', 'quickSearch', 'sort');
|
137
|
-
}
|
138
|
-
},
|
139
|
-
|
140
|
-
// Triggers an event in the event aggregator. If `Tableling.debug` is set, it also
|
141
|
-
// logs the event and its arguments.
|
142
|
-
ventTrigger : function() {
|
143
|
-
|
144
|
-
var args = Array.prototype.slice.call(arguments);
|
145
|
-
this.vent.trigger.apply(this.vent, args);
|
146
|
-
|
147
|
-
if (Tableling.debug) {
|
148
|
-
console.log(args.shift() + ' - ' + JSON.stringify(args));
|
149
|
-
}
|
150
|
-
}
|
151
|
-
});
|
152
|
-
|
153
|
-
// Tableling.Collection
|
154
|
-
// --------------------
|
155
|
-
//
|
156
|
-
// Tableling expects fetch responses to have a `total` property in addition
|
157
|
-
// to the model data. You can extend this Backbone.Collection subclass which
|
158
|
-
// expects the following response format:
|
159
|
-
//
|
160
|
-
// {
|
161
|
-
// "total": 12,
|
162
|
-
// "data": [
|
163
|
-
// { /* ... model data ... */ },
|
164
|
-
// { /* ... model data ... */ }
|
165
|
-
// ]
|
166
|
-
// }
|
167
|
-
Tableling.Collection = Backbone.Collection.extend({
|
168
|
-
|
169
|
-
parse : function(response) {
|
170
|
-
return response.data;
|
171
|
-
}
|
172
|
-
});
|
173
|
-
|
174
|
-
// Implementations
|
175
|
-
// ---------------
|
176
|
-
//
|
177
|
-
// <a href="tableling.bootstrap.html">tableling.bootstrap</a> provides views styled
|
178
|
-
// with [Twitter Bootstrap](http://twitter.github.com/bootstrap/) classes.
|
179
|
-
|
180
|
-
// Tableling.Modular
|
181
|
-
// -----------------
|
182
|
-
//
|
183
|
-
// Tableling subclass which splits functionality into *modules*
|
184
|
-
// and handles rendering.
|
185
|
-
Tableling.Modular = Tableling.Table.extend({
|
186
|
-
|
187
|
-
// The list of module names must be specified by subclasses.
|
188
|
-
modules : [],
|
189
|
-
|
190
|
-
// Modules are set up after rendering, before refreshing.
|
191
|
-
setup : function() {
|
192
|
-
|
193
|
-
this.moduleViews = {};
|
194
|
-
_.each(this.modules, _.bind(this.setupModule, this));
|
195
|
-
|
196
|
-
Tableling.Table.prototype.setup.call(this);
|
197
|
-
},
|
198
|
-
|
199
|
-
// ### Modules
|
200
|
-
// Each module is identified by a name, for example `pageSize`.
|
201
|
-
setupModule : function(name) {
|
202
|
-
|
203
|
-
// The layout must have a region named after the module, e.g. `pageSizeRegion`.
|
204
|
-
var region = name + 'Region';
|
205
|
-
|
206
|
-
// It must have a view class, e.g. `pageSizeView`, which will be shown into
|
207
|
-
// the region.
|
208
|
-
var viewClass = this[name + 'View'];
|
209
|
-
|
210
|
-
// When instantiated, the view class will be passed the event
|
211
|
-
// aggregator as the `vent` option. Additional options can be
|
212
|
-
// given named after the view class, e.g. `pageSizeViewOptions`.
|
213
|
-
var options = _.extend(this[name + 'ViewOptions'] || {}, { vent: this.vent });
|
214
|
-
|
215
|
-
var view = new viewClass(options);
|
216
|
-
|
217
|
-
// Module view instances are stored by name in the `moduleViews` property
|
218
|
-
// for future reference.
|
219
|
-
this.moduleViews[name] = view;
|
220
|
-
|
221
|
-
this[region].show(view);
|
222
|
-
return view;
|
223
|
-
},
|
224
|
-
|
225
|
-
// By default, a modular table expects a `table` module which
|
226
|
-
// should have a collection (e.g. a Marionette CompositeView or
|
227
|
-
// CollectionView). If your subclass does not have that, it
|
228
|
-
// should override this method to return the Backbone.Collection
|
229
|
-
// used to fetch table data.
|
230
|
-
getCollection : function() {
|
231
|
-
return this.moduleViews.table.collection;
|
232
|
-
}
|
233
|
-
});
|
234
|
-
|
235
|
-
// ### Example
|
236
|
-
// This is how a `PageSizeView` module might be registered in a subclass:
|
237
|
-
//
|
238
|
-
// var MyTable = Tableling.Modular.extend({
|
239
|
-
//
|
240
|
-
// modules : [ 'pageSize' ],
|
241
|
-
//
|
242
|
-
// pageSizeView : PageSizeView,
|
243
|
-
// pageSizeViewOptions : {
|
244
|
-
// itemView : PageSizeItem
|
245
|
-
// },
|
246
|
-
//
|
247
|
-
// regions : {
|
248
|
-
// pageSizeRegion : '.pageSize'
|
249
|
-
// }
|
250
|
-
// });
|
251
|
-
|
252
|
-
// Tableling.Module
|
253
|
-
// ----------------
|
254
|
-
//
|
255
|
-
// A module is an item view that is automatically bound to the table's
|
256
|
-
// event aggregator.
|
257
|
-
Tableling.Module = Backbone.Marionette.ItemView.extend({
|
258
|
-
|
259
|
-
initialize : function(options) {
|
260
|
-
this.vent = options.vent;
|
261
|
-
|
262
|
-
// The `refresh` method of the view is called once the view is rendered
|
263
|
-
// and every time the table is refreshed.
|
264
|
-
this.vent.on('table:refreshed', this.refresh, this);
|
265
|
-
this.on('render', this.refresh, this);
|
266
|
-
},
|
267
|
-
|
268
|
-
// Call `update` to trigger an update of the table.
|
269
|
-
update : function() {
|
270
|
-
this.vent.trigger('table:update', this.config());
|
271
|
-
},
|
272
|
-
|
273
|
-
// Implementations should override this to stay up to date with
|
274
|
-
// the table state. Note that the data parameter will be undefined
|
275
|
-
// on the first refresh when the view is rendered.
|
276
|
-
refresh : function(data) {
|
277
|
-
},
|
278
|
-
|
279
|
-
// New table configuration to be sent on updates. For example,
|
280
|
-
// a page size view might update the `pageSize` property.
|
281
|
-
config : function() {
|
282
|
-
return {};
|
283
|
-
}
|
284
|
-
});
|
285
|
-
|
286
|
-
// Tableling.FieldModule
|
287
|
-
// ---------------------
|
288
|
-
//
|
289
|
-
// A basic module with a single form field. It comes with sensible
|
290
|
-
// defaults and only requires a `name` and a `template` parameter.
|
291
|
-
Tableling.FieldModule = Tableling.Module.extend({
|
292
|
-
|
293
|
-
initialize : function(options) {
|
294
|
-
|
295
|
-
Tableling.Module.prototype.initialize.call(this, options);
|
296
|
-
|
297
|
-
if (!this.ui) {
|
298
|
-
this.ui = {};
|
299
|
-
}
|
300
|
-
// The name attribute of the form field is the same as the
|
301
|
-
// module's, e.g. `pageSize`.
|
302
|
-
this.ui.field = '[name="' + this.name + '"]';
|
303
|
-
|
304
|
-
if (!this.events) {
|
305
|
-
this.events = {};
|
306
|
-
}
|
307
|
-
this.events['change [name="' + this.name + '"]'] = 'update';
|
308
|
-
},
|
309
|
-
|
310
|
-
// The table property updated is the one with the same name as the module.
|
311
|
-
config : function() {
|
312
|
-
var config = {};
|
313
|
-
config[this.name] = this.ui.field.val();
|
314
|
-
return config;
|
315
|
-
}
|
316
|
-
});
|
317
|
-
|
318
|
-
// This is how a `PageSizeView` module might be implemented:
|
319
|
-
//
|
320
|
-
// var html = '<input type="text" name="pageSize" />';
|
321
|
-
//
|
322
|
-
// var PageSizeView = Tableling.FieldModule.extend({
|
323
|
-
// name : 'pageSize'
|
324
|
-
// template : _.template(html)
|
325
|
-
// });
|
326
|
-
//
|
327
|
-
// When the value of the input field changes, the event aggregator will
|
328
|
-
// receive a `tableling:update` event with the `pageSize` property set
|
329
|
-
// to that value.
|
330
|
-
|
331
|
-
Tableling.Plain = {};
|
332
|
-
|
333
|
-
Tableling.Plain.Table = Tableling.Modular.extend({
|
334
|
-
|
335
|
-
className: 'tableling',
|
336
|
-
modules : [ 'table', 'pageSize', 'quickSearch', 'info', 'pagination' ],
|
337
|
-
template : _.template('<div class="header"><div class="pageSize" /><div class="quickSearch" /></div><div class="table" /><div class="footer"><div class="info" /><div class="pagination" /></div>'),
|
338
|
-
|
339
|
-
regions : {
|
340
|
-
tableRegion : '.table',
|
341
|
-
pageSizeRegion : '.pageSize',
|
342
|
-
quickSearchRegion : '.quickSearch',
|
343
|
-
infoRegion : '.info',
|
344
|
-
paginationRegion : '.pagination'
|
345
|
-
}
|
346
|
-
});
|
347
|
-
|
348
|
-
Tableling.Plain.TableView = Backbone.Marionette.CompositeView.extend({
|
349
|
-
|
350
|
-
events : {
|
351
|
-
'click thead th' : 'updateSort'
|
352
|
-
},
|
353
|
-
|
354
|
-
initialize : function(options) {
|
355
|
-
// TODO: add auto-sort
|
356
|
-
this.vent = options.vent;
|
357
|
-
this.sort = [];
|
358
|
-
},
|
359
|
-
|
360
|
-
updateSort : function(ev) {
|
361
|
-
|
362
|
-
var el = $(ev.currentTarget);
|
363
|
-
if (!(el.hasClass('sorting') || el.hasClass('sorting-asc') || el.hasClass('sorting-desc'))) {
|
364
|
-
return;
|
365
|
-
}
|
366
|
-
|
367
|
-
var field = this.fieldName(el);
|
368
|
-
|
369
|
-
if (ev.shiftKey || this.sort.length == 1) {
|
370
|
-
|
371
|
-
var existing = _.find(this.sort, function(item) {
|
372
|
-
return item.field == field;
|
373
|
-
});
|
374
|
-
|
375
|
-
if (existing) {
|
376
|
-
existing.direction = existing.direction == 'asc' ? 'desc' : 'asc';
|
377
|
-
el.removeClass('sorting sorting-asc sorting-desc');
|
378
|
-
el.addClass('sorting-' + existing.direction);
|
379
|
-
return this.vent.trigger('table:update', this.config());
|
380
|
-
}
|
381
|
-
}
|
382
|
-
|
383
|
-
if (!ev.shiftKey) {
|
384
|
-
this.sort.length = 0;
|
385
|
-
this.$el.find('thead th').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
386
|
-
}
|
387
|
-
|
388
|
-
this.sort.push({
|
389
|
-
field: field,
|
390
|
-
direction: 'asc'
|
391
|
-
});
|
392
|
-
|
393
|
-
el.removeClass('sorting sorting-asc sorting-desc').addClass('sorting-asc');
|
394
|
-
|
395
|
-
this.vent.trigger('table:update', this.config());
|
396
|
-
},
|
397
|
-
|
398
|
-
config : function() {
|
399
|
-
return {
|
400
|
-
page : 1,
|
401
|
-
sort : this.sortConfig()
|
402
|
-
};
|
403
|
-
},
|
404
|
-
|
405
|
-
sortConfig : function() {
|
406
|
-
if (!this.sort.length) {
|
407
|
-
return null;
|
408
|
-
}
|
409
|
-
return _.map(this.sort, function(item) {
|
410
|
-
return item.field + ' ' + item.direction;
|
411
|
-
});
|
412
|
-
},
|
413
|
-
|
414
|
-
fieldName : function(el) {
|
415
|
-
return el.data('field') || el.text().toLowerCase();
|
416
|
-
}
|
417
|
-
});
|
418
|
-
|
419
|
-
Tableling.Plain.PageSizeView = Tableling.Plain.Table.prototype.pageSizeView = Tableling.FieldModule.extend({
|
420
|
-
// TODO: update current page intelligently
|
421
|
-
name : 'pageSize',
|
422
|
-
template : _.template('<select name="pageSize"><option>5</option><option>10</option><option>15</option></select> entries per page')
|
423
|
-
});
|
424
|
-
|
425
|
-
Tableling.Plain.QuickSearchView = Tableling.Plain.Table.prototype.quickSearchView = Tableling.FieldModule.extend({
|
426
|
-
name : 'quickSearch',
|
427
|
-
template : _.template('<input type="text" name="quickSearch" placeholder="Quick search..." />')
|
428
|
-
});
|
429
|
-
|
430
|
-
Tableling.Plain.InfoView = Tableling.Plain.Table.prototype.infoView = Tableling.Module.extend({
|
431
|
-
|
432
|
-
template : _.template('Showing <span class="first">0</span> to <span class="last">0</span> of <span class="total">0</span> entries'),
|
433
|
-
|
434
|
-
ui : {
|
435
|
-
first: '.first',
|
436
|
-
last: '.last',
|
437
|
-
total: '.total'
|
438
|
-
},
|
439
|
-
|
440
|
-
refresh : function(data) {
|
441
|
-
if (data) {
|
442
|
-
this.ui.first.text(this.firstRecord(data));
|
443
|
-
this.ui.last.text(this.lastRecord(data));
|
444
|
-
this.ui.total.text(data.total);
|
445
|
-
}
|
446
|
-
},
|
447
|
-
|
448
|
-
firstRecord : function(data) {
|
449
|
-
return data.length ? (data.page - 1) * data.pageSize + 1 : 0;
|
450
|
-
},
|
451
|
-
|
452
|
-
lastRecord : function(data) {
|
453
|
-
return data.length ? this.firstRecord(data) + data.length - 1 : 0;
|
454
|
-
}
|
455
|
-
});
|
456
|
-
|
457
|
-
Tableling.Plain.PaginationView = Tableling.Plain.Table.prototype.paginationView = Tableling.Module.extend({
|
458
|
-
|
459
|
-
template : _.template('<div class="pagination"><ul><li class="first"><a href="#"><<</a></li><li class="previous"><a href="#"><</a></li><li class="next"><a href="#">></a></li><li class="last"><a href="#">>></a></li></ul></div>'),
|
460
|
-
|
461
|
-
ui : {
|
462
|
-
first : '.first',
|
463
|
-
previous : '.previous',
|
464
|
-
next : '.next',
|
465
|
-
last : '.last'
|
466
|
-
},
|
467
|
-
|
468
|
-
events : {
|
469
|
-
'click .first:not(.disabled)' : 'goToFirstPage',
|
470
|
-
'click .previous:not(.disabled)' : 'goToPreviousPage',
|
471
|
-
'click .next:not(.disabled)' : 'goToNextPage',
|
472
|
-
'click .last:not(.disabled)' : 'goToLastPage'
|
473
|
-
},
|
474
|
-
|
475
|
-
refresh : function(data) {
|
476
|
-
if (!data) {
|
477
|
-
this.ui.first.addClass('disabled');
|
478
|
-
this.ui.previous.addClass('disabled');
|
479
|
-
this.ui.next.addClass('disabled');
|
480
|
-
this.ui.last.addClass('disabled');
|
481
|
-
} else {
|
482
|
-
this.data = data;
|
483
|
-
this.enable(this.ui.first, data.page > 1);
|
484
|
-
this.enable(this.ui.previous, data.page > 1);
|
485
|
-
this.enable(this.ui.next, data.page < this.numberOfPages(data));
|
486
|
-
this.enable(this.ui.last, data.page < this.numberOfPages(data));
|
487
|
-
}
|
488
|
-
},
|
489
|
-
|
490
|
-
enable : function(el, enabled) {
|
491
|
-
el.removeClass('disabled');
|
492
|
-
if (!enabled) {
|
493
|
-
el.addClass('disabled');
|
494
|
-
}
|
495
|
-
},
|
496
|
-
|
497
|
-
numberOfPages : function() {
|
498
|
-
return Math.ceil(this.data.total / this.data.pageSize);
|
499
|
-
},
|
500
|
-
|
501
|
-
goToFirstPage : function() {
|
502
|
-
this.goToPage(1);
|
503
|
-
},
|
504
|
-
|
505
|
-
goToPreviousPage : function() {
|
506
|
-
this.goToPage(this.data.page - 1);
|
507
|
-
},
|
508
|
-
|
509
|
-
goToNextPage : function() {
|
510
|
-
this.goToPage(this.data.page + 1);
|
511
|
-
},
|
512
|
-
|
513
|
-
goToLastPage : function() {
|
514
|
-
this.goToPage(this.numberOfPages());
|
515
|
-
},
|
516
|
-
|
517
|
-
goToPage : function(n) {
|
518
|
-
this.vent.trigger('table:update', { page : n });
|
519
|
-
}
|
520
|
-
});
|
521
|
-
|
522
|
-
Tableling.Bootstrap = {};
|
523
|
-
|
524
|
-
Tableling.Bootstrap.Table = Tableling.Plain.Table.extend({
|
525
|
-
template : _.template('<div class="header"><div class="pageSize pull-left" /><div class="quickSearch pull-right" /></div><div class="table" /><div class="footer"><div class="info pull-left" /><div class="pagination pull-right" /></div>')
|
526
|
-
});
|
527
|
-
|
528
|
-
Tableling.Bootstrap.TableView = Tableling.Plain.TableView.extend({});
|
529
|
-
|
530
|
-
Tableling.Bootstrap.PageSizeView = Tableling.Bootstrap.Table.prototype.pageSizeView = Tableling.Plain.PageSizeView.extend({
|
531
|
-
template : _.template('<select name="pageSize" class="input-mini"><option>5</option><option>10</option><option>15</option></select> entries per page')
|
532
|
-
});
|
533
|
-
|
534
|
-
Tableling.Bootstrap.QuickSearchView = Tableling.Bootstrap.Table.prototype.quickSearchView = Tableling.Plain.QuickSearchView.extend({});
|
535
|
-
|
536
|
-
Tableling.Bootstrap.InfoView = Tableling.Bootstrap.Table.prototype.infoView = Tableling.Plain.InfoView.extend({});
|
537
|
-
|
538
|
-
Tableling.Bootstrap.PaginationView = Tableling.Bootstrap.Table.prototype.paginationView = Tableling.Plain.PaginationView.extend({});
|
539
|
-
|
540
|
-
|
541
|
-
return Tableling;
|
542
|
-
|
543
|
-
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|
1
|
+
// Only the <a href="tableling/core.html">core</a> functionality is required by default.
|
2
|
+
//
|
3
|
+
//= require tableling/core
|