ezframe 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +11 -4
- data/app_template/asset/image/favicon.ico +0 -0
- data/app_template/asset/js/ezframe.js +288 -0
- data/app_template/config/generic.yml +3 -0
- data/app_template/config/materialize.yml +5 -0
- data/{example/chat → app_template}/config.ru +2 -10
- data/app_template/pages/basic.rb +5 -0
- data/exe/create_table.rb +1 -0
- data/exe/setup.rb +15 -0
- data/ezframe.gemspec +3 -4
- data/lib/ezframe/auth.rb +15 -12
- data/lib/ezframe/column_set.rb +68 -28
- data/lib/ezframe/column_type.rb +231 -68
- data/lib/ezframe/config.rb +4 -0
- data/lib/ezframe/controller.rb +20 -10
- data/lib/ezframe/database.rb +10 -3
- data/lib/ezframe/ht.rb +167 -0
- data/lib/ezframe/html.rb +28 -4
- data/lib/ezframe/japanese_utils.rb +40 -0
- data/lib/ezframe/{pages.rb → loader.rb} +3 -0
- data/lib/ezframe/materialize.rb +55 -20
- data/lib/ezframe/model.rb +0 -2
- data/lib/ezframe/page_base.rb +18 -12
- data/lib/ezframe/page_kit.rb +12 -33
- data/lib/ezframe/template.rb +20 -15
- data/lib/ezframe/util.rb +5 -0
- data/lib/ezframe/version.rb +1 -1
- data/lib/ezframe.rb +5 -4
- metadata +27 -70
- data/example/auth/Gemfile +0 -8
- data/example/auth/asset/css/materialize.min.css +0 -13
- data/example/auth/asset/js/common.js +0 -200
- data/example/auth/asset/js/htmlgen.js +0 -79
- data/example/auth/columns/user.yml +0 -12
- data/example/auth/config/view_conf.yml +0 -3
- data/example/auth/config.ru +0 -26
- data/example/auth/pages/app.rb +0 -61
- data/example/auth/template/base.html +0 -12
- data/example/chat/Gemfile +0 -9
- data/example/chat/asset/css/materialize.min.css +0 -13
- data/example/chat/asset/js/common.js +0 -200
- data/example/chat/asset/js/htmlgen.js +0 -79
- data/example/chat/columns/belong.yml +0 -6
- data/example/chat/columns/channel.yml +0 -3
- data/example/chat/columns/talk.yml +0 -6
- data/example/chat/columns/user.yml +0 -12
- data/example/chat/config/view_conf.yml +0 -3
- data/example/chat/pages/app.rb +0 -59
- data/example/chat/template/base.html +0 -12
- data/example/todo/Gemfile +0 -8
- data/example/todo/asset/css/datatable.css +0 -54
- data/example/todo/asset/css/materialize.min.css +0 -13
- data/example/todo/asset/js/common.js +0 -135
- data/example/todo/asset/js/datatable.js +0 -1814
- data/example/todo/asset/js/htmlgen.js +0 -79
- data/example/todo/asset/js/init.js +0 -3
- data/example/todo/asset/js/materialize.min.js +0 -6
- data/example/todo/asset/js/mydatatable.js +0 -9
- data/example/todo/asset/js/mymaterialize.js +0 -22
- data/example/todo/columns/todo.yml +0 -9
- data/example/todo/config/view_conf.yml +0 -3
- data/example/todo/config.ru +0 -15
- data/example/todo/pages/app.rb +0 -93
- data/example/todo/template/base.html +0 -12
- data/exe/myrackup +0 -5
- data/lib/ezframe/hthash.rb +0 -116
@@ -1,1814 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
var DataTable = function (table, opts) {
|
4
|
-
|
5
|
-
this.options = {};
|
6
|
-
this.table = table;
|
7
|
-
this.currentPage = 0;
|
8
|
-
this.currentStart = 0; // different from currentPage * pageSize because there is a filter
|
9
|
-
this.filterIndex = [];
|
10
|
-
|
11
|
-
for (var k in DataTable.defaultOptions) {
|
12
|
-
if (DataTable.defaultOptions.hasOwnProperty(k)) {
|
13
|
-
if (opts.hasOwnProperty(k)) {
|
14
|
-
this.options[k] = opts[k] ;
|
15
|
-
}
|
16
|
-
else {
|
17
|
-
this.options[k] = DataTable.defaultOptions[k] ;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
|
22
|
-
if (opts.hasOwnProperty('data')) {
|
23
|
-
this.options.data = opts.data ;
|
24
|
-
}
|
25
|
-
|
26
|
-
/* If nb columns not specified, count the number of column from thead. */
|
27
|
-
if (this.options.nbColumns < 0) {
|
28
|
-
this.options.nbColumns = this.table.tHead.rows[0].cells.length;
|
29
|
-
}
|
30
|
-
|
31
|
-
/* Create the base for pagination. */
|
32
|
-
this.pagingDivs = document.querySelectorAll(this.options.pagingDivSelector);
|
33
|
-
for (var i = 0; i < this.pagingDivs.length; ++i) {
|
34
|
-
var div = this.pagingDivs[i];
|
35
|
-
this.addClass(div, 'pagination-datatables');
|
36
|
-
this.addClass(div, this.options.pagingDivClass);
|
37
|
-
var ul = document.createElement('ul');
|
38
|
-
this.addClass(ul, this.options.pagingListClass);
|
39
|
-
div.appendChild(ul);
|
40
|
-
}
|
41
|
-
this.pagingLists = document.querySelectorAll(this.options.pagingDivSelector + ' ul');
|
42
|
-
this.counterDivs = document.querySelectorAll(this.options.counterDivSelector);
|
43
|
-
this.loadingDiv = document.querySelector(this.options.loadingDivSelector);
|
44
|
-
|
45
|
-
/* DATA ! */
|
46
|
-
|
47
|
-
var dataTable = this;
|
48
|
-
|
49
|
-
if (!this.table.tHead) {
|
50
|
-
this.table.tHead = document.createElement('thead');
|
51
|
-
this.table.appendChild(this.table.rows[0]);
|
52
|
-
}
|
53
|
-
|
54
|
-
/* Compatibility issue (forceStrings => No defined data types). */
|
55
|
-
if (this.options.forceStrings) {
|
56
|
-
this.options.dataTypes = false ;
|
57
|
-
}
|
58
|
-
|
59
|
-
var ths = this.table.tHead.rows[0].cells ;
|
60
|
-
|
61
|
-
if (!this.table.tBodies[0]) {
|
62
|
-
this.table.tBodies[0] = document.createElement('tbody');
|
63
|
-
}
|
64
|
-
|
65
|
-
if (this.options.data instanceof Array) {
|
66
|
-
this.data = this.options.data;
|
67
|
-
}
|
68
|
-
else if (this.options.data instanceof Object) {
|
69
|
-
var ajaxOptions = DataTable.defaultAjaxOptions;
|
70
|
-
for (var k in this.options.data) {
|
71
|
-
ajaxOptions[k] = this.options.data[k];
|
72
|
-
}
|
73
|
-
this.options.data = ajaxOptions;
|
74
|
-
var fetchData = true;
|
75
|
-
if (fetchData) {
|
76
|
-
if (this.table.dataset.size !== undefined) {
|
77
|
-
this.options.data.size = parseInt(this.table.dataset.size, 10);
|
78
|
-
}
|
79
|
-
this.data = [];
|
80
|
-
if (this.options.data.size !== undefined) {
|
81
|
-
this.loadingDiv.innerHTML = '<div class="progress datatable-load-bar">'
|
82
|
-
+ '<div class="progress-bar progress-bar-striped active" style="width: 0%;">'
|
83
|
-
+ '</div></div>';
|
84
|
-
if (this.options.data.allInOne) {
|
85
|
-
this.getAjaxDataAsync(true);
|
86
|
-
}
|
87
|
-
else {
|
88
|
-
for (var i = 0; i < this.options.data.size;
|
89
|
-
i += this.options.pageSize * this.options.pagingNumberOfPages) {
|
90
|
-
this.getAjaxDataAsync(i);
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
94
|
-
else {
|
95
|
-
this.loadingDiv.innerHTML = '<div class="progress datatable-load-bar">'
|
96
|
-
+ '<div class="progress-bar progress-bar-striped active" style="width: 0%;">'
|
97
|
-
+ '</div></div>';
|
98
|
-
this.getAjaxDataAsync(0, true);
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
else if (this.table.tBodies[0].rows.length > 0) {
|
103
|
-
this.data = [];
|
104
|
-
var rows = this.table.tBodies[0].rows;
|
105
|
-
var nCols = rows[0].cells.length ;
|
106
|
-
for (var i = 0; i < rows.length; ++i) {
|
107
|
-
this.data.push ([]) ;
|
108
|
-
}
|
109
|
-
for (var j = 0 ; j < nCols ; ++j) {
|
110
|
-
var dt = function (x) { return x ; } ;
|
111
|
-
if (this.options.dataTypes instanceof Array) {
|
112
|
-
switch (this.options.dataTypes[j]) {
|
113
|
-
case 'int':
|
114
|
-
dt = parseInt ;
|
115
|
-
break ;
|
116
|
-
case 'float':
|
117
|
-
case 'double':
|
118
|
-
dt = parseFloat ;
|
119
|
-
break ;
|
120
|
-
case 'date':
|
121
|
-
case 'datetime':
|
122
|
-
dt = function (x) { return new Date(x) ; } ;
|
123
|
-
break ;
|
124
|
-
case false:
|
125
|
-
case true:
|
126
|
-
case 'string':
|
127
|
-
case 'str':
|
128
|
-
dt = function (x) { return x ; } ;
|
129
|
-
break ;
|
130
|
-
default:
|
131
|
-
dt = this.options.dataTypes[j] ;
|
132
|
-
}
|
133
|
-
}
|
134
|
-
for (var i = 0; i < rows.length; ++i) {
|
135
|
-
this.data[i].push(dt(rows[i].cells[j].innerHTML.trim())) ;
|
136
|
-
}
|
137
|
-
}
|
138
|
-
if (this.options.dataTypes === true) {
|
139
|
-
for (var c = 0; c < this.data[0].length; ++c) {
|
140
|
-
var isNumeric = true;
|
141
|
-
for (var i = 0; i < this.data.length; ++i) {
|
142
|
-
if (this.data[i][c] !== ""
|
143
|
-
&& !((this.data[i][c] - parseFloat(this.data[i][c]) + 1) >= 0)) {
|
144
|
-
isNumeric = false;
|
145
|
-
}
|
146
|
-
}
|
147
|
-
if (isNumeric) {
|
148
|
-
for (var i = 0; i < this.data.length; ++i) {
|
149
|
-
if (this.data[i][c] !== "") {
|
150
|
-
this.data[i][c] = parseFloat(this.data[i][c]);
|
151
|
-
}
|
152
|
-
}
|
153
|
-
}
|
154
|
-
}
|
155
|
-
}
|
156
|
-
}
|
157
|
-
|
158
|
-
/* Add sorting class to all th and add callback. */
|
159
|
-
this.createSort();
|
160
|
-
|
161
|
-
/* Add filter where it's needed. */
|
162
|
-
this.createFilter();
|
163
|
-
|
164
|
-
this.triggerSort();
|
165
|
-
this.filter();
|
166
|
-
|
167
|
-
};
|
168
|
-
|
169
|
-
DataTable.prototype = {
|
170
|
-
|
171
|
-
constructor: DataTable,
|
172
|
-
|
173
|
-
/**
|
174
|
-
*
|
175
|
-
* Add the specified class(es) to the specified DOM Element.
|
176
|
-
*
|
177
|
-
* @param node The DOM Element
|
178
|
-
* @param classes (Array or String)
|
179
|
-
*
|
180
|
-
**/
|
181
|
-
addClass: function (node, classes) {
|
182
|
-
if (typeof classes === "string") {
|
183
|
-
classes = classes.split(' ');
|
184
|
-
}
|
185
|
-
classes.forEach(function (c) {
|
186
|
-
if (!c) { return; }
|
187
|
-
node.classList.add(c);
|
188
|
-
});
|
189
|
-
},
|
190
|
-
|
191
|
-
/**
|
192
|
-
*
|
193
|
-
* Remove the specified node from the DOM.
|
194
|
-
*
|
195
|
-
* @param node The node to removes
|
196
|
-
*
|
197
|
-
**/
|
198
|
-
removeNode: function (node) {
|
199
|
-
if (node) {
|
200
|
-
node.parentNode.removeChild(node);
|
201
|
-
}
|
202
|
-
},
|
203
|
-
|
204
|
-
/**
|
205
|
-
*
|
206
|
-
* Clear size option and set timeout (if specified) for refresh.
|
207
|
-
*
|
208
|
-
* Note: This function should be call when a ajax loading is finished.
|
209
|
-
*
|
210
|
-
* @update refreshTimeOut The new timeout
|
211
|
-
*
|
212
|
-
**/
|
213
|
-
setRefreshTimeout: function () {
|
214
|
-
if (this.options.data.refresh) {
|
215
|
-
clearTimeout(this.refreshTimeOut);
|
216
|
-
this.refreshTimeOut = setTimeout((function (datatable) {
|
217
|
-
return function () { datatable.getAjaxDataAsync(0, true); };
|
218
|
-
})(this), this.options.data.refresh);
|
219
|
-
}
|
220
|
-
},
|
221
|
-
|
222
|
-
/**
|
223
|
-
*
|
224
|
-
* Hide the loading divs.
|
225
|
-
*
|
226
|
-
**/
|
227
|
-
hideLoadingDivs: function () {
|
228
|
-
this.removeNode(this.loadingDiv);
|
229
|
-
},
|
230
|
-
|
231
|
-
|
232
|
-
/**
|
233
|
-
*
|
234
|
-
* Update the loading divs with the current % of data load (according
|
235
|
-
* to this.options.data.size).
|
236
|
-
*
|
237
|
-
* Note: Call setRefreshTimeout & hideLoadingDivs if all the data have been loaded.
|
238
|
-
*
|
239
|
-
**/
|
240
|
-
updateLoadingDivs: function () {
|
241
|
-
if (this.data.length >= this.options.data.size) {
|
242
|
-
this.setRefreshTimeout();
|
243
|
-
this.hideLoadingDivs();
|
244
|
-
}
|
245
|
-
else {
|
246
|
-
this.loadingDiv.querySelector('div.progress .progress-bar').style.width =
|
247
|
-
parseInt(100 * this.data.length / this.options.data.size, 10) + '%';
|
248
|
-
}
|
249
|
-
},
|
250
|
-
|
251
|
-
/**
|
252
|
-
*
|
253
|
-
* Get data according to this.options.data, asynchronously, using recursivity.
|
254
|
-
*
|
255
|
-
* @param start The first offset to send to the server
|
256
|
-
*
|
257
|
-
* @update data Concat data received from server to old data
|
258
|
-
*
|
259
|
-
* Note: Each call increment start by pageSize * pagingNumberOfPages.
|
260
|
-
*
|
261
|
-
**/
|
262
|
-
getAjaxDataAsync: function (start, recursive) {
|
263
|
-
if (typeof recursive === "undefined") { recursive = false; }
|
264
|
-
if (recursive && typeof this.syncData === "undefined") {
|
265
|
-
this.syncData = {
|
266
|
-
data: [],
|
267
|
-
toAdd: [],
|
268
|
-
toUpdate: {},
|
269
|
-
toDelete: []
|
270
|
-
};
|
271
|
-
}
|
272
|
-
var xhr = new XMLHttpRequest();
|
273
|
-
xhr.timeout = this.options.data.timeout;
|
274
|
-
xhr.onreadystatechange = function (datatable, start, recursive) {
|
275
|
-
return function () {
|
276
|
-
if (this.readyState == 4) {
|
277
|
-
switch (this.status) {
|
278
|
-
case 200:
|
279
|
-
if (recursive) {
|
280
|
-
if (this.response.length > 0) {
|
281
|
-
datatable.syncData.data =
|
282
|
-
datatable.syncData.data.concat(this.response);
|
283
|
-
datatable.getAjaxDataAsync(start + datatable.options.pageSize * datatable.options.pagingNumberOfPages, true);
|
284
|
-
}
|
285
|
-
else {
|
286
|
-
var syncData = datatable.syncData;
|
287
|
-
delete datatable.syncData;
|
288
|
-
datatable.data = syncData.data;
|
289
|
-
datatable.addRows(syncData.toAdd);
|
290
|
-
syncData.toDelete.forEach(function (e) {
|
291
|
-
if (e instanceof Function) {
|
292
|
-
datatable.deleteAll(e);
|
293
|
-
}
|
294
|
-
else {
|
295
|
-
datatable.deleteRow(e);
|
296
|
-
}
|
297
|
-
});
|
298
|
-
for (var id in syncData.toUpdate) {
|
299
|
-
datatable.updateRow(id, syncData.toUpdate[id]);
|
300
|
-
}
|
301
|
-
|
302
|
-
datatable.sort(true);
|
303
|
-
datatable.setRefreshTimeout();
|
304
|
-
}
|
305
|
-
}
|
306
|
-
else {
|
307
|
-
datatable.data = datatable.data.concat(this.response);
|
308
|
-
datatable.updateLoadingDivs();
|
309
|
-
datatable.sort(true);
|
310
|
-
}
|
311
|
-
break;
|
312
|
-
case 404:
|
313
|
-
case 500:
|
314
|
-
console.log("ERROR: " + this.status + " - " + this.statusText);
|
315
|
-
console.log(xhr);
|
316
|
-
break;
|
317
|
-
default:
|
318
|
-
datatable.getAjaxDataAsync(start, recursive);
|
319
|
-
break;
|
320
|
-
}
|
321
|
-
}
|
322
|
-
}
|
323
|
-
} (this, start, recursive);
|
324
|
-
var url = this.options.data.url ;
|
325
|
-
var limit = this.options.pageSize * this.options.pagingNumberOfPages ;
|
326
|
-
var formdata = new FormData();
|
327
|
-
if (start !== true) {
|
328
|
-
if (this.options.data.type.toUpperCase() == 'GET') {
|
329
|
-
url += '?start=' + start + '&limit=' + limit ;
|
330
|
-
}
|
331
|
-
else {
|
332
|
-
formdata.append('offset', start);
|
333
|
-
formdata.append('limit', limit);
|
334
|
-
}
|
335
|
-
}
|
336
|
-
xhr.open(this.options.data.type, url, true);
|
337
|
-
xhr.responseType = 'json';
|
338
|
-
xhr.send(formdata);
|
339
|
-
},
|
340
|
-
|
341
|
-
/**
|
342
|
-
*
|
343
|
-
* @return The last page number according to options.pageSize and
|
344
|
-
* current number of filtered elements.
|
345
|
-
*
|
346
|
-
**/
|
347
|
-
getLastPageNumber: function () {
|
348
|
-
return parseInt(Math.ceil(this.filterIndex.length / this.options.pageSize), 10);
|
349
|
-
},
|
350
|
-
|
351
|
-
createPagingLink: function (content, page, disabled) {
|
352
|
-
var link = document.createElement('a');
|
353
|
-
|
354
|
-
// Check options...
|
355
|
-
if (this.options.pagingLinkClass) {
|
356
|
-
link.classList.add(this.options.pagingLinkClass);
|
357
|
-
}
|
358
|
-
|
359
|
-
if (this.options.pagingLinkHref) {
|
360
|
-
link.href = this.options.pagingLinkHref;
|
361
|
-
}
|
362
|
-
|
363
|
-
if (this.options.pagingLinkDisabledTabIndex !== false && disabled) {
|
364
|
-
link.tabIndex = this.options.pagingLinkDisabledTabIndex;
|
365
|
-
}
|
366
|
-
|
367
|
-
link.dataset.page = page;
|
368
|
-
link.innerHTML = content;
|
369
|
-
return link;
|
370
|
-
},
|
371
|
-
|
372
|
-
/**
|
373
|
-
*
|
374
|
-
* Update the paging divs.
|
375
|
-
*
|
376
|
-
**/
|
377
|
-
updatePaging: function () {
|
378
|
-
|
379
|
-
/* Be carefull if you change something here, all this part calculate the first
|
380
|
-
and last page to display. I choose to center the current page, it's more beautiful... */
|
381
|
-
|
382
|
-
var nbPages = this.options.pagingNumberOfPages;
|
383
|
-
var dataTable = this;
|
384
|
-
var cp = parseInt(this.currentStart / this.options.pageSize, 10) + 1;
|
385
|
-
var lp = this.getLastPageNumber();
|
386
|
-
var start;
|
387
|
-
var end;
|
388
|
-
var first = this.filterIndex.length ? this.currentStart + 1 : 0;
|
389
|
-
var last = (this.currentStart + this.options.pageSize) > this.filterIndex.length ?
|
390
|
-
this.filterIndex.length : this.currentStart + this.options.pageSize;
|
391
|
-
|
392
|
-
if (cp < nbPages / 2) {
|
393
|
-
start = 1;
|
394
|
-
}
|
395
|
-
else if (cp >= lp - nbPages / 2) {
|
396
|
-
start = lp - nbPages + 1;
|
397
|
-
if (start < 1) {
|
398
|
-
start = 1;
|
399
|
-
}
|
400
|
-
}
|
401
|
-
else {
|
402
|
-
start = parseInt(cp - nbPages / 2 + 1, 10);
|
403
|
-
}
|
404
|
-
|
405
|
-
if (start + nbPages < lp + 1) {
|
406
|
-
end = start + nbPages - 1;
|
407
|
-
}
|
408
|
-
else {
|
409
|
-
end = lp;
|
410
|
-
}
|
411
|
-
|
412
|
-
/* Juste iterate over each paging list and append li to ul. */
|
413
|
-
|
414
|
-
for (var i = 0; i < this.pagingLists.length; ++i) {
|
415
|
-
var childs = [];
|
416
|
-
if (dataTable.options.firstPage) {
|
417
|
-
var li = document.createElement('li');
|
418
|
-
li.appendChild(dataTable.createPagingLink(
|
419
|
-
dataTable.options.firstPage, "first", cp === 1
|
420
|
-
));
|
421
|
-
if (cp === 1) { li.classList.add('active'); }
|
422
|
-
childs.push(li);
|
423
|
-
}
|
424
|
-
if (dataTable.options.prevPage) {
|
425
|
-
var li = document.createElement('li');
|
426
|
-
li.appendChild(dataTable.createPagingLink(
|
427
|
-
dataTable.options.prevPage, "prev", cp === 1
|
428
|
-
));
|
429
|
-
if (cp === 1) { li.classList.add('active'); }
|
430
|
-
childs.push(li);
|
431
|
-
}
|
432
|
-
if (dataTable.options.pagingPages) {
|
433
|
-
var _childs = this.options.pagingPages.call(this.table, start,
|
434
|
-
end, cp, first, last);
|
435
|
-
if (_childs instanceof Array) {
|
436
|
-
childs = childs.concat(_childs);
|
437
|
-
}
|
438
|
-
else {
|
439
|
-
childs.push(_childs);
|
440
|
-
}
|
441
|
-
}
|
442
|
-
else {
|
443
|
-
for (var k = start; k <= end; k++) {
|
444
|
-
var li = document.createElement('li');
|
445
|
-
li.appendChild(dataTable.createPagingLink(
|
446
|
-
k, k, cp === k
|
447
|
-
));
|
448
|
-
if (k === cp) { li.classList.add('active'); }
|
449
|
-
childs.push(li);
|
450
|
-
}
|
451
|
-
}
|
452
|
-
if (dataTable.options.nextPage) {
|
453
|
-
var li = document.createElement('li');
|
454
|
-
li.appendChild(dataTable.createPagingLink(
|
455
|
-
dataTable.options.nextPage, "next", cp === lp || lp === 0
|
456
|
-
));
|
457
|
-
if (cp === lp || lp === 0) { li.classList.add('active'); }
|
458
|
-
childs.push(li);
|
459
|
-
}
|
460
|
-
if (dataTable.options.lastPage) {
|
461
|
-
var li = document.createElement('li');
|
462
|
-
li.appendChild(dataTable.createPagingLink(
|
463
|
-
dataTable.options.lastPage, "last", cp === lp || lp === 0
|
464
|
-
));
|
465
|
-
if (cp === lp || lp === 0) { li.classList.add('active'); }
|
466
|
-
childs.push(li);
|
467
|
-
}
|
468
|
-
this.pagingLists[i].innerHTML = '';
|
469
|
-
childs.forEach(function (e) {
|
470
|
-
if (dataTable.options.pagingItemClass) {
|
471
|
-
e.classList.add(dataTable.options.pagingItemClass);
|
472
|
-
}
|
473
|
-
if (e.childNodes.length > 0) {
|
474
|
-
e.childNodes[0].addEventListener('click', function (event) {
|
475
|
-
event.preventDefault();
|
476
|
-
if (this.parentNode.classList.contains('active') ||
|
477
|
-
typeof this.dataset.page === 'undefined') {
|
478
|
-
return;
|
479
|
-
}
|
480
|
-
switch (this.dataset.page) {
|
481
|
-
case 'first':
|
482
|
-
dataTable.loadPage(1);
|
483
|
-
break;
|
484
|
-
case 'prev':
|
485
|
-
dataTable.loadPage(cp - 1);
|
486
|
-
break;
|
487
|
-
case 'next':
|
488
|
-
dataTable.loadPage(cp + 1);
|
489
|
-
break;
|
490
|
-
case 'last':
|
491
|
-
dataTable.loadPage(lp);
|
492
|
-
break;
|
493
|
-
default:
|
494
|
-
dataTable.loadPage(parseInt(parseInt(this.dataset.page), 10));
|
495
|
-
}
|
496
|
-
}, false);
|
497
|
-
}
|
498
|
-
this.pagingLists[i].appendChild(e);
|
499
|
-
}, this);
|
500
|
-
}
|
501
|
-
|
502
|
-
},
|
503
|
-
|
504
|
-
/**
|
505
|
-
*
|
506
|
-
* Update the counter divs.
|
507
|
-
*
|
508
|
-
**/
|
509
|
-
updateCounter: function () {
|
510
|
-
var cp = this.filterIndex.length ?
|
511
|
-
parseInt(this.currentStart / this.options.pageSize, 10) + 1 : 0;
|
512
|
-
var lp = parseInt(Math.ceil(this.filterIndex.length / this.options.pageSize), 10);
|
513
|
-
var first = this.filterIndex.length ? this.currentStart + 1 : 0;
|
514
|
-
var last = (this.currentStart + this.options.pageSize) > this.filterIndex.length ?
|
515
|
-
this.filterIndex.length : this.currentStart + this.options.pageSize;
|
516
|
-
for (var i = 0; i < this.counterDivs.length; ++i) {
|
517
|
-
this.counterDivs[i].innerHTML = this.options.counterText.call(this.table, cp, lp,
|
518
|
-
first, last,
|
519
|
-
this.filterIndex.length,
|
520
|
-
this.data.length);
|
521
|
-
}
|
522
|
-
},
|
523
|
-
|
524
|
-
/**
|
525
|
-
*
|
526
|
-
* @return The sort function according to options.sort, options.sortKey & options.sortDir.
|
527
|
-
*
|
528
|
-
* Note: This function could return false if no sort function can be generated.
|
529
|
-
*
|
530
|
-
**/
|
531
|
-
getSortFunction: function () {
|
532
|
-
if (this.options.sort === false) {
|
533
|
-
return false;
|
534
|
-
}
|
535
|
-
if (this.options.sort instanceof Function) {
|
536
|
-
return this.options.sort;
|
537
|
-
}
|
538
|
-
if (this.data.length === 0 || !(this.options.sortKey in this.data[0])) {
|
539
|
-
return false;
|
540
|
-
}
|
541
|
-
var key = this.options.sortKey;
|
542
|
-
var asc = this.options.sortDir === 'asc';
|
543
|
-
if (this.options.sort[key] instanceof Function) {
|
544
|
-
return function (s) {
|
545
|
-
return function (a, b) {
|
546
|
-
var vala = a[key], valb = b[key];
|
547
|
-
return asc ? s(vala, valb) : -s(vala, valb);
|
548
|
-
};
|
549
|
-
} (this.options.sort[key]);
|
550
|
-
}
|
551
|
-
return function (a, b) {
|
552
|
-
var vala = a[key], valb = b[key];
|
553
|
-
if (vala > valb) { return asc ? 1 : -1; }
|
554
|
-
if (vala < valb) { return asc ? -1 : 1; }
|
555
|
-
return 0;
|
556
|
-
};
|
557
|
-
},
|
558
|
-
|
559
|
-
/**
|
560
|
-
*
|
561
|
-
* Destroy the filters (remove the filter line).
|
562
|
-
*
|
563
|
-
**/
|
564
|
-
destroyFilter: function () {
|
565
|
-
this.removeNode(this.table.querySelector('.datatable-filter-line'));
|
566
|
-
},
|
567
|
-
|
568
|
-
/**
|
569
|
-
*
|
570
|
-
* Change the text input filter placeholder according to this.options.filterText.
|
571
|
-
*
|
572
|
-
**/
|
573
|
-
changePlaceHolder: function () {
|
574
|
-
var placeholder = this.options.filterText ? this.options.filterText : '';
|
575
|
-
var inputTexts = this.table.querySelectorAll('.datatable-filter-line input[type="text"]');
|
576
|
-
for (var i = 0; i < inputTexts.length; ++i) {
|
577
|
-
inputTexts[i].placeholder = placeholder;
|
578
|
-
}
|
579
|
-
},
|
580
|
-
|
581
|
-
/**
|
582
|
-
*
|
583
|
-
* Create a text filter for the specified field.
|
584
|
-
*
|
585
|
-
* @param field The field corresponding to the filter
|
586
|
-
*
|
587
|
-
* @update filters Add the new filter to the list of filter (calling addFilter)
|
588
|
-
*
|
589
|
-
* @return The input filter
|
590
|
-
*
|
591
|
-
**/
|
592
|
-
createTextFilter: function (field) {
|
593
|
-
var opt = this.options.filters[field];
|
594
|
-
var input = opt instanceof HTMLInputElement ? opt : document.createElement('input');
|
595
|
-
input.type = 'text';
|
596
|
-
if (this.options.filterText) {
|
597
|
-
input.placeholder = this.options.filterText;
|
598
|
-
}
|
599
|
-
this.addClass(input, 'datatable-filter datatable-input-text');
|
600
|
-
input.dataset.filter = field;
|
601
|
-
this.filterVals[field] = '';
|
602
|
-
var typewatch = (function () {
|
603
|
-
var timer = 0;
|
604
|
-
return function (callback, ms) {
|
605
|
-
clearTimeout(timer);
|
606
|
-
timer = setTimeout(callback, ms);
|
607
|
-
};
|
608
|
-
})();
|
609
|
-
input.onkeyup = function (datatable) {
|
610
|
-
return function () {
|
611
|
-
var val = this.value.toUpperCase();
|
612
|
-
var field = this.dataset.filter;
|
613
|
-
typewatch(function () {
|
614
|
-
datatable.filterVals[field] = val;
|
615
|
-
datatable.filter();
|
616
|
-
}, 300);
|
617
|
-
};
|
618
|
-
} (this);
|
619
|
-
input.onkeydown = input.onkeyup;
|
620
|
-
var regexp = opt === 'regexp' || input.dataset.regexp;
|
621
|
-
if (opt instanceof Function) {
|
622
|
-
this.addFilter(field, opt);
|
623
|
-
}
|
624
|
-
else if (regexp) {
|
625
|
-
this.addFilter(field, function (data, val) {
|
626
|
-
return new RegExp(val).test(String(data));
|
627
|
-
});
|
628
|
-
}
|
629
|
-
else {
|
630
|
-
this.addFilter(field, function (data, val) {
|
631
|
-
return String(data).toUpperCase().indexOf(val) !== -1;
|
632
|
-
});
|
633
|
-
}
|
634
|
-
this.addClass(input, this.options.filterInputClass);
|
635
|
-
return input;
|
636
|
-
},
|
637
|
-
|
638
|
-
/**
|
639
|
-
* Check if the specified value is in the specified array, without strict type checking.
|
640
|
-
*
|
641
|
-
* @param val The val to search
|
642
|
-
* @param arr The array
|
643
|
-
*
|
644
|
-
* @return true if the value was found in the array
|
645
|
-
**/
|
646
|
-
_isIn: function (val, arr) {
|
647
|
-
var found = false;
|
648
|
-
for (var i = 0; i < arr.length && !found; ++i) {
|
649
|
-
found = arr[i] == val;
|
650
|
-
}
|
651
|
-
return found;
|
652
|
-
},
|
653
|
-
|
654
|
-
/**
|
655
|
-
* Return the index of the specified element in the object.
|
656
|
-
*
|
657
|
-
* @param v
|
658
|
-
* @param a
|
659
|
-
*
|
660
|
-
* @return The index, or -1
|
661
|
-
**/
|
662
|
-
_index: function (v, a) {
|
663
|
-
if (a === undefined || a === null) {
|
664
|
-
return -1;
|
665
|
-
}
|
666
|
-
var index = -1;
|
667
|
-
for (var i = 0; i < a.length && index == -1; ++i) {
|
668
|
-
if (a[i] === v) index = i;
|
669
|
-
}
|
670
|
-
return index;
|
671
|
-
},
|
672
|
-
|
673
|
-
/**
|
674
|
-
* Return the keys of the specified object.
|
675
|
-
*
|
676
|
-
* @param obj
|
677
|
-
*
|
678
|
-
* @return The keys of the specified object.
|
679
|
-
**/
|
680
|
-
_keys: function (obj) {
|
681
|
-
if (obj === undefined || obj === null) {
|
682
|
-
return undefined;
|
683
|
-
}
|
684
|
-
var keys = [];
|
685
|
-
for (var k in obj) {
|
686
|
-
if (obj.hasOwnProperty(k)) keys.push(k);
|
687
|
-
}
|
688
|
-
return keys;
|
689
|
-
},
|
690
|
-
|
691
|
-
/**
|
692
|
-
*
|
693
|
-
* Create a select filter for the specified field.
|
694
|
-
*
|
695
|
-
* @param field The field corresponding to the filter
|
696
|
-
*
|
697
|
-
* @update filters Add the new filter to the list of filter (calling addFilter)
|
698
|
-
*
|
699
|
-
* @return The select filter.
|
700
|
-
*
|
701
|
-
**/
|
702
|
-
createSelectFilter: function (field) {
|
703
|
-
var opt = this.options.filters[field];
|
704
|
-
var values = {}, selected = [], multiple = false,
|
705
|
-
empty = true, emptyValue = this.options.filterEmptySelect;
|
706
|
-
var tag = false;
|
707
|
-
if (opt instanceof HTMLSelectElement) {
|
708
|
-
tag = opt;
|
709
|
-
}
|
710
|
-
else if (opt instanceof Object && 'element' in opt && opt.element) {
|
711
|
-
tag = opt.element;
|
712
|
-
}
|
713
|
-
if (opt instanceof HTMLSelectElement || opt === 'select') {
|
714
|
-
values = this.getFilterOptions(field);
|
715
|
-
}
|
716
|
-
else {
|
717
|
-
multiple = ('multiple' in opt) && (opt.multiple === true);
|
718
|
-
empty = ('empty' in opt) && opt.empty;
|
719
|
-
emptyValue = (('empty' in opt) && (typeof opt.empty === 'string')) ?
|
720
|
-
opt.empty : this.options.filterEmptySelect;
|
721
|
-
if ('values' in opt) {
|
722
|
-
if (opt.values === 'auto') {
|
723
|
-
values = this.getFilterOptions(field);
|
724
|
-
}
|
725
|
-
else {
|
726
|
-
values = opt.values;
|
727
|
-
}
|
728
|
-
if ('default' in opt) {
|
729
|
-
selected = opt['default'];
|
730
|
-
}
|
731
|
-
else if (multiple) {
|
732
|
-
selected = [];
|
733
|
-
for (var k in values) {
|
734
|
-
if (values[k] instanceof Object) {
|
735
|
-
selected = selected.concat(this._keys(values[k]));
|
736
|
-
}
|
737
|
-
else {
|
738
|
-
selected.push(k);
|
739
|
-
}
|
740
|
-
}
|
741
|
-
}
|
742
|
-
else {
|
743
|
-
selected = [];
|
744
|
-
}
|
745
|
-
if (!(selected instanceof Array)) {
|
746
|
-
selected = [selected];
|
747
|
-
}
|
748
|
-
}
|
749
|
-
else {
|
750
|
-
values = opt;
|
751
|
-
selected = multiple ? this._keys(values) : [];
|
752
|
-
}
|
753
|
-
}
|
754
|
-
var select = tag ? tag : document.createElement('select');
|
755
|
-
if (multiple) {
|
756
|
-
select.multiple = true;
|
757
|
-
}
|
758
|
-
if (opt['default']) {
|
759
|
-
select.dataset['default'] = opt['default'];
|
760
|
-
}
|
761
|
-
this.addClass(select, 'datatable-filter datatable-select');
|
762
|
-
select.dataset.filter = field;
|
763
|
-
if (empty) {
|
764
|
-
var option = document.createElement('option');
|
765
|
-
option.dataset.empty = true;
|
766
|
-
option.value = "";
|
767
|
-
option.innerHTML = emptyValue;
|
768
|
-
select.appendChild(option);
|
769
|
-
}
|
770
|
-
var allKeys = [];
|
771
|
-
for (var key in values) {
|
772
|
-
if (values[key] instanceof Object) {
|
773
|
-
var optgroup = document.createElement('optgroup');
|
774
|
-
optgroup.label = key;
|
775
|
-
for (var skey in values[key]) {
|
776
|
-
if (values[key].hasOwnProperty(skey)) {
|
777
|
-
allKeys.push(skey);
|
778
|
-
var option = document.createElement('option');
|
779
|
-
option.value = skey;
|
780
|
-
option.selected = this._isIn(skey, selected);
|
781
|
-
option.innerHTML = values[key][skey];
|
782
|
-
optgroup.appendChild(option);
|
783
|
-
}
|
784
|
-
}
|
785
|
-
select.appendChild(optgroup);
|
786
|
-
}
|
787
|
-
else {
|
788
|
-
allKeys.push(key);
|
789
|
-
var option = document.createElement('option');
|
790
|
-
option.value = key;
|
791
|
-
option.selected = this._isIn(key, selected);
|
792
|
-
option.innerHTML = values[key];
|
793
|
-
select.appendChild(option);
|
794
|
-
}
|
795
|
-
}
|
796
|
-
var val = select.value;
|
797
|
-
if (multiple) {
|
798
|
-
val = [];
|
799
|
-
for (var i = 0; i < select.options.length; ++i) {
|
800
|
-
if (select.options[i].selected) { val.push(select.options[i].value); }
|
801
|
-
}
|
802
|
-
}
|
803
|
-
this.filterVals[field] = multiple ? val : ((empty && !val) ? allKeys : [val]);
|
804
|
-
select.onchange = function (allKeys, multiple, empty, datatable) {
|
805
|
-
return function () {
|
806
|
-
var val = this.value;
|
807
|
-
if (multiple) {
|
808
|
-
val = [];
|
809
|
-
for (var i = 0; i < this.options.length; ++i) {
|
810
|
-
if (this.options[i].selected) { val.push(this.options[i].value); }
|
811
|
-
}
|
812
|
-
}
|
813
|
-
var field = this.dataset.filter;
|
814
|
-
datatable.filterVals[field] = multiple ? val : ((empty && !val) ? allKeys : [val]);
|
815
|
-
datatable.filter();
|
816
|
-
};
|
817
|
-
} (allKeys, multiple, empty, this);
|
818
|
-
if (opt instanceof Object && opt.fn instanceof Function) {
|
819
|
-
this.addFilter(field, opt.fn);
|
820
|
-
select.dataset.filterType = 'function';
|
821
|
-
}
|
822
|
-
else {
|
823
|
-
this.addFilter(field, function (aKeys, datatable) {
|
824
|
-
return function (data, val) {
|
825
|
-
if (!val) { return false; }
|
826
|
-
if (val == aKeys && !data) { return true; }
|
827
|
-
return datatable._isIn(data, val);
|
828
|
-
};
|
829
|
-
} (allKeys, this));
|
830
|
-
select.dataset.filterType = 'default';
|
831
|
-
}
|
832
|
-
this.addClass(select, this.options.filterSelectClass);
|
833
|
-
return select;
|
834
|
-
},
|
835
|
-
|
836
|
-
/**
|
837
|
-
*
|
838
|
-
* Create the filter line according to options.filters.
|
839
|
-
*
|
840
|
-
**/
|
841
|
-
createFilter: function () {
|
842
|
-
this.filters = [];
|
843
|
-
this.filterTags = [];
|
844
|
-
this.filterVals = [];
|
845
|
-
// Speical options if '*'
|
846
|
-
if (this.options.filters === '*') {
|
847
|
-
var nThs = this.table.tHead.rows[0].cells.length;
|
848
|
-
this.options.filters = [];
|
849
|
-
while (nThs--) {
|
850
|
-
this.options.filters.push(true);
|
851
|
-
}
|
852
|
-
}
|
853
|
-
if (this.options.filters) {
|
854
|
-
var filterLine = false;
|
855
|
-
var tr = document.createElement('tr');
|
856
|
-
tr.classList.add('datatable-filter-line');
|
857
|
-
for (var field in this.options.filters) {
|
858
|
-
if (this.options.filters.hasOwnProperty(field)) {
|
859
|
-
var td = document.createElement('td');
|
860
|
-
if (this.options.filters[field] !== false) {
|
861
|
-
var opt = this.options.filters[field];
|
862
|
-
var input = opt === true || opt === 'regexp' || opt === 'input' || opt instanceof Function || opt instanceof HTMLInputElement;
|
863
|
-
var filter = input ? this.createTextFilter(field) : this.createSelectFilter(field);
|
864
|
-
this.filterTags[field] = filter;
|
865
|
-
if (!document.body.contains(filter)) {
|
866
|
-
td.classList.add('datatable-filter-cell');
|
867
|
-
td.appendChild(filter);
|
868
|
-
}
|
869
|
-
}
|
870
|
-
if (!(this.options.filters[field] instanceof Object) || !this.options.filters[field].noColumn) {
|
871
|
-
tr.appendChild(td);
|
872
|
-
}
|
873
|
-
}
|
874
|
-
}
|
875
|
-
if (tr.querySelectorAll('td.datatable-filter-cell').length > 0) {
|
876
|
-
this.table.tHead.appendChild(tr);
|
877
|
-
}
|
878
|
-
}
|
879
|
-
},
|
880
|
-
|
881
|
-
/**
|
882
|
-
*
|
883
|
-
* Filter data and refresh.
|
884
|
-
*
|
885
|
-
* @param keepCurrentPage true if the current page should not be changed (on refresh
|
886
|
-
* for example), if not specified or false, the current page will be set to 0.
|
887
|
-
*
|
888
|
-
* @update filterIndex Will contain the new filtered indexes
|
889
|
-
* @update currentStart The new starting point
|
890
|
-
*
|
891
|
-
**/
|
892
|
-
filter: function (keepCurrentPage) {
|
893
|
-
if (typeof keepCurrentPage === 'undefined') {
|
894
|
-
keepCurrentPage = false;
|
895
|
-
}
|
896
|
-
var oldCurrentStart = this.currentStart;
|
897
|
-
this.currentStart = 0;
|
898
|
-
this.filterIndex = [];
|
899
|
-
for (var i = 0; i < this.data.length; i++) {
|
900
|
-
if (this.checkFilter(this.data[i])) { this.filterIndex.push(i); }
|
901
|
-
}
|
902
|
-
if (keepCurrentPage) {
|
903
|
-
this.currentStart = oldCurrentStart;
|
904
|
-
while (this.currentStart >= this.filterIndex.length) {
|
905
|
-
this.currentStart -= this.options.pageSize;
|
906
|
-
}
|
907
|
-
if (this.currentStart < 0) {
|
908
|
-
this.currentStart = 0;
|
909
|
-
}
|
910
|
-
}
|
911
|
-
if (this.options.filterSelectOptions && this.filterIndex.length > 0) {
|
912
|
-
var dtable = this;
|
913
|
-
var allKeys = [];
|
914
|
-
for (var j = 0; j < this.data[0].length; ++j) {
|
915
|
-
allKeys.push({});
|
916
|
-
}
|
917
|
-
for (var i = 0; i < this.filterIndex.length; ++i) {
|
918
|
-
var row = this.data[this.filterIndex[i]];
|
919
|
-
for (var j = 0; j < row.length; ++j) {
|
920
|
-
allKeys[j][row[j]] = true;
|
921
|
-
}
|
922
|
-
}
|
923
|
-
for (var k = 0; k < allKeys.length; ++k) {
|
924
|
-
var keys = this._keys(allKeys[k]);
|
925
|
-
if (this.filterTags[k]
|
926
|
-
&& this.filterTags[k] instanceof HTMLSelectElement
|
927
|
-
&& this.filterTags[k].dataset.filterType == 'default') {
|
928
|
-
var options = this.filterTags[k].childNodes;
|
929
|
-
for (var i = 0; i < options.length; ++i) {
|
930
|
-
if (!options[i].dataset.empty) {
|
931
|
-
options[i].style.display = dtable._isIn(options[i].value, keys)
|
932
|
-
? 'block' : 'none';
|
933
|
-
}
|
934
|
-
}
|
935
|
-
}
|
936
|
-
}
|
937
|
-
}
|
938
|
-
this.refresh();
|
939
|
-
},
|
940
|
-
|
941
|
-
|
942
|
-
/**
|
943
|
-
*
|
944
|
-
* Reset all filters.
|
945
|
-
*
|
946
|
-
**/
|
947
|
-
resetFilters: function () {
|
948
|
-
var dtable = this;
|
949
|
-
this.filterTags.forEach(function (e) {
|
950
|
-
var field = e.dataset.filter;
|
951
|
-
if (e instanceof HTMLInputElement) {
|
952
|
-
e.value = '';
|
953
|
-
dtable.filterVals[field] = '';
|
954
|
-
}
|
955
|
-
else {
|
956
|
-
if (e.multiple) {
|
957
|
-
var allKeys = [];
|
958
|
-
for (var i = 0; i < e.childNodes.length; ++i) {
|
959
|
-
e.childNodes[i].selected = true;
|
960
|
-
allKeys.push(e.childNodes[i].value);
|
961
|
-
}
|
962
|
-
dtable.filterVals[field] = allKeys;
|
963
|
-
}
|
964
|
-
else if (e.dataset['default']
|
965
|
-
&& e.querySelector('option[value="' + e.dataset['default'] + '"]').length > 0) {
|
966
|
-
for (var i = 0; i < e.childNodes.length; ++i) {
|
967
|
-
e.childNodes[i].selected = e.childNodes[i].value == e.dataset['default'];
|
968
|
-
}
|
969
|
-
dtable.filterVals[field] = [e.dataset['default']];
|
970
|
-
}
|
971
|
-
else if (e.childNodes.length > 0) {
|
972
|
-
e.childNodes[0].selected = true;
|
973
|
-
for (var i = 1; i < e.childNodes.length; ++i) {
|
974
|
-
e.childNodes[i].selected = false;
|
975
|
-
}
|
976
|
-
if (e.childNodes[0].dataset.empty) {
|
977
|
-
var allKeys = [];
|
978
|
-
for (var i = 1; i < e.childNodes.length; ++i) {
|
979
|
-
allKeys.push(e.childNodes[i].value);
|
980
|
-
}
|
981
|
-
dtable.filterVals[field] = allKeys;
|
982
|
-
}
|
983
|
-
else {
|
984
|
-
dtable.filterVals[field] = [e.childNodes[0].value];
|
985
|
-
}
|
986
|
-
}
|
987
|
-
}
|
988
|
-
});
|
989
|
-
this.filter();
|
990
|
-
},
|
991
|
-
|
992
|
-
/**
|
993
|
-
* Strip HTML tags for the specified string.
|
994
|
-
*
|
995
|
-
* @param str The string from which tags must be stripped.
|
996
|
-
*
|
997
|
-
* @return The string with HTML tags removed.
|
998
|
-
*
|
999
|
-
**/
|
1000
|
-
stripTags: function (str) {
|
1001
|
-
var e = document.createElement('div');
|
1002
|
-
e.innerHTML = str;
|
1003
|
-
return e.textContent || e.innerText;
|
1004
|
-
},
|
1005
|
-
|
1006
|
-
/**
|
1007
|
-
*
|
1008
|
-
* Check if the specified data match the filters according to this.filters
|
1009
|
-
* and this.filterVals.
|
1010
|
-
*
|
1011
|
-
* @param data The data to check
|
1012
|
-
*
|
1013
|
-
* @return true if the data match the filters, false otherwise
|
1014
|
-
*
|
1015
|
-
**/
|
1016
|
-
checkFilter: function (data) {
|
1017
|
-
var ok = true;
|
1018
|
-
for (var fk in this.filters) {
|
1019
|
-
var currentData = fk[0] === '_' ? data : data[fk];
|
1020
|
-
if (typeof currentData === "string") {
|
1021
|
-
currentData = this.stripTags(currentData);
|
1022
|
-
}
|
1023
|
-
if (!this.filters[fk](currentData, this.filterVals[fk])) {
|
1024
|
-
ok = false;
|
1025
|
-
break;
|
1026
|
-
}
|
1027
|
-
}
|
1028
|
-
return ok;
|
1029
|
-
},
|
1030
|
-
|
1031
|
-
/**
|
1032
|
-
*
|
1033
|
-
* Add a new filter.
|
1034
|
-
*
|
1035
|
-
* @update filters
|
1036
|
-
*
|
1037
|
-
**/
|
1038
|
-
addFilter: function (field, filter) {
|
1039
|
-
this.filters[field] = filter;
|
1040
|
-
},
|
1041
|
-
|
1042
|
-
/**
|
1043
|
-
*
|
1044
|
-
* Get the filter select options for a specified field according
|
1045
|
-
* to this.data.
|
1046
|
-
*
|
1047
|
-
* @return The options found.
|
1048
|
-
*
|
1049
|
-
**/
|
1050
|
-
getFilterOptions: function (field) {
|
1051
|
-
var options = {}, values = [];
|
1052
|
-
for (var key in this.data) {
|
1053
|
-
if (this.data[key][field] !== '') {
|
1054
|
-
values.push(this.data[key][field]);
|
1055
|
-
}
|
1056
|
-
}
|
1057
|
-
values.sort();
|
1058
|
-
for (var i in values) {
|
1059
|
-
if (values.hasOwnProperty(i)) {
|
1060
|
-
var txt = this.stripTags(values[i]);
|
1061
|
-
options[txt] = txt;
|
1062
|
-
}
|
1063
|
-
}
|
1064
|
-
return options;
|
1065
|
-
},
|
1066
|
-
|
1067
|
-
/**
|
1068
|
-
*
|
1069
|
-
* Remove class, data and event on sort headers.
|
1070
|
-
*
|
1071
|
-
**/
|
1072
|
-
destroySort: function () {
|
1073
|
-
$('thead th').removeClass('sorting sorting-asc sorting-desc')
|
1074
|
-
.unbind('click.datatable')
|
1075
|
-
.removeData('sort');
|
1076
|
-
},
|
1077
|
-
|
1078
|
-
/**
|
1079
|
-
*
|
1080
|
-
* Add class, event & data to headers according to this.options.sort or data-sort attribute
|
1081
|
-
* of headers.
|
1082
|
-
*
|
1083
|
-
* @update options.sort Will be set to true if not already and a data-sort attribute is found.
|
1084
|
-
*
|
1085
|
-
**/
|
1086
|
-
createSort: function () {
|
1087
|
-
var dataTable = this;
|
1088
|
-
if (!(this.options.sort instanceof Function)) {
|
1089
|
-
|
1090
|
-
var countTH = 0;
|
1091
|
-
var ths = this.table.tHead.rows[0].cells;
|
1092
|
-
for (var i = 0; i < ths.length; ++i) {
|
1093
|
-
|
1094
|
-
if (ths[i].dataset.sort) {
|
1095
|
-
dataTable.options.sort = true;
|
1096
|
-
}
|
1097
|
-
else if (dataTable.options.sort === '*') {
|
1098
|
-
ths[i].dataset.sort = countTH;
|
1099
|
-
}
|
1100
|
-
else {
|
1101
|
-
var key;
|
1102
|
-
if (dataTable.options.sort instanceof Array) {
|
1103
|
-
key = countTH;
|
1104
|
-
}
|
1105
|
-
else if (dataTable.options.sort instanceof Object) {
|
1106
|
-
key = dataTable._keys(dataTable.options.sort)[countTH];
|
1107
|
-
}
|
1108
|
-
if (key !== undefined && dataTable.options.sort[key]) {
|
1109
|
-
ths[i].dataset.sort = key;
|
1110
|
-
}
|
1111
|
-
}
|
1112
|
-
|
1113
|
-
if (ths[i].dataset.sort !== undefined) {
|
1114
|
-
ths[i].classList.add('sorting');
|
1115
|
-
}
|
1116
|
-
|
1117
|
-
countTH++;
|
1118
|
-
|
1119
|
-
ths[i].addEventListener('click', function () {
|
1120
|
-
if (this.dataset.sort) {
|
1121
|
-
if (this.classList.contains('sorting-asc')) {
|
1122
|
-
dataTable.options.sortDir = 'desc';
|
1123
|
-
this.classList.remove('sorting-asc')
|
1124
|
-
this.classList.add('sorting-desc');
|
1125
|
-
}
|
1126
|
-
else if (this.classList.contains('sorting-desc')) {
|
1127
|
-
dataTable.options.sortDir = 'asc';
|
1128
|
-
this.classList.remove('sorting-desc');
|
1129
|
-
this.classList.add('sorting-asc');
|
1130
|
-
}
|
1131
|
-
else {
|
1132
|
-
var oths = this.parentNode.cells;
|
1133
|
-
for (var j = 0; j < oths.length; j++) {
|
1134
|
-
oths[j].classList.remove('sorting-desc');
|
1135
|
-
oths[j].classList.remove('sorting-asc');
|
1136
|
-
}
|
1137
|
-
dataTable.options.sortDir = 'asc';
|
1138
|
-
dataTable.options.sortKey = this.dataset.sort;
|
1139
|
-
this.classList.add('sorting-asc');
|
1140
|
-
}
|
1141
|
-
dataTable.sort();
|
1142
|
-
dataTable.refresh();
|
1143
|
-
}
|
1144
|
-
}, false);
|
1145
|
-
|
1146
|
-
}
|
1147
|
-
|
1148
|
-
}
|
1149
|
-
},
|
1150
|
-
|
1151
|
-
/**
|
1152
|
-
*
|
1153
|
-
* Trigger sort event on the table: If options.sort is a function,
|
1154
|
-
* sort the table, otherwize trigger click on the column specifid by options.sortKey.
|
1155
|
-
*
|
1156
|
-
**/
|
1157
|
-
triggerSort: function () {
|
1158
|
-
if (this.options.sort instanceof Function) {
|
1159
|
-
this.sort();
|
1160
|
-
this.refresh();
|
1161
|
-
}
|
1162
|
-
else if (this.options.sortKey !== false) {
|
1163
|
-
var ths = this.table.tHead.rows[0].cells;
|
1164
|
-
var th;
|
1165
|
-
for (var j = 0; j < ths.length; j++) {
|
1166
|
-
ths[j].classList.remove('sorting-desc');
|
1167
|
-
ths[j].classList.remove('sorting-asc');
|
1168
|
-
if (ths[j].dataset.sort === this.options.sortKey) {
|
1169
|
-
th = ths[j];
|
1170
|
-
}
|
1171
|
-
}
|
1172
|
-
if (th !== undefined) {
|
1173
|
-
th.classList.add('sorting-' + this.options.sortDir);
|
1174
|
-
this.sort();
|
1175
|
-
this.refresh();
|
1176
|
-
}
|
1177
|
-
}
|
1178
|
-
},
|
1179
|
-
|
1180
|
-
/**
|
1181
|
-
*
|
1182
|
-
* Sort the data.
|
1183
|
-
*
|
1184
|
-
* @update data
|
1185
|
-
*
|
1186
|
-
**/
|
1187
|
-
sort: function (keepCurrentPage) {
|
1188
|
-
var fnSort = this.getSortFunction();
|
1189
|
-
if (fnSort !== false) {
|
1190
|
-
this.data.sort(fnSort);
|
1191
|
-
}
|
1192
|
-
this.filter(keepCurrentPage);
|
1193
|
-
},
|
1194
|
-
|
1195
|
-
/**
|
1196
|
-
*
|
1197
|
-
* Try to identify the specified data with the specify identifier according
|
1198
|
-
* to this.options.identify.
|
1199
|
-
*
|
1200
|
-
* @return true if the data match, false otherwize
|
1201
|
-
*
|
1202
|
-
**/
|
1203
|
-
identify: function (id, data) {
|
1204
|
-
if (this.options.identify === false) {
|
1205
|
-
return false;
|
1206
|
-
}
|
1207
|
-
if (this.options.identify instanceof Function) {
|
1208
|
-
return this.options.identify(id, data);
|
1209
|
-
}
|
1210
|
-
return data[this.options.identify] == id;
|
1211
|
-
},
|
1212
|
-
|
1213
|
-
/**
|
1214
|
-
*
|
1215
|
-
* Find the index of the first element matching id in the data array.
|
1216
|
-
*
|
1217
|
-
* @param The id to find (will be match according to this.options.identify)
|
1218
|
-
*
|
1219
|
-
* @return The index of the first element found, or -1 if no element is found
|
1220
|
-
*
|
1221
|
-
**/
|
1222
|
-
indexOf: function (id) {
|
1223
|
-
var index = -1;
|
1224
|
-
for (var i = 0; i < this.data.length && index === -1; i++) {
|
1225
|
-
if (this.identify(id, this.data[i])) {
|
1226
|
-
index = i;
|
1227
|
-
}
|
1228
|
-
}
|
1229
|
-
return index;
|
1230
|
-
},
|
1231
|
-
|
1232
|
-
/**
|
1233
|
-
*
|
1234
|
-
* Get an elements from the data array.
|
1235
|
-
*
|
1236
|
-
* @param id An identifier for the element (see this.options.identify)
|
1237
|
-
*
|
1238
|
-
**/
|
1239
|
-
row: function (id) {
|
1240
|
-
if (this.options.identify === true) {
|
1241
|
-
return this.data[id];
|
1242
|
-
}
|
1243
|
-
return this.data[this.indexOf(id)];
|
1244
|
-
},
|
1245
|
-
|
1246
|
-
/**
|
1247
|
-
*
|
1248
|
-
* Retrieve all data.
|
1249
|
-
*
|
1250
|
-
*
|
1251
|
-
**/
|
1252
|
-
all: function (filter) {
|
1253
|
-
if (typeof filter === "undefined"
|
1254
|
-
|| filter === true) {
|
1255
|
-
return this.data;
|
1256
|
-
}
|
1257
|
-
var returnData = [];
|
1258
|
-
for (var i = 0; i < this.data.length; ++i) {
|
1259
|
-
if (filter(this.data[i])) {
|
1260
|
-
returnData.push(this.data[i]);
|
1261
|
-
}
|
1262
|
-
}
|
1263
|
-
return returnData;
|
1264
|
-
},
|
1265
|
-
|
1266
|
-
/**
|
1267
|
-
*
|
1268
|
-
* Add an element to the data array.
|
1269
|
-
*
|
1270
|
-
* @param data The element to add
|
1271
|
-
*
|
1272
|
-
* @update data
|
1273
|
-
*
|
1274
|
-
**/
|
1275
|
-
addRow: function (data) {
|
1276
|
-
this.data.push(data);
|
1277
|
-
if (typeof this.syncData !== "undefined") {
|
1278
|
-
this.syncData.toAdd.push(data);
|
1279
|
-
}
|
1280
|
-
this.sort();
|
1281
|
-
this.filter();
|
1282
|
-
this.currentStart = parseInt(this._index(this._index(data, this.data),
|
1283
|
-
this.filterIndex)
|
1284
|
-
/ this.options.pageSize, 10) * this.options.pageSize;
|
1285
|
-
this.refresh();
|
1286
|
-
},
|
1287
|
-
|
1288
|
-
/**
|
1289
|
-
*
|
1290
|
-
* Add elements to the data array.
|
1291
|
-
*
|
1292
|
-
* @param data Array of elements to add
|
1293
|
-
*
|
1294
|
-
* @update data
|
1295
|
-
*
|
1296
|
-
**/
|
1297
|
-
addRows: function (data) {
|
1298
|
-
this.data = this.data.concat(data);
|
1299
|
-
if (typeof this.syncData !== "undefined") {
|
1300
|
-
this.syncData.toAdd = this.syncData.toAdd.concat(data);
|
1301
|
-
}
|
1302
|
-
this.sort();
|
1303
|
-
this.filter();
|
1304
|
-
this.currentStart = parseInt(this._index(this._index(data, this.data),
|
1305
|
-
this.filterIndex)
|
1306
|
-
/ this.options.pageSize, 10) * this.options.pageSize;
|
1307
|
-
this.refresh();
|
1308
|
-
},
|
1309
|
-
|
1310
|
-
/**
|
1311
|
-
*
|
1312
|
-
* Remove an element from the data array.
|
1313
|
-
*
|
1314
|
-
* @param id An identifier for the element (see this.options.identify)
|
1315
|
-
*
|
1316
|
-
**/
|
1317
|
-
deleteRow: function (id) {
|
1318
|
-
var oldCurrentStart = this.currentStart;
|
1319
|
-
var index = this.indexOf(id);
|
1320
|
-
if (index === -1) {
|
1321
|
-
console.log('No data found with id: ' + id);
|
1322
|
-
return;
|
1323
|
-
}
|
1324
|
-
this.data.splice(index, 1);
|
1325
|
-
if (typeof this.syncData !== "undefined") {
|
1326
|
-
this.syncData.toDelete.push(id);
|
1327
|
-
}
|
1328
|
-
this.filter();
|
1329
|
-
if (oldCurrentStart < this.filterIndex.length) {
|
1330
|
-
this.currentStart = oldCurrentStart;
|
1331
|
-
}
|
1332
|
-
else {
|
1333
|
-
this.currentStart = oldCurrentStart - this.options.pageSize;
|
1334
|
-
if (this.currentStart < 0) { this.currentStart = 0; }
|
1335
|
-
}
|
1336
|
-
this.refresh();
|
1337
|
-
},
|
1338
|
-
|
1339
|
-
/**
|
1340
|
-
*
|
1341
|
-
* Delete all elements matching the filter arg.
|
1342
|
-
*
|
1343
|
-
**/
|
1344
|
-
deleteAll: function (filter) {
|
1345
|
-
var oldCurrentStart = this.currentStart
|
1346
|
-
var newData = [];
|
1347
|
-
if (typeof this.syncData !== "undefined") {
|
1348
|
-
this.syncData.toDelete.push(filter);
|
1349
|
-
}
|
1350
|
-
for (var i = 0; i < this.data.length; ++i) {
|
1351
|
-
if (!filter(this.data[i])) {
|
1352
|
-
newData.push(this.data[i]);
|
1353
|
-
}
|
1354
|
-
}
|
1355
|
-
this.data = newData;
|
1356
|
-
this.filter();
|
1357
|
-
if (oldCurrentStart < this.filterIndex.length) {
|
1358
|
-
this.currentStart = oldCurrentStart;
|
1359
|
-
}
|
1360
|
-
else {
|
1361
|
-
this.currentStart = oldCurrentStart - this.options.pageSize;
|
1362
|
-
if (this.currentStart < 0) { this.currentStart = 0; }
|
1363
|
-
}
|
1364
|
-
this.refresh();
|
1365
|
-
},
|
1366
|
-
|
1367
|
-
/**
|
1368
|
-
*
|
1369
|
-
* Update an element in the data array. Will add the element if it is not found.
|
1370
|
-
*
|
1371
|
-
* @param id An identifier for the element (see this.options.identify)
|
1372
|
-
* @param data The new data (identifier value will be set to id)
|
1373
|
-
*
|
1374
|
-
**/
|
1375
|
-
updateRow: function (id, data) {
|
1376
|
-
var index = this.indexOf(id);
|
1377
|
-
if (typeof this.syncData !== "undefined") {
|
1378
|
-
this.syncData.toUpdate[id] = data;
|
1379
|
-
}
|
1380
|
-
if (index !== -1) {
|
1381
|
-
if (id in data) {
|
1382
|
-
delete data[id];
|
1383
|
-
}
|
1384
|
-
for (var key in this.data[index]) {
|
1385
|
-
if (key in data) {
|
1386
|
-
this.data[index][key] = data[key];
|
1387
|
-
}
|
1388
|
-
}
|
1389
|
-
this.sort();
|
1390
|
-
this.filter();
|
1391
|
-
this.currentStart = parseInt(this._index(this.indexOf(id),
|
1392
|
-
this.filterIndex)
|
1393
|
-
/ this.options.pageSize, 10) * this.options.pageSize;
|
1394
|
-
this.refresh();
|
1395
|
-
}
|
1396
|
-
},
|
1397
|
-
|
1398
|
-
/**
|
1399
|
-
*
|
1400
|
-
* Change the current page and refresh.
|
1401
|
-
*
|
1402
|
-
* @param page The number of the page to load
|
1403
|
-
*
|
1404
|
-
* @update currentStart
|
1405
|
-
*
|
1406
|
-
**/
|
1407
|
-
loadPage: function (page) {
|
1408
|
-
var oldPage = this.currentStart / this.options.pageSize;
|
1409
|
-
if (page < 1) {
|
1410
|
-
page = 1;
|
1411
|
-
}
|
1412
|
-
else if (page > this.getLastPageNumber()) {
|
1413
|
-
page = this.getLastPageNumber();
|
1414
|
-
}
|
1415
|
-
this.currentStart = (page - 1) * this.options.pageSize;
|
1416
|
-
this.refresh();
|
1417
|
-
this.options.onChange.call(this.table, oldPage + 1, page);
|
1418
|
-
},
|
1419
|
-
|
1420
|
-
/**
|
1421
|
-
*
|
1422
|
-
* @return The current page
|
1423
|
-
*
|
1424
|
-
**/
|
1425
|
-
getCurrentPage: function () {
|
1426
|
-
return this.currentStart / this.options.pageSize + 1;
|
1427
|
-
},
|
1428
|
-
|
1429
|
-
/**
|
1430
|
-
*
|
1431
|
-
* Refresh the page according to current page (DO NOT SORT).
|
1432
|
-
* This function call options.lineFormat.
|
1433
|
-
*
|
1434
|
-
**/
|
1435
|
-
refresh: function () {
|
1436
|
-
this.options.beforeRefresh.call(this.table);
|
1437
|
-
this.updatePaging();
|
1438
|
-
this.updateCounter();
|
1439
|
-
this.table.tBodies[0].innerHTML = "";
|
1440
|
-
if (this.currentStart >= this.currentDataLength) {
|
1441
|
-
this.table.tBodies[0].innerHTML = '<tr><td colspan="' + this.options.nbColumns + '">'
|
1442
|
-
+ '<div class="progress progress-striped active">'
|
1443
|
-
+ '<div class="bar" style="width: 100%;"></div>'
|
1444
|
-
+ '</div></div></tr>';
|
1445
|
-
return;
|
1446
|
-
}
|
1447
|
-
for (var i = 0;
|
1448
|
-
i < this.options.pageSize && i + this.currentStart < this.filterIndex.length;
|
1449
|
-
i++) {
|
1450
|
-
var index = this.filterIndex[this.currentStart + i];
|
1451
|
-
var data = this.data[index];
|
1452
|
-
this.table.tBodies[0].appendChild(this.options.lineFormat.call(this.table,
|
1453
|
-
index, data));
|
1454
|
-
}
|
1455
|
-
this.options.afterRefresh.call(this.table);
|
1456
|
-
},
|
1457
|
-
|
1458
|
-
/**
|
1459
|
-
*
|
1460
|
-
* Set a option and refresh the table if necessary.
|
1461
|
-
*
|
1462
|
-
* @param key The name of the option to change
|
1463
|
-
* @param val The new option value
|
1464
|
-
*
|
1465
|
-
* @update options
|
1466
|
-
*
|
1467
|
-
**/
|
1468
|
-
setOption: function (key, val) {
|
1469
|
-
if (key in this.options) {
|
1470
|
-
this.options[key] = val;
|
1471
|
-
if (key === 'sort') {
|
1472
|
-
this.destroySort();
|
1473
|
-
this.createSort();
|
1474
|
-
this.triggerSort();
|
1475
|
-
}
|
1476
|
-
if (key === 'sortKey' || key === 'sortDir') {
|
1477
|
-
this.sort();
|
1478
|
-
}
|
1479
|
-
if (key === 'filters') {
|
1480
|
-
this.destroyFilter();
|
1481
|
-
this.createFilter();
|
1482
|
-
}
|
1483
|
-
if (key === 'filterText') {
|
1484
|
-
this.changePlaceHolder();
|
1485
|
-
}
|
1486
|
-
this.filter();
|
1487
|
-
}
|
1488
|
-
},
|
1489
|
-
|
1490
|
-
/**
|
1491
|
-
*
|
1492
|
-
* Set a list of options and refresh the table if necessary.
|
1493
|
-
*
|
1494
|
-
* @param options A list of options to set (plain object)
|
1495
|
-
*
|
1496
|
-
* @update options
|
1497
|
-
*
|
1498
|
-
**/
|
1499
|
-
setOptions: function (options) {
|
1500
|
-
for (var key in options) {
|
1501
|
-
if (key in this.options) {
|
1502
|
-
this.options[key] = options[key];
|
1503
|
-
}
|
1504
|
-
}
|
1505
|
-
if ('sort' in options) {
|
1506
|
-
this.destroySort();
|
1507
|
-
this.createSort();
|
1508
|
-
this.triggerSort();
|
1509
|
-
}
|
1510
|
-
else if ('sortKey' in options || 'sortDir' in options) {
|
1511
|
-
this.sort();
|
1512
|
-
}
|
1513
|
-
if ('filters' in options) {
|
1514
|
-
this.destroyFilter();
|
1515
|
-
this.createFilter();
|
1516
|
-
}
|
1517
|
-
if ('filterText' in options) {
|
1518
|
-
this.changePlaceHolder();
|
1519
|
-
}
|
1520
|
-
this.filter();
|
1521
|
-
},
|
1522
|
-
|
1523
|
-
/**
|
1524
|
-
*
|
1525
|
-
* Remove all the elements added by the datatable.
|
1526
|
-
*
|
1527
|
-
**/
|
1528
|
-
destroy: function () {
|
1529
|
-
if (this.refreshTimeOut !== undefined) {
|
1530
|
-
clearTimeout(this.refreshTimeOut);
|
1531
|
-
}
|
1532
|
-
this.destroySort();
|
1533
|
-
for (var i = 0; i < this.pagingDivs.length; ++i) {
|
1534
|
-
this.pagingDivs[i].classList.remove('pagination-datatable');
|
1535
|
-
this.pagingDivs[i].classList.remove(this.options.pagingDivClass);
|
1536
|
-
this.pagingDivs[i].innerHTML = '';
|
1537
|
-
}
|
1538
|
-
this.destroyFilter();
|
1539
|
-
this.table.classList.remove(this.options.tableClass);
|
1540
|
-
this.removeNode(this.table.tBodies[0]);
|
1541
|
-
this.table.appendChild(document.createElement('tbody'));
|
1542
|
-
for (var i = 0; i < this.data.length; i++) {
|
1543
|
-
var index = this.filterIndex[this.currentStart + i];
|
1544
|
-
var data = this.data[index];
|
1545
|
-
this.table.tBodies[0].appendChild(this.options.lineFormat.call(this.table,
|
1546
|
-
index, data));
|
1547
|
-
}
|
1548
|
-
|
1549
|
-
}
|
1550
|
-
};
|
1551
|
-
|
1552
|
-
/**
|
1553
|
-
* Default option for DataTable.
|
1554
|
-
*
|
1555
|
-
*/
|
1556
|
-
DataTable.defaultOptions = {
|
1557
|
-
|
1558
|
-
/**
|
1559
|
-
* Specify whether the type of the column should be deduced or not. If this option
|
1560
|
-
* is true, the type is not deduced (mainly here for backward compatibility).
|
1561
|
-
*
|
1562
|
-
* @see dataTypes
|
1563
|
-
*/
|
1564
|
-
forceStrings: false,
|
1565
|
-
|
1566
|
-
/**
|
1567
|
-
* Specify the class of the table.
|
1568
|
-
*
|
1569
|
-
*/
|
1570
|
-
tableClass: 'datatable',
|
1571
|
-
|
1572
|
-
/**
|
1573
|
-
* Specify the selector for the paging div element.
|
1574
|
-
*
|
1575
|
-
*/
|
1576
|
-
pagingDivSelector: '.paging',
|
1577
|
-
|
1578
|
-
/**
|
1579
|
-
* Specify the class for the paging div element.
|
1580
|
-
*
|
1581
|
-
*/
|
1582
|
-
pagingDivClass: 'text-center',
|
1583
|
-
|
1584
|
-
/**
|
1585
|
-
* Specify the class for the paging list element.
|
1586
|
-
*
|
1587
|
-
*/
|
1588
|
-
pagingListClass: 'pagination',
|
1589
|
-
|
1590
|
-
/**
|
1591
|
-
* Specify the class for the paging list item elements.
|
1592
|
-
*
|
1593
|
-
*/
|
1594
|
-
pagingItemClass: '',
|
1595
|
-
|
1596
|
-
/**
|
1597
|
-
* Specify the class for the paging list link elements.
|
1598
|
-
*
|
1599
|
-
*/
|
1600
|
-
pagingLinkClass: '',
|
1601
|
-
|
1602
|
-
/**
|
1603
|
-
* Specify the href attribute for the paging list link elements.
|
1604
|
-
*
|
1605
|
-
*/
|
1606
|
-
pagingLinkHref: '',
|
1607
|
-
|
1608
|
-
/**
|
1609
|
-
* Specify the tabindex attribute for the paging list link elements when
|
1610
|
-
* disabled.
|
1611
|
-
*
|
1612
|
-
*/
|
1613
|
-
pagingLinkDisabledTabIndex: false,
|
1614
|
-
|
1615
|
-
/**
|
1616
|
-
* Specify the selector for the counter div element.
|
1617
|
-
*
|
1618
|
-
* @see counterText
|
1619
|
-
*/
|
1620
|
-
counterDivSelector: '.counter',
|
1621
|
-
|
1622
|
-
/**
|
1623
|
-
* Specify the selector the loading div element.
|
1624
|
-
*
|
1625
|
-
* @see data
|
1626
|
-
*/
|
1627
|
-
loadingDivSelector: '.loading',
|
1628
|
-
|
1629
|
-
/**
|
1630
|
-
* Sepcify the sort options.
|
1631
|
-
*
|
1632
|
-
* @type boolean|string|Array|Object
|
1633
|
-
*/
|
1634
|
-
sort: false,
|
1635
|
-
|
1636
|
-
/**
|
1637
|
-
* Specify the default sort key.
|
1638
|
-
*
|
1639
|
-
* @type boolean|int|string.
|
1640
|
-
*/
|
1641
|
-
sortKey: false,
|
1642
|
-
|
1643
|
-
/**
|
1644
|
-
* Specify the default sort directions, 'asc' or 'desc'.
|
1645
|
-
*
|
1646
|
-
*/
|
1647
|
-
sortDir: 'asc',
|
1648
|
-
|
1649
|
-
/**
|
1650
|
-
* Specify the number of columns, a value of -1 (default) specify
|
1651
|
-
* the the number of columns should be retrieved for the <thead>
|
1652
|
-
* elements of the table.
|
1653
|
-
*
|
1654
|
-
*/
|
1655
|
-
nbColumns: -1,
|
1656
|
-
|
1657
|
-
/**
|
1658
|
-
* Specify the number of elements to display per page.
|
1659
|
-
*
|
1660
|
-
*/
|
1661
|
-
pageSize: 20,
|
1662
|
-
|
1663
|
-
/**
|
1664
|
-
* Specify the number of pages to display in the paging list element.
|
1665
|
-
*
|
1666
|
-
*/
|
1667
|
-
pagingNumberOfPages: 9,
|
1668
|
-
|
1669
|
-
/**
|
1670
|
-
* Specify the way of identifying items from the data array:
|
1671
|
-
*
|
1672
|
-
* - if this option is false (default), no identification is provided.
|
1673
|
-
* - if a Function is specified, the function is used to identify:
|
1674
|
-
* function (id, item) -> boolean
|
1675
|
-
* - if an int or a string is specified, items are identified by the
|
1676
|
-
* value corresponding to the key.
|
1677
|
-
*
|
1678
|
-
* @type boolean|int|string|Function.
|
1679
|
-
*
|
1680
|
-
*/
|
1681
|
-
identify: false,
|
1682
|
-
|
1683
|
-
/**
|
1684
|
-
* Callback function when the table is updated.
|
1685
|
-
*
|
1686
|
-
*/
|
1687
|
-
onChange: function (oldPage, newPage) { },
|
1688
|
-
|
1689
|
-
/**
|
1690
|
-
* Function used to generate content for the counter div element.
|
1691
|
-
*
|
1692
|
-
*/
|
1693
|
-
counterText: function (currentPage, totalPage,
|
1694
|
-
firstRow, lastRow,
|
1695
|
-
totalRow, totalRowUnfiltered) {
|
1696
|
-
var counterText = 'Page ' + currentPage + ' on ' + totalPage
|
1697
|
-
+ '. Showing ' + firstRow + ' to ' + lastRow + ' of ' + totalRow + ' entries';
|
1698
|
-
if (totalRow != totalRowUnfiltered) {
|
1699
|
-
counterText += ' (filtered from ' + totalRowUnfiltered + ' total entries)';
|
1700
|
-
}
|
1701
|
-
counterText += '.';
|
1702
|
-
return counterText;
|
1703
|
-
},
|
1704
|
-
|
1705
|
-
/**
|
1706
|
-
* Content of the paging item pointing to the first page.
|
1707
|
-
*
|
1708
|
-
*/
|
1709
|
-
firstPage: '<<',
|
1710
|
-
|
1711
|
-
/**
|
1712
|
-
* Content of the paging item pointing to the previous page.
|
1713
|
-
*
|
1714
|
-
*/
|
1715
|
-
prevPage: '<',
|
1716
|
-
|
1717
|
-
/**
|
1718
|
-
*
|
1719
|
-
*/
|
1720
|
-
pagingPages: false,
|
1721
|
-
|
1722
|
-
/**
|
1723
|
-
* Content of the paging item pointing to the next page.
|
1724
|
-
*
|
1725
|
-
*/
|
1726
|
-
nextPage: '>',
|
1727
|
-
|
1728
|
-
/**
|
1729
|
-
* Content of the paging item pointing to the last page.
|
1730
|
-
*
|
1731
|
-
*/
|
1732
|
-
lastPage: '>>',
|
1733
|
-
|
1734
|
-
/**
|
1735
|
-
* Specify the type of the columns:
|
1736
|
-
*
|
1737
|
-
* - if false, the type is not deduced and values are treated as strings.
|
1738
|
-
* - if true, the type is deduced automatically.
|
1739
|
-
* - if an Array is specified, the type of each column is retrieve from the
|
1740
|
-
* array values, possible values are 'int', 'float' <> 'double', 'date' <> 'datetime',
|
1741
|
-
* false <> true <> 'string' <> 'str'. A function can also be specified to convert
|
1742
|
-
* the value.
|
1743
|
-
*
|
1744
|
-
* @see forceStrings
|
1745
|
-
*
|
1746
|
-
*/
|
1747
|
-
dataTypes: true,
|
1748
|
-
|
1749
|
-
/**
|
1750
|
-
* Specify the filter options.
|
1751
|
-
*
|
1752
|
-
*/
|
1753
|
-
filters: {},
|
1754
|
-
|
1755
|
-
/**
|
1756
|
-
* Specify the placeholder for the textual input filters.
|
1757
|
-
*/
|
1758
|
-
filterText: 'Search... ',
|
1759
|
-
|
1760
|
-
/**
|
1761
|
-
* Specify the placeholder for the select input filters.
|
1762
|
-
*/
|
1763
|
-
filterEmptySelect: '',
|
1764
|
-
|
1765
|
-
/**
|
1766
|
-
*
|
1767
|
-
*/
|
1768
|
-
filterSelectOptions: false,
|
1769
|
-
|
1770
|
-
/**
|
1771
|
-
*
|
1772
|
-
*/
|
1773
|
-
filterInputClass: 'form-control',
|
1774
|
-
|
1775
|
-
/**
|
1776
|
-
*
|
1777
|
-
*/
|
1778
|
-
filterSelectClass: 'form-control',
|
1779
|
-
|
1780
|
-
/**
|
1781
|
-
* Callback function before the display is reloaded.
|
1782
|
-
*
|
1783
|
-
*/
|
1784
|
-
beforeRefresh: function () { },
|
1785
|
-
|
1786
|
-
/**
|
1787
|
-
* Callback function after the display has been reloaded.
|
1788
|
-
*
|
1789
|
-
*/
|
1790
|
-
afterRefresh: function () { },
|
1791
|
-
|
1792
|
-
/**
|
1793
|
-
* Function used to generate the row of the table.
|
1794
|
-
*
|
1795
|
-
*/
|
1796
|
-
lineFormat: function (id, data) {
|
1797
|
-
var res = document.createElement('tr');
|
1798
|
-
res.dataset.id = id;
|
1799
|
-
for (var key in data) {
|
1800
|
-
if (data.hasOwnProperty(key)) {
|
1801
|
-
res.innerHTML += '<td>' + data[key] + '</td>';
|
1802
|
-
}
|
1803
|
-
}
|
1804
|
-
return res;
|
1805
|
-
}
|
1806
|
-
};
|
1807
|
-
|
1808
|
-
DataTable.defaultAjaxOptions = {
|
1809
|
-
url: null,
|
1810
|
-
size: null,
|
1811
|
-
refresh: false,
|
1812
|
-
allInOne: false,
|
1813
|
-
timeout: 2000
|
1814
|
-
};
|