bootstrap-table-rails 1.9.1 → 1.10.0
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/README.md +5 -1
- data/lib/bootstrap-table-rails/version.rb +1 -1
- data/vendor/assets/javascripts/bootstrap-table-locale-all.js +30 -10
- data/vendor/assets/javascripts/bootstrap-table.js +157 -53
- data/vendor/assets/javascripts/extensions/bootstrap-table-cookie.js +8 -4
- data/vendor/assets/javascripts/extensions/bootstrap-table-editable.js +21 -0
- data/vendor/assets/javascripts/extensions/bootstrap-table-export.js +9 -2
- data/vendor/assets/javascripts/extensions/bootstrap-table-filter-control.js +127 -46
- data/vendor/assets/javascripts/extensions/bootstrap-table-group-by 2.js +226 -0
- data/vendor/assets/javascripts/extensions/bootstrap-table-mobile.js +5 -0
- data/vendor/assets/javascripts/extensions/bootstrap-table-natural-sorting.js +12 -2
- data/vendor/assets/javascripts/extensions/bootstrap-table-reorder-rows.js +1 -0
- data/vendor/assets/javascripts/extensions/bootstrap-table-sticky-header.js +104 -0
- data/vendor/assets/javascripts/locale/bootstrap-table-ca-ES.js +7 -6
- data/vendor/assets/javascripts/locale/bootstrap-table-en-US.js +2 -2
- data/vendor/assets/javascripts/locale/bootstrap-table-nl-NL.js +16 -1
- data/vendor/assets/javascripts/locale/bootstrap-table-ru-RU.js +3 -0
- data/vendor/assets/javascripts/locale/bootstrap-table-zh-TW.js +2 -2
- data/vendor/assets/stylesheets/bootstrap-table.css +7 -2
- data/vendor/assets/stylesheets/extensions/bootstrap-table-group-by 2.css +7 -0
- data/vendor/assets/stylesheets/extensions/bootstrap-table-sticky-header.css +22 -0
- metadata +6 -2
@@ -123,7 +123,7 @@
|
|
123
123
|
cookieExpire = cookieExpire * 30 * 24 * 60 * 60;
|
124
124
|
break;
|
125
125
|
case 'y':
|
126
|
-
cookieExpire = cookieExpire * 365 *
|
126
|
+
cookieExpire = cookieExpire * 365 * 24 * 60 * 60;
|
127
127
|
break;
|
128
128
|
default:
|
129
129
|
cookieExpire = undefined;
|
@@ -203,7 +203,7 @@
|
|
203
203
|
searchControls = getCurrentSearchControls(that);
|
204
204
|
|
205
205
|
header.find(searchControls).each(function (index, ele) {
|
206
|
-
field = $(this).
|
206
|
+
field = $(this).closest('[data-field]').data('field');
|
207
207
|
result = $.grep(filterControl, function (valueObj) {
|
208
208
|
return valueObj.field === field;
|
209
209
|
});
|
@@ -317,8 +317,12 @@
|
|
317
317
|
};
|
318
318
|
|
319
319
|
BootstrapTable.prototype.onSearch = function () {
|
320
|
-
|
321
|
-
|
320
|
+
var target = Array.prototype.slice.apply(arguments);
|
321
|
+
_onSearch.apply(this, target);
|
322
|
+
|
323
|
+
if ($(target[0].currentTarget).parent().hasClass('search')) {
|
324
|
+
setCookie(this, cookieIds.searchText, this.searchText);
|
325
|
+
}
|
322
326
|
};
|
323
327
|
|
324
328
|
BootstrapTable.prototype.deleteCookie = function (cookieName) {
|
@@ -47,14 +47,34 @@
|
|
47
47
|
return;
|
48
48
|
}
|
49
49
|
|
50
|
+
var editableOptions = {}, editableDataMarkup = [], editableDataPrefix = 'editable-';
|
51
|
+
|
52
|
+
var processDataOptions = function(key, value) {
|
53
|
+
// Replace camel case with dashes.
|
54
|
+
var dashKey = key.replace(/([A-Z])/g, function($1){return "-"+$1.toLowerCase();});
|
55
|
+
if (dashKey.slice(0, editableDataPrefix.length) == editableDataPrefix) {
|
56
|
+
var dataKey = dashKey.replace(editableDataPrefix, 'data-');
|
57
|
+
editableOptions[dataKey] = value;
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
$.each(that.options, processDataOptions);
|
62
|
+
|
50
63
|
var _formatter = column.formatter;
|
51
64
|
column.formatter = function (value, row, index) {
|
52
65
|
var result = _formatter ? _formatter(value, row, index) : value;
|
53
66
|
|
67
|
+
$.each(column, processDataOptions);
|
68
|
+
|
69
|
+
$.each(editableOptions, function (key, value) {
|
70
|
+
editableDataMarkup.push(' ' + key + '="' + value + '"');
|
71
|
+
});
|
72
|
+
|
54
73
|
return ['<a href="javascript:void(0)"',
|
55
74
|
' data-name="' + column.field + '"',
|
56
75
|
' data-pk="' + row[that.options.idField] + '"',
|
57
76
|
' data-value="' + result + '"',
|
77
|
+
editableDataMarkup.join(''),
|
58
78
|
'>' + '</a>'
|
59
79
|
].join('');
|
60
80
|
};
|
@@ -81,6 +101,7 @@
|
|
81
101
|
row = data[index],
|
82
102
|
oldValue = row[column.field];
|
83
103
|
|
104
|
+
$(this).data('value', params.submitValue);
|
84
105
|
row[column.field] = params.submitValue;
|
85
106
|
that.trigger('editable-save', column.field, row, oldValue, $(this));
|
86
107
|
});
|
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
(function ($) {
|
7
7
|
'use strict';
|
8
|
+
var sprintf = $.fn.bootstrapTable.utils.sprintf;
|
8
9
|
|
9
10
|
var TYPE_NAME = {
|
10
11
|
json: 'JSON',
|
@@ -27,6 +28,10 @@
|
|
27
28
|
exportOptions: {}
|
28
29
|
});
|
29
30
|
|
31
|
+
$.extend($.fn.bootstrapTable.defaults.icons, {
|
32
|
+
export: 'glyphicon-export icon-share'
|
33
|
+
});
|
34
|
+
|
30
35
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
31
36
|
_initToolbar = BootstrapTable.prototype.initToolbar;
|
32
37
|
|
@@ -43,9 +48,11 @@
|
|
43
48
|
if (!$export.length) {
|
44
49
|
$export = $([
|
45
50
|
'<div class="export btn-group">',
|
46
|
-
'<button class="btn btn-default
|
51
|
+
'<button class="btn btn-default' +
|
52
|
+
sprintf(' btn-%s', this.options.iconSize) +
|
53
|
+
' dropdown-toggle" ' +
|
47
54
|
'data-toggle="dropdown" type="button">',
|
48
|
-
'<i class="
|
55
|
+
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.export),
|
49
56
|
'<span class="caret"></span>',
|
50
57
|
'</button>',
|
51
58
|
'<ul class="dropdown-menu" role="menu">',
|
@@ -11,8 +11,9 @@
|
|
11
11
|
var sprintf = $.fn.bootstrapTable.utils.sprintf;
|
12
12
|
|
13
13
|
var addOptionToSelectControl = function (selectControl, value, text) {
|
14
|
+
value = $.trim(value);
|
14
15
|
selectControl = $(selectControl.get(selectControl.length - 1));
|
15
|
-
if (
|
16
|
+
if (existOptionInSelectControl(selectControl, value)) {
|
16
17
|
selectControl.append($("<option></option>")
|
17
18
|
.attr("value", value)
|
18
19
|
.text($('<div />').html(text).text()));
|
@@ -35,11 +36,11 @@
|
|
35
36
|
}
|
36
37
|
};
|
37
38
|
|
38
|
-
var
|
39
|
+
var existOptionInSelectControl = function (selectControl, value) {
|
39
40
|
var options = selectControl.get(selectControl.length - 1).options;
|
40
41
|
for (var i = 0; i < options.length; i++) {
|
41
42
|
if (options[i].value === value.toString()) {
|
42
|
-
//The value is
|
43
|
+
//The value is not valid to add
|
43
44
|
return false;
|
44
45
|
}
|
45
46
|
}
|
@@ -74,12 +75,12 @@
|
|
74
75
|
var header = getCurrentHeader(that),
|
75
76
|
searchControls = getCurrentSearchControls(that);
|
76
77
|
|
77
|
-
that.options.
|
78
|
+
that.options.valuesFilterControl = [];
|
78
79
|
|
79
80
|
header.find(searchControls).each(function () {
|
80
|
-
that.options.
|
81
|
+
that.options.valuesFilterControl.push(
|
81
82
|
{
|
82
|
-
field: $(this).
|
83
|
+
field: $(this).closest('[data-field]').data('field'),
|
83
84
|
value: $(this).val()
|
84
85
|
});
|
85
86
|
});
|
@@ -91,10 +92,10 @@
|
|
91
92
|
header = getCurrentHeader(that),
|
92
93
|
searchControls = getCurrentSearchControls(that);
|
93
94
|
|
94
|
-
if (that.options.
|
95
|
+
if (that.options.valuesFilterControl.length > 0) {
|
95
96
|
header.find(searchControls).each(function (index, ele) {
|
96
|
-
field = $(this).
|
97
|
-
result = $.grep(that.options.
|
97
|
+
field = $(this).closest('[data-field]').data('field');
|
98
|
+
result = $.grep(that.options.valuesFilterControl, function (valueObj) {
|
98
99
|
return valueObj.field === field;
|
99
100
|
});
|
100
101
|
|
@@ -105,6 +106,24 @@
|
|
105
106
|
}
|
106
107
|
};
|
107
108
|
|
109
|
+
var collectBootstrapCookies = function cookiesRegex() {
|
110
|
+
var cookies = [],
|
111
|
+
foundCookies = document.cookie.match(/(?:bs.table.)(\w*)/g);
|
112
|
+
|
113
|
+
if (foundCookies) {
|
114
|
+
$.each(foundCookies, function (i, cookie) {
|
115
|
+
if (/./.test(cookie)) {
|
116
|
+
cookie = cookie.split(".").pop();
|
117
|
+
}
|
118
|
+
|
119
|
+
if ($.inArray(cookie, cookies) === -1) {
|
120
|
+
cookies.push(cookie);
|
121
|
+
}
|
122
|
+
});
|
123
|
+
return cookies;
|
124
|
+
}
|
125
|
+
};
|
126
|
+
|
108
127
|
var createControls = function (that, header) {
|
109
128
|
var addedFilterControl = false,
|
110
129
|
isVisible,
|
@@ -122,24 +141,13 @@
|
|
122
141
|
if (!column.filterControl) {
|
123
142
|
html.push('<div style="height: 34px;"></div>');
|
124
143
|
} else {
|
125
|
-
html.push('<div style="margin:
|
144
|
+
html.push('<div style="margin: 0 2px 2px 2px;" class="filterControl">');
|
126
145
|
|
127
|
-
|
146
|
+
var nameControl = column.filterControl.toLowerCase();
|
147
|
+
if (column.searchable && that.options.filterTemplate[nameControl]) {
|
128
148
|
addedFilterControl = true;
|
129
|
-
isVisible = 'visible'
|
130
|
-
|
131
|
-
switch (column.filterControl.toLowerCase()) {
|
132
|
-
case 'input' :
|
133
|
-
html.push(sprintf('<input type="text" class="form-control" style="width: 100%; visibility: %s">', isVisible));
|
134
|
-
break;
|
135
|
-
case 'select':
|
136
|
-
html.push(sprintf('<select class="%s form-control" style="width: 100%; visibility: %s"></select>',
|
137
|
-
column.field, isVisible))
|
138
|
-
break;
|
139
|
-
case 'datepicker':
|
140
|
-
html.push(sprintf('<input type="text" class="date-filter-control %s form-control" style="width: 100%; visibility: %s">',
|
141
|
-
column.field, isVisible));
|
142
|
-
break;
|
149
|
+
isVisible = 'visible';
|
150
|
+
html.push(that.options.filterTemplate[nameControl](that, column.field, isVisible));
|
143
151
|
}
|
144
152
|
}
|
145
153
|
|
@@ -229,14 +237,42 @@
|
|
229
237
|
}
|
230
238
|
};
|
231
239
|
|
240
|
+
var getDirectionOfSelectOptions = function (alignment) {
|
241
|
+
alignment = alignment === undefined ? 'left' : alignment.toLowerCase();
|
242
|
+
|
243
|
+
switch (alignment) {
|
244
|
+
case 'left':
|
245
|
+
return 'ltr';
|
246
|
+
case 'right':
|
247
|
+
return 'rtl';
|
248
|
+
case 'auto':
|
249
|
+
return 'auto';
|
250
|
+
default:
|
251
|
+
return 'ltr'
|
252
|
+
}
|
253
|
+
};
|
254
|
+
|
232
255
|
$.extend($.fn.bootstrapTable.defaults, {
|
233
256
|
filterControl: false,
|
234
257
|
onColumnSearch: function (field, text) {
|
235
258
|
return false;
|
236
259
|
},
|
237
260
|
filterShowClear: false,
|
261
|
+
alignmentSelectControlOptions: undefined,
|
238
262
|
//internal variables
|
239
|
-
|
263
|
+
valuesFilterControl: [],
|
264
|
+
filterTemplate: {
|
265
|
+
input: function (that, field, isVisible) {
|
266
|
+
return sprintf('<input type="text" class="form-control %s" style="width: 100%; visibility: %s">', field, isVisible);
|
267
|
+
},
|
268
|
+
select: function (that, field, isVisible) {
|
269
|
+
return sprintf('<select class="%s form-control" style="width: 100%; visibility: %s" dir="%s"></select>',
|
270
|
+
field, isVisible, getDirectionOfSelectOptions(that.options.alignmentSelectControlOptions))
|
271
|
+
},
|
272
|
+
datepicker: function (that, field, isVisible) {
|
273
|
+
return sprintf('<input type="text" class="date-filter-control %s form-control" style="width: 100%; visibility: %s">', field, isVisible);
|
274
|
+
}
|
275
|
+
}
|
240
276
|
});
|
241
277
|
|
242
278
|
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
|
@@ -250,6 +286,10 @@
|
|
250
286
|
'column-search.bs.table': 'onColumnSearch'
|
251
287
|
});
|
252
288
|
|
289
|
+
$.extend($.fn.bootstrapTable.defaults.icons, {
|
290
|
+
clear: 'glyphicon-trash icon-clear'
|
291
|
+
});
|
292
|
+
|
253
293
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
254
294
|
_init = BootstrapTable.prototype.init,
|
255
295
|
_initToolbar = BootstrapTable.prototype.initToolbar,
|
@@ -258,11 +298,11 @@
|
|
258
298
|
_initSearch = BootstrapTable.prototype.initSearch;
|
259
299
|
|
260
300
|
BootstrapTable.prototype.init = function () {
|
261
|
-
//Make sure that the
|
301
|
+
//Make sure that the filterControl option is set
|
262
302
|
if (this.options.filterControl) {
|
263
303
|
var that = this;
|
264
304
|
//Make sure that the internal variables are set correctly
|
265
|
-
this.options.
|
305
|
+
this.options.valuesFilterControl = [];
|
266
306
|
|
267
307
|
this.$el.on('reset-view.bs.table', function () {
|
268
308
|
//Create controls on $tableHeader if the height is set
|
@@ -282,13 +322,20 @@
|
|
282
322
|
if (that.options.height) {
|
283
323
|
fixHeaderCSS(that);
|
284
324
|
}
|
285
|
-
}).on('column-switch.bs.table', function(
|
325
|
+
}).on('column-switch.bs.table', function() {
|
286
326
|
setValues(that);
|
287
327
|
});
|
288
328
|
}
|
289
329
|
_init.apply(this, Array.prototype.slice.apply(arguments));
|
290
330
|
};
|
291
331
|
|
332
|
+
$.extend($.fn.bootstrapTable.locales, {
|
333
|
+
formatClearFilters: function () {
|
334
|
+
return 'Clear Filters';
|
335
|
+
}
|
336
|
+
});
|
337
|
+
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
|
338
|
+
|
292
339
|
BootstrapTable.prototype.initToolbar = function () {
|
293
340
|
if ((!this.showToolbar) && (this.options.filterControl)) {
|
294
341
|
this.showToolbar = this.options.filterControl;
|
@@ -302,9 +349,9 @@
|
|
302
349
|
|
303
350
|
if (!$btnClear.length) {
|
304
351
|
$btnClear = $([
|
305
|
-
'<button class="btn btn-default
|
306
|
-
|
307
|
-
'<i class="
|
352
|
+
'<button class="btn btn-default" ',
|
353
|
+
sprintf('type="button" title="%s">', this.options.formatClearFilters()),
|
354
|
+
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.clear),
|
308
355
|
'</button>',
|
309
356
|
'</ul>'].join('')).appendTo($btnGroup);
|
310
357
|
|
@@ -361,6 +408,10 @@
|
|
361
408
|
BootstrapTable.prototype.initSearch = function () {
|
362
409
|
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
|
363
410
|
|
411
|
+
if (!this.options.sidePagination === 'server') {
|
412
|
+
return;
|
413
|
+
}
|
414
|
+
|
364
415
|
var that = this;
|
365
416
|
var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
|
366
417
|
|
@@ -370,24 +421,28 @@
|
|
370
421
|
var thisColumn = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)];
|
371
422
|
var fval = fp[key].toLowerCase();
|
372
423
|
var value = item[key];
|
373
|
-
|
424
|
+
|
425
|
+
// Fix #142: search use formated data
|
426
|
+
if (thisColumn && thisColumn.searchFormatter) {
|
427
|
+
value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
|
374
428
|
that.header.formatters[$.inArray(key, that.header.fields)],
|
375
429
|
[value, item, i], value);
|
430
|
+
}
|
376
431
|
|
377
|
-
if(thisColumn.filterStrictSearch){
|
432
|
+
if (thisColumn.filterStrictSearch) {
|
378
433
|
if (!($.inArray(key, that.header.fields) !== -1 &&
|
379
434
|
(typeof value === 'string' || typeof value === 'number') &&
|
380
435
|
value.toString().toLowerCase() === fval.toString().toLowerCase())) {
|
381
436
|
return false;
|
382
437
|
}
|
383
438
|
}
|
384
|
-
else{
|
439
|
+
else {
|
385
440
|
if (!($.inArray(key, that.header.fields) !== -1 &&
|
386
441
|
(typeof value === 'string' || typeof value === 'number') &&
|
387
442
|
(value + '').toLowerCase().indexOf(fval) !== -1)) {
|
388
443
|
return false;
|
389
444
|
}
|
390
|
-
}
|
445
|
+
}
|
391
446
|
}
|
392
447
|
return true;
|
393
448
|
}) : this.data;
|
@@ -396,7 +451,7 @@
|
|
396
451
|
BootstrapTable.prototype.onColumnSearch = function (event) {
|
397
452
|
copyValues(this);
|
398
453
|
var text = $.trim($(event.currentTarget).val());
|
399
|
-
var $field = $(event.currentTarget).
|
454
|
+
var $field = $(event.currentTarget).closest('[data-field]').data('field');
|
400
455
|
|
401
456
|
if ($.isEmptyObject(this.filterColumnsPartial)) {
|
402
457
|
this.filterColumnsPartial = {};
|
@@ -415,22 +470,48 @@
|
|
415
470
|
|
416
471
|
BootstrapTable.prototype.clearFilterControl = function () {
|
417
472
|
if (this.options.filterControl && this.options.filterShowClear) {
|
418
|
-
|
473
|
+
var that = this,
|
474
|
+
cookies = collectBootstrapCookies(),
|
475
|
+
header = getCurrentHeader(that),
|
476
|
+
table = header.closest('table'),
|
477
|
+
controls = header.find(getCurrentSearchControls(that)),
|
478
|
+
search = that.$toolbar.find('.search input'),
|
479
|
+
timeoutId = 0;
|
480
|
+
|
481
|
+
$.each(that.options.valuesFilterControl, function (i, item) {
|
419
482
|
item.value = '';
|
420
483
|
});
|
421
484
|
|
422
|
-
setValues(
|
423
|
-
|
424
|
-
var controls = getCurrentHeader(this).find(getCurrentSearchControls(this)),
|
425
|
-
timeoutId = 0;
|
485
|
+
setValues(that);
|
426
486
|
|
487
|
+
// Clear each type of filter if it exists.
|
488
|
+
// Requires the body to reload each time a type of filter is found because we never know
|
489
|
+
// which ones are going to be present.
|
427
490
|
if (controls.length > 0) {
|
428
491
|
this.filterColumnsPartial = {};
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
492
|
+
$(controls[0]).trigger(controls[0].tagName === 'INPUT' ? 'keyup' : 'change');
|
493
|
+
}
|
494
|
+
|
495
|
+
if (search.length > 0) {
|
496
|
+
that.resetSearch();
|
433
497
|
}
|
498
|
+
|
499
|
+
// use the default sort order if it exists. do nothing if it does not
|
500
|
+
if (that.options.sortName !== table.data('sortName') || that.options.sortOrder !== table.data('sortOrder')) {
|
501
|
+
var sorter = sprintf(header.find('[data-field="%s"]', $(controls[0]).closest('table').data('sortName')));
|
502
|
+
that.onSort(table.data('sortName'), table.data('sortName'));
|
503
|
+
$(sorter).find('.sortable').trigger('click');
|
504
|
+
}
|
505
|
+
|
506
|
+
// clear cookies once the filters are clean
|
507
|
+
clearTimeout(timeoutId);
|
508
|
+
timeoutId = setTimeout(function () {
|
509
|
+
if (cookies && cookies.length > 0) {
|
510
|
+
$.each(cookies, function (i, item) {
|
511
|
+
that.deleteCookie(item);
|
512
|
+
});
|
513
|
+
}
|
514
|
+
}, that.options.searchTimeOut);
|
434
515
|
}
|
435
516
|
};
|
436
517
|
}(jQuery);
|
@@ -0,0 +1,226 @@
|
|
1
|
+
/**
|
2
|
+
* @author: Yura Knoxville
|
3
|
+
* @version: v1.0.0
|
4
|
+
*/
|
5
|
+
|
6
|
+
!function ($) {
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
var initBodyCaller,
|
11
|
+
tableGroups;
|
12
|
+
|
13
|
+
// it only does '%s', and return '' when arguments are undefined
|
14
|
+
var sprintf = function (str) {
|
15
|
+
var args = arguments,
|
16
|
+
flag = true,
|
17
|
+
i = 1;
|
18
|
+
|
19
|
+
str = str.replace(/%s/g, function () {
|
20
|
+
var arg = args[i++];
|
21
|
+
|
22
|
+
if (typeof arg === 'undefined') {
|
23
|
+
flag = false;
|
24
|
+
return '';
|
25
|
+
}
|
26
|
+
return arg;
|
27
|
+
});
|
28
|
+
return flag ? str : '';
|
29
|
+
};
|
30
|
+
|
31
|
+
var groupBy = function (array , f) {
|
32
|
+
var groups = {};
|
33
|
+
array.forEach(function(o) {
|
34
|
+
var group = f(o);
|
35
|
+
groups[group] = groups[group] || [];
|
36
|
+
groups[group].push(o);
|
37
|
+
});
|
38
|
+
|
39
|
+
return groups;
|
40
|
+
};
|
41
|
+
|
42
|
+
$.extend($.fn.bootstrapTable.defaults, {
|
43
|
+
groupBy: false,
|
44
|
+
groupByField: ''
|
45
|
+
});
|
46
|
+
|
47
|
+
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
48
|
+
_initSort = BootstrapTable.prototype.initSort,
|
49
|
+
_initBody = BootstrapTable.prototype.initBody,
|
50
|
+
_updateSelected = BootstrapTable.prototype.updateSelected;
|
51
|
+
|
52
|
+
BootstrapTable.prototype.initSort = function () {
|
53
|
+
_initSort.apply(this, Array.prototype.slice.apply(arguments));
|
54
|
+
|
55
|
+
var that = this;
|
56
|
+
tableGroups = [];
|
57
|
+
|
58
|
+
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
|
59
|
+
|
60
|
+
if ((this.options.sortName != this.options.groupByField)) {
|
61
|
+
this.data.sort(function(a, b) {
|
62
|
+
return a[that.options.groupByField].localeCompare(b[that.options.groupByField]);
|
63
|
+
});
|
64
|
+
}
|
65
|
+
|
66
|
+
var that = this;
|
67
|
+
var groups = groupBy(that.data, function (item) {
|
68
|
+
return [item[that.options.groupByField]];
|
69
|
+
});
|
70
|
+
|
71
|
+
var index = 0;
|
72
|
+
$.each(groups, function(key, value) {
|
73
|
+
tableGroups.push({
|
74
|
+
id: index,
|
75
|
+
name: key
|
76
|
+
});
|
77
|
+
|
78
|
+
value.forEach(function(item) {
|
79
|
+
if (!item._data) {
|
80
|
+
item._data = {};
|
81
|
+
}
|
82
|
+
|
83
|
+
item._data['parent-index'] = index;
|
84
|
+
});
|
85
|
+
|
86
|
+
index++;
|
87
|
+
});
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
BootstrapTable.prototype.initBody = function () {
|
92
|
+
initBodyCaller = true;
|
93
|
+
|
94
|
+
_initBody.apply(this, Array.prototype.slice.apply(arguments));
|
95
|
+
|
96
|
+
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
|
97
|
+
var that = this,
|
98
|
+
checkBox = false,
|
99
|
+
visibleColumns = 0;
|
100
|
+
|
101
|
+
this.columns.forEach(function(column) {
|
102
|
+
if (column.checkbox) {
|
103
|
+
checkBox = true;
|
104
|
+
} else {
|
105
|
+
if (column.visible) {
|
106
|
+
visibleColumns += 1;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
});
|
110
|
+
|
111
|
+
if (this.options.detailView && !this.options.cardView) {
|
112
|
+
visibleColumns += 1;
|
113
|
+
}
|
114
|
+
|
115
|
+
tableGroups.forEach(function(item){
|
116
|
+
var html = [];
|
117
|
+
|
118
|
+
html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
|
119
|
+
|
120
|
+
if (that.options.detailView && !that.options.cardView) {
|
121
|
+
html.push('<td class="detail"></td>');
|
122
|
+
}
|
123
|
+
|
124
|
+
if (checkBox) {
|
125
|
+
html.push('<td class="bs-checkbox">',
|
126
|
+
'<input name="btSelectGroup" type="checkbox" />',
|
127
|
+
'</td>'
|
128
|
+
);
|
129
|
+
}
|
130
|
+
|
131
|
+
html.push('<td',
|
132
|
+
sprintf(' colspan="%s"', visibleColumns),
|
133
|
+
'>', item.name, '</td>'
|
134
|
+
);
|
135
|
+
|
136
|
+
html.push('</tr>');
|
137
|
+
|
138
|
+
that.$body.find('tr[data-parent-index='+item.id+']:first').before($(html.join('')));
|
139
|
+
});
|
140
|
+
|
141
|
+
this.$selectGroup = [];
|
142
|
+
this.$body.find('[name="btSelectGroup"]').each(function() {
|
143
|
+
var self = $(this);
|
144
|
+
|
145
|
+
that.$selectGroup.push({
|
146
|
+
group: self,
|
147
|
+
item: that.$selectItem.filter(function () {
|
148
|
+
return ($(this).closest('tr').data('parent-index') ===
|
149
|
+
self.closest('tr').data('group-index'));
|
150
|
+
})
|
151
|
+
});
|
152
|
+
});
|
153
|
+
|
154
|
+
this.$container.off('click', '.groupBy')
|
155
|
+
.on('click', '.groupBy', function() {
|
156
|
+
$(this).toggleClass('expanded');
|
157
|
+
that.$body.find('tr[data-parent-index='+$(this).closest('tr').data('group-index')+']').toggleClass('hidden');
|
158
|
+
});
|
159
|
+
|
160
|
+
this.$container.off('click', '[name="btSelectGroup"]')
|
161
|
+
.on('click', '[name="btSelectGroup"]', function (event) {
|
162
|
+
event.stopImmediatePropagation();
|
163
|
+
|
164
|
+
var self = $(this);
|
165
|
+
var checked = self.prop('checked');
|
166
|
+
that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'));
|
167
|
+
});
|
168
|
+
}
|
169
|
+
|
170
|
+
initBodyCaller = false;
|
171
|
+
this.updateSelected();
|
172
|
+
};
|
173
|
+
|
174
|
+
BootstrapTable.prototype.updateSelected = function () {
|
175
|
+
if (!initBodyCaller) {
|
176
|
+
_updateSelected.apply(this, Array.prototype.slice.apply(arguments));
|
177
|
+
|
178
|
+
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
|
179
|
+
this.$selectGroup.forEach(function (item) {
|
180
|
+
var checkGroup = item.item.filter(':enabled').length ===
|
181
|
+
item.item.filter(':enabled').filter(':checked').length;
|
182
|
+
|
183
|
+
item.group.prop('checked', checkGroup);
|
184
|
+
});
|
185
|
+
}
|
186
|
+
}
|
187
|
+
};
|
188
|
+
|
189
|
+
BootstrapTable.prototype.getGroupSelections = function (index) {
|
190
|
+
var that = this;
|
191
|
+
|
192
|
+
return $.grep(this.data, function (row) {
|
193
|
+
return (row[that.header.stateField] && (row._data['parent-index'] === index));
|
194
|
+
});
|
195
|
+
};
|
196
|
+
|
197
|
+
BootstrapTable.prototype.checkGroup = function (index) {
|
198
|
+
this.checkGroup_(index, true);
|
199
|
+
};
|
200
|
+
|
201
|
+
BootstrapTable.prototype.uncheckGroup = function (index) {
|
202
|
+
this.checkGroup_(index, false);
|
203
|
+
};
|
204
|
+
|
205
|
+
BootstrapTable.prototype.checkGroup_ = function (index, checked) {
|
206
|
+
var rows;
|
207
|
+
var filter = function() {
|
208
|
+
return ($(this).closest('tr').data('parent-index') === index);
|
209
|
+
};
|
210
|
+
|
211
|
+
if (!checked) {
|
212
|
+
rows = this.getGroupSelections(index);
|
213
|
+
}
|
214
|
+
|
215
|
+
this.$selectItem.filter(filter).prop('checked', checked);
|
216
|
+
|
217
|
+
|
218
|
+
this.updateRows();
|
219
|
+
this.updateSelected();
|
220
|
+
if (checked) {
|
221
|
+
rows = this.getGroupSelections(index);
|
222
|
+
}
|
223
|
+
this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
|
224
|
+
};
|
225
|
+
|
226
|
+
}(jQuery);
|