bootstrap-table-rails 1.10.1 → 1.11.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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bootstrap-table-rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/bootstrap-table-locale-all.js +60 -19
  4. data/vendor/assets/javascripts/bootstrap-table.js +305 -94
  5. data/vendor/assets/javascripts/extensions/bootstrap-table-angular.js +5 -3
  6. data/vendor/assets/javascripts/extensions/bootstrap-table-cookie.js +85 -28
  7. data/vendor/assets/javascripts/extensions/bootstrap-table-copy-rows.js +102 -0
  8. data/vendor/assets/javascripts/extensions/bootstrap-table-editable.js +51 -33
  9. data/vendor/assets/javascripts/extensions/bootstrap-table-export.js +11 -2
  10. data/vendor/assets/javascripts/extensions/bootstrap-table-filter-control.js +216 -71
  11. data/vendor/assets/javascripts/extensions/bootstrap-table-group-by.js +1 -1
  12. data/vendor/assets/javascripts/extensions/bootstrap-table-i18n-enhance.js +34 -0
  13. data/vendor/assets/javascripts/extensions/bootstrap-table-multi-toggle.js +88 -0
  14. data/vendor/assets/javascripts/extensions/bootstrap-table-multiple-search.js +6 -2
  15. data/vendor/assets/javascripts/extensions/bootstrap-table-multiple-sort.js +39 -24
  16. data/vendor/assets/javascripts/extensions/bootstrap-table-natural-sorting.js +12 -2
  17. data/vendor/assets/javascripts/extensions/bootstrap-table-reorder-columns.js +57 -1
  18. data/vendor/assets/javascripts/extensions/bootstrap-table-select2-filter.js +303 -0
  19. data/vendor/assets/javascripts/extensions/bootstrap-table-sticky-header.js +16 -9
  20. data/vendor/assets/javascripts/locale/bootstrap-table-en-US.js +6 -0
  21. data/vendor/assets/javascripts/locale/bootstrap-table-it-IT.js +5 -1
  22. data/vendor/assets/javascripts/locale/bootstrap-table-nl-NL.js +24 -15
  23. data/vendor/assets/javascripts/locale/bootstrap-table-pt-PT.js +18 -3
  24. data/vendor/assets/javascripts/locale/bootstrap-table-zh-CN.js +7 -1
  25. data/vendor/assets/stylesheets/bootstrap-table.css +9 -2
  26. metadata +7 -3
@@ -1,24 +1,27 @@
1
1
  /**
2
2
  * @author: Dennis Hernández
3
3
  * @webSite: http://djhvscf.github.io/Blog
4
- * @version: v1.0.0
4
+ * @version: v2.1.0
5
5
  */
6
6
 
