bootstrap-table-rails 1.10.1 → 1.11.0

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