bootstrap-table-rails 1.9.1 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|