7
- !function ($) {
7
+ (function ($) {
8
8
 
9
9
  'use strict';
10
10
 
11
- var sprintf = $.fn.bootstrapTable.utils.sprintf;
11
+ var sprintf = $.fn.bootstrapTable.utils.sprintf,
12
+ objectKeys = $.fn.bootstrapTable.utils.objectKeys;
12
13
 
13
14
  var addOptionToSelectControl = function (selectControl, value, text) {
14
15
  value = $.trim(value);
15
16
  selectControl = $(selectControl.get(selectControl.length - 1));
16
- if (existOptionInSelectControl(selectControl, value)) {
17
+ if (!existOptionInSelectControl(selectControl, value)) {
17
18
  selectControl.append($("<option></option>")
18
19
  .attr("value", value)
19
20
  .text($('<div />').html(text).text()));
21
+ }
22
+ };
20
23
 
21
- // Sort it. Not overly efficient to do this here
24
+ var sortSelectControl = function (selectControl) {
22
25
  var $opts = selectControl.find('option:gt(0)');
23
26
  $opts.sort(function (a, b) {
24
27
  a = $(a).text().toLowerCase();
@@ -33,7 +36,6 @@
33
36
 
34
37
  selectControl.find('option:gt(0)').remove();
35
38
  selectControl.append($opts);
36
- }
37
39
  };
38
40
 
39
41
  var existOptionInSelectControl = function (selectControl, value) {
@@ -41,12 +43,12 @@
41
43
  for (var i = 0; i < options.length; i++) {
42
44
  if (options[i].value === value.toString()) {
43
45
  //The value is not valid to add
44
- return false;
46
+ return true;
45
47
  }
46
48
  }
47
49
 
48
50
  //If we get here, the value is valid to add
49
- return true;
51
+ return false;
50
52
  };
51
53
 
52
54
  var fixHeaderCSS = function (that) {
@@ -71,6 +73,38 @@
71
73
  return searchControls;
72
74
  };
73
75
 
76
+ var getCursorPosition = function(el) {
77
+ if ($.fn.bootstrapTable.utils.isIEBrowser()) {
78
+ if ($(el).is('input')) {
79
+ var pos = 0;
80
+ if ('selectionStart' in el) {
81
+ pos = el.selectionStart;
82
+ } else if ('selection' in document) {
83
+ el.focus();
84
+ var Sel = document.selection.createRange();
85
+ var SelLength = document.selection.createRange().text.length;
86
+ Sel.moveStart('character', -el.value.length);
87
+ pos = Sel.text.length - SelLength;
88
+ }
89
+ return pos;
90
+ } else {
91
+ return -1;
92
+ }
93
+ } else {
94
+ return -1;
95
+ }
96
+ };
97
+
98
+ var setCursorPosition = function (el, index) {
99
+ if ($.fn.bootstrapTable.utils.isIEBrowser()) {
100
+ if(el.setSelectionRange !== undefined) {
101
+ el.setSelectionRange(index, index);
102
+ } else {
103
+ $(el).val(el.value);
104
+ }
105
+ }
106
+ };
107
+
74
108
  var copyValues = function (that) {
75
109
  var header = getCurrentHeader(that),
76
110
  searchControls = getCurrentSearchControls(that);
@@ -81,7 +115,8 @@
81
115
  that.options.valuesFilterControl.push(
82
116
  {
83
117
  field: $(this).closest('[data-field]').data('field'),
84
- value: $(this).val()
118
+ value: $(this).val(),
119
+ position: getCursorPosition($(this).get(0))
85
120
  });
86
121
  });
87
122
  };
@@ -101,6 +136,7 @@
101
136
 
102
137
  if (result.length > 0) {
103
138
  $(this).val(result[0].value);
139
+ setCursorPosition($(this).get(0), result[0].position);
104
140
  }
105
141
  });
106
142
  }
@@ -124,9 +160,9 @@
124
160
  }
125
161
  };
126
162
 
127
- var initFilterSelectControls = function (bootstrapTable) {
128
- var data = bootstrapTable.options.data,
129
- itemsPerPage = bootstrapTable.pageTo < bootstrapTable.options.data.length ? bootstrapTable.options.data.length : bootstrapTable.pageTo,
163
+ var initFilterSelectControls = function (that) {
164
+ var data = that.options.data,
165
+ itemsPerPage = that.pageTo < that.options.data.length ? that.options.data.length : that.pageTo,
130
166
 
131
167
  isColumnSearchableViaSelect = function (column) {
132
168
  return column.filterControl && column.filterControl.toLowerCase() === 'select' && column.searchable;
@@ -140,29 +176,40 @@
140
176
  return selectControl && selectControl.length > 0;
141
177
  };
142
178
 
143
- for (var i = bootstrapTable.pageFrom - 1; i < bootstrapTable.pageTo; i++) {
144
-
145
- $.each(bootstrapTable.header.fields, function (j, field) {
146
- var column = bootstrapTable.columns[$.fn.bootstrapTable.utils.getFieldIndex(bootstrapTable.columns, field)],
147
- selectControl = $('.' + column.field);
179
+ var z = that.options.pagination ?
180
+ (that.options.sidePagination === 'server' ? that.pageTo : that.options.totalRows) :
181
+ that.pageTo;
148
182
 
183
+ $.each(that.header.fields, function (j, field) {
184
+ var column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, field)],
185
+ selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
149
186
 
150
- if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) {
151
- if (selectControl.get(selectControl.length - 1).options.length === 0) {
152
- //Added the default option
153
- addOptionToSelectControl(selectControl, '', '');
154
- }
187
+ if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) {
188
+ if (selectControl.get(selectControl.length - 1).options.length === 0) {
189
+ //Added the default option
190
+ addOptionToSelectControl(selectControl, '', '');
191
+ }
155
192
 
193
+ var uniqueValues = {};
194
+ for (var i = 0; i < z; i++) {
156
195
  //Added a new value
157
196
  var fieldValue = data[i][field],
158
- formattedValue = $.fn.bootstrapTable.utils.calculateObjectValue(bootstrapTable.header, bootstrapTable.header.formatters[j], [fieldValue, data[i], i], fieldValue);
197
+ formattedValue = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[j], [fieldValue, data[i], i], fieldValue);
159
198
 
160
- addOptionToSelectControl(selectControl, fieldValue, formattedValue);
199
+ uniqueValues[formattedValue] = fieldValue;
200
+ }
201
+ for (var key in uniqueValues) {
202
+ addOptionToSelectControl(selectControl, uniqueValues[key], key);
161
203
  }
162
- });
163
- }
164
204
 
165
- }
205
+ sortSelectControl(selectControl);
206
+ }
207
+ });
208
+ };
209
+
210
+ var escapeID = function( id ) {
211
+ return String(id).replace( /(:|\.|\[|\]|,)/g, "\\$1" );
212
+ };
166
213
 
167
214
  var createControls = function (that, header) {
168
215
  var addedFilterControl = false,
@@ -198,29 +245,48 @@
198
245
  return false;
199
246
  }
200
247
  });
248
+
201
249
  if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {
202
- var filterDataType = column.filterData.substring(0, 3);
203
- var filterDataSource = column.filterData.substring(4, column.filterData.length);
204
- var selectControl = $('.' + column.field);
205
- addOptionToSelectControl(selectControl, '', '');
250
+ var filterDataType = getFilterDataMethod(filterDataMethods, column.filterData.substring(0, column.filterData.indexOf(':')));
251
+ var filterDataSource, selectControl;
252
+
253
+ if (filterDataType !== null) {
254
+ filterDataSource = column.filterData.substring(column.filterData.indexOf(':') + 1, column.filterData.length);
255
+ selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
206
256
 
257
+ addOptionToSelectControl(selectControl, '', '');
258
+ filterDataType(filterDataSource, selectControl);
259
+ } else {
260
+ throw new SyntaxError('Error. You should use any of these allowed filter data methods: var, json, url.' + ' Use like this: var: {key: "value"}');
261
+ }
262
+
263
+ var variableValues, key;
207
264
  switch (filterDataType) {
208
265
  case 'url':
209
266
  $.ajax({
210
267
  url: filterDataSource,
211
268
  dataType: 'json',
212
269
  success: function (data) {
213
- $.each(data, function (key, value) {
214
- addOptionToSelectControl(selectControl, key, value);
215
- });
270
+ for (var key in data) {
271
+ addOptionToSelectControl(selectControl, key, data[key]);
272
+ }
273
+ sortSelectControl(selectControl);
216
274
  }
217
275
  });
218
276
  break;
219
277
  case 'var':
220
- var variableValues = window[filterDataSource];
221
- for (var key in variableValues) {
278
+ variableValues = window[filterDataSource];
279
+ for (key in variableValues) {
222
280
  addOptionToSelectControl(selectControl, key, variableValues[key]);
223
281
  }
282
+ sortSelectControl(selectControl);
283
+ break;
284
+ case 'jso':
285
+ variableValues = JSON.parse(filterDataSource);
286
+ for (key in variableValues) {
287
+ addOptionToSelectControl(selectControl, key, variableValues[key]);
288
+ }
289
+ sortSelectControl(selectControl);
224
290
  break;
225
291
  }
226
292
  }
@@ -264,7 +330,7 @@
264
330
  if (header.find('.date-filter-control').length > 0) {
265
331
  $.each(that.columns, function (i, column) {
266
332
  if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'datepicker') {
267
- header.find('.date-filter-control.' + column.field).datepicker(column.filterDatepickerOptions)
333
+ header.find('.date-filter-control.bootstrap-table-filter-control-' + column.field).datepicker(column.filterDatepickerOptions)
268
334
  .on('changeDate', function (e) {
269
335
  //Fired the keyup event
270
336
  $(e.currentTarget).keyup();
@@ -288,10 +354,50 @@
288
354
  case 'auto':
289
355
  return 'auto';
290
356
  default:
291
- return 'ltr'
357
+ return 'ltr';
292
358
  }
293
359
  };
294
360
 
361
+ var filterDataMethods =
362
+ {
363
+ 'var': function (filterDataSource, selectControl) {
364
+ var variableValues = window[filterDataSource];
365
+ for (var key in variableValues) {
366
+ addOptionToSelectControl(selectControl, key, variableValues[key]);
367
+ }
368
+ sortSelectControl(selectControl);
369
+ },
370
+ 'url': function (filterDataSource, selectControl) {
371
+ $.ajax({
372
+ url: filterDataSource,
373
+ dataType: 'json',
374
+ success: function (data) {
375
+ for (var key in data) {
376
+ addOptionToSelectControl(selectControl, key, data[key]);
377
+ }
378
+ sortSelectControl(selectControl);
379
+ }
380
+ });
381
+ },
382
+ 'json':function (filterDataSource, selectControl) {
383
+ var variableValues = JSON.parse(filterDataSource);
384
+ for (var key in variableValues) {
385
+ addOptionToSelectControl(selectControl, key, variableValues[key]);
386
+ }
387
+ sortSelectControl(selectControl);
388
+ }
389
+ };
390
+
391
+ var getFilterDataMethod = function (objFilterDataMethod, searchTerm) {
392
+ var keys = Object.keys(objFilterDataMethod);
393
+ for (var i = 0; i < keys.length; i++) {
394
+ if (keys[i] === searchTerm) {
395
+ return objFilterDataMethod[searchTerm];
396
+ }
397
+ }
398
+ return null;
399
+ };
400
+
295
401
  $.extend($.fn.bootstrapTable.defaults, {
296
402
  filterControl: false,
297
403
  onColumnSearch: function (field, text) {
@@ -299,27 +405,28 @@
299
405
  },
300
406
  filterShowClear: false,
301
407
  alignmentSelectControlOptions: undefined,
302
- //internal variables
303
- valuesFilterControl: [],
304
408
  filterTemplate: {
305
409
  input: function (that, field, isVisible) {
306
- return sprintf('<input type="text" class="form-control %s" style="width: 100%; visibility: %s">', field, isVisible);
410
+ return sprintf('<input type="text" class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s">', field, isVisible);
307
411
  },
308
412
  select: function (that, field, isVisible) {
309
- return sprintf('<select class="%s form-control" style="width: 100%; visibility: %s" dir="%s"></select>',
310
- field, isVisible, getDirectionOfSelectOptions(that.options.alignmentSelectControlOptions))
413
+ return sprintf('<select class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" dir="%s"></select>',
414
+ field, isVisible, getDirectionOfSelectOptions(that.options.alignmentSelectControlOptions));
311
415
  },
312
416
  datepicker: function (that, field, isVisible) {
313
- return sprintf('<input type="text" class="date-filter-control %s form-control" style="width: 100%; visibility: %s">', field, isVisible);
417
+ return sprintf('<input type="text" class="form-control date-filter-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s">', field, isVisible);
314
418
  }
315
- }
419
+ },
420
+ //internal variables
421
+ valuesFilterControl: []
316
422
  });
317
423
 
318
424
  $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
319
425
  filterControl: undefined,
320
426
  filterData: undefined,
321
427
  filterDatepickerOptions: undefined,
322
- filterStrictSearch: false
428
+ filterStrictSearch: false,
429
+ filterStartsWithSearch: false
323
430
  });
324
431
 
325
432
  $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
@@ -330,6 +437,13 @@
330
437
  clear: 'glyphicon-trash icon-clear'
331
438
  });
332
439
 
440
+ $.extend($.fn.bootstrapTable.locales, {
441
+ formatClearFilters: function () {
442
+ return 'Clear Filters';
443
+ }
444
+ });
445
+ $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
446
+
333
447
  var BootstrapTable = $.fn.bootstrapTable.Constructor,
334
448
  _init = BootstrapTable.prototype.init,
335
449
  _initToolbar = BootstrapTable.prototype.initToolbar,
@@ -341,6 +455,12 @@
341
455
  //Make sure that the filterControl option is set
342
456
  if (this.options.filterControl) {
343
457
  var that = this;
458
+
459
+ // Compatibility: IE < 9 and old browsers
460
+ if (!Object.keys) {
461
+ objectKeys();
462
+ }
463
+
344
464
  //Make sure that the internal variables are set correctly
345
465
  this.options.valuesFilterControl = [];
346
466
 
@@ -369,31 +489,22 @@
369
489
  _init.apply(this, Array.prototype.slice.apply(arguments));
370
490
  };
371
491
 
372
- $.extend($.fn.bootstrapTable.locales, {
373
- formatClearFilters: function () {
374
- return 'Clear Filters';
375
- }
376
- });
377
- $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
378
-
379
492
  BootstrapTable.prototype.initToolbar = function () {
380
- if ((!this.showToolbar) && (this.options.filterControl)) {
381
- this.showToolbar = this.options.filterControl;
382
- }
493
+ this.showToolbar = this.options.filterControl && this.options.filterShowClear;
383
494
 
384
495
  _initToolbar.apply(this, Array.prototype.slice.apply(arguments));
385
496
 
386
497
  if (this.options.filterControl && this.options.filterShowClear) {
387
498
  var $btnGroup = this.$toolbar.find('>.btn-group'),
388
- $btnClear = $btnGroup.find('div.export');
499
+ $btnClear = $btnGroup.find('.filter-show-clear');
389
500
 
390
501
  if (!$btnClear.length) {
391
- $btnClear = $([
392
- '<button class="btn btn-default" ',
502
+ $btnClear = $([
503
+ '<button class="btn btn-default filter-show-clear" ',
393
504
  sprintf('type="button" title="%s">', this.options.formatClearFilters()),
394
505
  sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.clear),
395
- '</button>',
396
- '</ul>'].join('')).appendTo($btnGroup);
506
+ '</button>'
507
+ ].join('')).appendTo($btnGroup);
397
508
 
398
509
  $btnClear.off('click').on('click', $.proxy(this.clearFilterControl, this));
399
510
  }
@@ -418,7 +529,7 @@
418
529
  BootstrapTable.prototype.initSearch = function () {
419
530
  _initSearch.apply(this, Array.prototype.slice.apply(arguments));
420
531
 
421
- if (!this.options.sidePagination === 'server') {
532
+ if (this.options.sidePagination === 'server') {
422
533
  return;
423
534
  }
424
535
 
@@ -431,7 +542,7 @@
431
542
  var thisColumn = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)];
432
543
  var fval = fp[key].toLowerCase();
433
544
  var value = item[key];
434
-
545
+
435
546
  // Fix #142: search use formated data
436
547
  if (thisColumn && thisColumn.searchFormatter) {
437
548
  value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
@@ -445,8 +556,13 @@
445
556
  value.toString().toLowerCase() === fval.toString().toLowerCase())) {
446
557
  return false;
447
558
  }
448
- }
449
- else {
559
+ } else if (thisColumn.filterStartsWithSearch) {
560
+ if (!($.inArray(key, that.header.fields) !== -1 &&
561
+ (typeof value === 'string' || typeof value === 'number') &&
562
+ (value + '').toLowerCase().indexOf(fval) === 0)) {
563
+ return false;
564
+ }
565
+ } else {
450
566
  if (!($.inArray(key, that.header.fields) !== -1 &&
451
567
  (typeof value === 'string' || typeof value === 'number') &&
452
568
  (value + '').toLowerCase().indexOf(fval) !== -1)) {
@@ -458,7 +574,24 @@
458
574
  }) : this.data;
459
575
  };
460
576
 
577
+ BootstrapTable.prototype.initColumnSearch = function(filterColumnsDefaults) {
578
+ copyValues(this);
579
+
580
+ if (filterColumnsDefaults) {
581
+ this.filterColumnsPartial = filterColumnsDefaults;
582
+ this.updatePagination();
583
+
584
+ for (var filter in filterColumnsDefaults) {
585
+ this.trigger('column-search', filter, filterColumnsDefaults[filter]);
586
+ }
587
+ }
588
+ };
589
+
461
590
  BootstrapTable.prototype.onColumnSearch = function (event) {
591
+ if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
592
+ return;
593
+ }
594
+
462
595
  copyValues(this);
463
596
  var text = $.trim($(event.currentTarget).val());
464
597
  var $field = $(event.currentTarget).closest('[data-field]').data('field');
@@ -472,9 +605,15 @@
472
605
  delete this.filterColumnsPartial[$field];
473
606
  }
474
607
 
608
+ // if the searchText is the same as the previously selected column value,
609
+ // bootstrapTable will not try searching again (even though the selected column
610
+ // may be different from the previous search). As a work around
611
+ // we're manually appending some text to bootrap's searchText field
612
+ // to guarantee that it will perform a search again when we call this.onSearch(event)
613
+ this.searchText += "randomText";
614
+
475
615
  this.options.pageNumber = 1;
476
616
  this.onSearch(event);
477
- this.updatePagination();
478
617
  this.trigger('column-search', $field, text);
479
618
  };
480
619
 
@@ -500,6 +639,8 @@
500
639
  if (controls.length > 0) {
501
640
  this.filterColumnsPartial = {};
502
641
  $(controls[0]).trigger(controls[0].tagName === 'INPUT' ? 'keyup' : 'change');
642
+ } else {
643
+ return;
503
644
  }
504
645
 
505
646
  if (search.length > 0) {
@@ -508,9 +649,11 @@
508
649
 
509
650
  // use the default sort order if it exists. do nothing if it does not
510
651
  if (that.options.sortName !== table.data('sortName') || that.options.sortOrder !== table.data('sortOrder')) {
511
- var sorter = sprintf(header.find('[data-field="%s"]', $(controls[0]).closest('table').data('sortName')));
512
- that.onSort(table.data('sortName'), table.data('sortName'));
513
- $(sorter).find('.sortable').trigger('click');
652
+ var sorter = header.find(sprintf('[data-field="%s"]', $(controls[0]).closest('table').data('sortName')));
653
+ if (sorter.length > 0) {
654
+ that.onSort(table.data('sortName'), table.data('sortName'));
655
+ $(sorter).find('.sortable').trigger('click');
656
+ }
514
657
  }
515
658
 
516
659
  // clear cookies once the filters are clean
@@ -518,10 +661,12 @@
518
661
  timeoutId = setTimeout(function () {
519
662
  if (cookies && cookies.length > 0) {
520
663
  $.each(cookies, function (i, item) {
521
- that.deleteCookie(item);
664
+ if (that.deleteCookie !== undefined) {
665
+ that.deleteCookie(item);
666
+ }
522
667
  });
523
668
  }
524
669
  }, that.options.searchTimeOut);
525
670
  }
526
671
  };
527
- }(jQuery);
672
+ })(jQuery);