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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d2b9beb426cf9b17643e50bc3734bb52bac2ac8
4
- data.tar.gz: 09b330bad1cdad021c3a889f19025acb09c7786e
3
+ metadata.gz: c05b4195ad766c3b26f0f2485f0b973862ef2728
4
+ data.tar.gz: 25a78fa1c75f7eef2d54392fd72d1414353ed683
5
5
  SHA512:
6
- metadata.gz: 13d4cf255186a97d28d8d93ef23db6f273c0f4036577a8b784c1c1eb593ef6c62eaa43608d0bbb59eb4a6a04d6c3f1d5279619a9a0aff040017e153517855a71
7
- data.tar.gz: 5a63a0f8ab2bdfecd95ee8cf6958cb60d1205f73176db93538e56581ca92c053b15a84402513144ff28ccbec0e30e61797060521d660fafb2c2904565897062a
6
+ metadata.gz: 039327619e54a229bc6ea5841c8709c6119cfaf394f3af7e080373605e33fa21b5934406f2886ff0ac326650522f670529f05af389a59432c0fa56a32ea88fae
7
+ data.tar.gz: 3c06f123c2e71d448bce802383704186a118147215cd30ce2fe5da2747ec5ce1e56b2a61e82317c18c2b6dd19177a579e4d49ff26b6b1d57eaa814c2463c18a6
@@ -1,7 +1,7 @@
1
1
  module Bootstrap
2
2
  module Table
3
3
  module Rails
4
- VERSION = "1.10.1"
4
+ VERSION = "1.11.0"
5
5
  end
6
6
  end
7
7
  end
@@ -311,6 +311,12 @@
311
311
  },
312
312
  formatAllRows: function () {
313
313
  return 'All';
314
+ },
315
+ formatExport: function () {
316
+ return 'Export data';
317
+ },
318
+ formatClearFilters: function () {
319
+ return 'Clear filters';
314
320
  }
315
321
  };
316
322
 
@@ -842,6 +848,7 @@
842
848
  * Bootstrap Table Italian translation
843
849
  * Author: Davide Renzi<davide.renzi@gmail.com>
844
850
  * Author: Davide Borsatto <davide.borsatto@gmail.com>
851
+ * Author: Alessio Felicioni <alessio.felicioni@gmail.com>
845
852
  */
846
853
  (function ($) {
847
854
  'use strict';
@@ -854,7 +861,7 @@
854
861
  return pageNumber + ' elementi per pagina';
855
862
  },
856
863
  formatShowingRows: function (pageFrom, pageTo, totalRows) {
857
- return 'Pagina ' + pageFrom + ' di ' + pageTo + ' (' + totalRows + ' records)';
864
+ return 'Pagina ' + pageFrom + ' di ' + pageTo + ' (' + totalRows + ' elementi)';
858
865
  },
859
866
  formatSearch: function () {
860
867
  return 'Cerca';
@@ -870,6 +877,9 @@
870
877
  },
871
878
  formatColumns: function () {
872
879
  return 'Colonne';
880
+ },
881
+ formatAllRows: function () {
882
+ return 'Tutto';
873
883
  }
874
884
  };
875
885
 
@@ -1083,39 +1093,48 @@
1083
1093
  * Bootstrap Table Dutch translation
1084
1094
  * Author: Your Name <info@a2hankes.nl>
1085
1095
  */
1086
- (function ($) {
1096
+ (function($) {
1087
1097
  'use strict';
1088
1098
 
1089
1099
  $.fn.bootstrapTable.locales['nl-NL'] = {
1090
- formatLoadingMessage: function () {
1100
+ formatLoadingMessage: function() {
1091
1101
  return 'Laden, even geduld...';
1092
1102
  },
1093
- formatRecordsPerPage: function (pageNumber) {
1103
+ formatRecordsPerPage: function(pageNumber) {
1094
1104
  return pageNumber + ' records per pagina';
1095
1105
  },
1096
- formatShowingRows: function (pageFrom, pageTo, totalRows) {
1106
+ formatShowingRows: function(pageFrom, pageTo, totalRows) {
1097
1107
  return 'Toon ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' record' + ((totalRows > 1) ? 's' : '');
1098
1108
  },
1099
- formatDetailPagination: function (totalRows) {
1109
+ formatDetailPagination: function(totalRows) {
1100
1110
  return 'Toon ' + totalRows + ' record' + ((totalRows > 1) ? 's' : '');
1101
1111
  },
1102
- formatSearch: function () {
1112
+ formatSearch: function() {
1103
1113
  return 'Zoeken';
1104
1114
  },
1105
- formatNoMatches: function () {
1115
+ formatNoMatches: function() {
1106
1116
  return 'Geen resultaten gevonden';
1107
1117
  },
1108
- formatRefresh: function () {
1109
- return 'Vernieuwen';
1118
+ formatRefresh: function() {
1119
+ return 'Vernieuwen';
1110
1120
  },
1111
- formatToggle: function () {
1112
- return 'Omschakelen';
1121
+ formatToggle: function() {
1122
+ return 'Omschakelen';
1113
1123
  },
1114
- formatColumns: function () {
1115
- return 'Kolommen';
1124
+ formatColumns: function() {
1125
+ return 'Kolommen';
1116
1126
  },
1117
- formatAllRows: function () {
1118
- return 'Alle';
1127
+ formatAllRows: function() {
1128
+ return 'Alle';
1129
+ },
1130
+ formatPaginationSwitch: function() {
1131
+ return 'Verberg/Toon paginatie';
1132
+ },
1133
+ formatExport: function() {
1134
+ return 'Exporteer data';
1135
+ },
1136
+ formatClearFilters: function() {
1137
+ return 'Verwijder filters';
1119
1138
  }
1120
1139
  };
1121
1140
 
@@ -1212,19 +1231,34 @@
1212
1231
 
1213
1232
  $.fn.bootstrapTable.locales['pt-PT'] = {
1214
1233
  formatLoadingMessage: function () {
1215
- return 'A carregar, aguarde...';
1234
+ return 'A carregar, por favor aguarde...';
1216
1235
  },
1217
1236
  formatRecordsPerPage: function (pageNumber) {
1218
- return pageNumber + ' registos por página';
1237
+ return pageNumber + ' registos por p&aacute;gina';
1219
1238
  },
1220
1239
  formatShowingRows: function (pageFrom, pageTo, totalRows) {
1221
- return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';
1240
+ return 'A mostrar ' + pageFrom + ' at&eacute; ' + pageTo + ' de ' + totalRows + ' linhas';
1222
1241
  },
1223
1242
  formatSearch: function () {
1224
1243
  return 'Pesquisa';
1225
1244
  },
1226
1245
  formatNoMatches: function () {
1227
1246
  return 'Nenhum registo encontrado';
1247
+ },
1248
+ formatPaginationSwitch: function () {
1249
+ return 'Esconder/Mostrar pagina&ccedil&atilde;o';
1250
+ },
1251
+ formatRefresh: function () {
1252
+ return 'Atualizar';
1253
+ },
1254
+ formatToggle: function () {
1255
+ return 'Alternar';
1256
+ },
1257
+ formatColumns: function () {
1258
+ return 'Colunas';
1259
+ },
1260
+ formatAllRows: function () {
1261
+ return 'Tudo';
1228
1262
  }
1229
1263
  };
1230
1264
 
@@ -1609,12 +1643,19 @@
1609
1643
  },
1610
1644
  formatColumns: function () {
1611
1645
  return '列';
1646
+ },
1647
+ formatExport: function () {
1648
+ return '导出数据';
1649
+ },
1650
+ formatClearFilters: function () {
1651
+ return '清空过滤';
1612
1652
  }
1613
1653
  };
1614
1654
 
1615
1655
  $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
1616
1656
 
1617
1657
  })(jQuery);
1658
+
1618
1659
  /**
1619
1660
  * Bootstrap Table Chinese translation
1620
1661
  * Author: Zhixin Wen<wenzhixin2010@gmail.com>
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * @author zhixin wen <wenzhixin2010@gmail.com>
3
- * version: 1.10.1
3
+ * version: 1.11.0
4
4
  * https://github.com/wenzhixin/bootstrap-table/
5
5
  */
6
6
 
7
- !function ($) {
7
+ (function ($) {
8
8
  'use strict';
9
9
 
10
10
  // TOOLS DEFINITION
@@ -229,6 +229,49 @@
229
229
  return !!(navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./));
230
230
  };
231
231
 
232
+ var objectKeys = function () {
233
+ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
234
+ if (!Object.keys) {
235
+ Object.keys = (function() {
236
+ var hasOwnProperty = Object.prototype.hasOwnProperty,
237
+ hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
238
+ dontEnums = [
239
+ 'toString',
240
+ 'toLocaleString',
241
+ 'valueOf',
242
+ 'hasOwnProperty',
243
+ 'isPrototypeOf',
244
+ 'propertyIsEnumerable',
245
+ 'constructor'
246
+ ],
247
+ dontEnumsLength = dontEnums.length;
248
+
249
+ return function(obj) {
250
+ if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
251
+ throw new TypeError('Object.keys called on non-object');
252
+ }
253
+
254
+ var result = [], prop, i;
255
+
256
+ for (prop in obj) {
257
+ if (hasOwnProperty.call(obj, prop)) {
258
+ result.push(prop);
259
+ }
260
+ }
261
+
262
+ if (hasDontEnumBug) {
263
+ for (i = 0; i < dontEnumsLength; i++) {
264
+ if (hasOwnProperty.call(obj, dontEnums[i])) {
265
+ result.push(dontEnums[i]);
266
+ }
267
+ }
268
+ }
269
+ return result;
270
+ };
271
+ }());
272
+ }
273
+ };
274
+
232
275
  // BOOTSTRAP TABLE CLASS DEFINITION
233
276
  // ======================
234
277
 
@@ -249,6 +292,7 @@
249
292
  undefinedText: '-',
250
293
  sortName: undefined,
251
294
  sortOrder: 'asc',
295
+ sortStable: false,
252
296
  striped: false,
253
297
  columns: [[]],
254
298
  data: [],
@@ -313,6 +357,7 @@
313
357
  searchTimeOut: 500,
314
358
  searchText: '',
315
359
  iconSize: undefined,
360
+ buttonsClass: 'default',
316
361
  iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)
317
362
  icons: {
318
363
  paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
@@ -324,6 +369,10 @@
324
369
  detailClose: 'glyphicon-minus icon-minus'
325
370
  },
326
371
 
372
+ customSearch: $.noop,
373
+
374
+ customSort: $.noop,
375
+
327
376
  rowStyle: function (row, index) {
328
377
  return {};
329
378
  },
@@ -332,6 +381,10 @@
332
381
  return {};
333
382
  },
334
383
 
384
+ footerStyle: function (row, index) {
385
+ return {};
386
+ },
387
+
335
388
  onAll: function (name, args) {
336
389
  return false;
337
390
  },
@@ -404,19 +457,22 @@
404
457
  onRefreshOptions: function (options) {
405
458
  return false;
406
459
  },
460
+ onRefresh: function (params) {
461
+ return false;
462
+ },
407
463
  onResetView: function () {
408
464
  return false;
409
465
  }
410
466
  };
411
467
 
412
- BootstrapTable.LOCALES = [];
468
+ BootstrapTable.LOCALES = {};
413
469
 
414
- BootstrapTable.LOCALES['en-US'] = BootstrapTable.LOCALES['en'] = {
470
+ BootstrapTable.LOCALES['en-US'] = BootstrapTable.LOCALES.en = {
415
471
  formatLoadingMessage: function () {
416
472
  return 'Loading, please wait...';
417
473
  },
418
474
  formatRecordsPerPage: function (pageNumber) {
419
- return sprintf('%s records per page', pageNumber);
475
+ return sprintf('%s rows per page', pageNumber);
420
476
  },
421
477
  formatShowingRows: function (pageFrom, pageTo, totalRows) {
422
478
  return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);
@@ -503,7 +559,8 @@
503
559
  'expand-row.bs.table': 'onExpandRow',
504
560
  'collapse-row.bs.table': 'onCollapseRow',
505
561
  'refresh-options.bs.table': 'onRefreshOptions',
506
- 'reset-view.bs.table': 'onResetView'
562
+ 'reset-view.bs.table': 'onResetView',
563
+ 'refresh.bs.table': 'onRefresh'
507
564
  };
508
565
 
509
566
  BootstrapTable.prototype.init = function () {
@@ -524,7 +581,7 @@
524
581
  if (this.options.locale) {
525
582
  var parts = this.options.locale.split(/-|_/);
526
583
  parts[0].toLowerCase();
527
- parts[1] && parts[1].toUpperCase();
584
+ if (parts[1]) parts[1].toUpperCase();
528
585
  if ($.fn.bootstrapTable.locales[this.options.locale]) {
529
586
  // locale as requested
530
587
  $.extend(this.options, $.fn.bootstrapTable.locales[this.options.locale]);
@@ -594,6 +651,10 @@
594
651
  var column = [];
595
652
 
596
653
  $(this).find('th').each(function () {
654
+ // Fix #2014 - getFieldIndex and elsewhere assume this is string, causes issues if not
655
+ if (typeof $(this).data('field') !== 'undefined') {
656
+ $(this).data('field', $(this).data('field') + '');
657
+ }
597
658
  column.push($.extend({}, {
598
659
  title: $(this).html(),
599
660
  'class': $(this).attr('class'),
@@ -628,7 +689,8 @@
628
689
  return;
629
690
  }
630
691
 
631
- this.$el.find('>tbody>tr').each(function () {
692
+ var m = [];
693
+ this.$el.find('>tbody>tr').each(function (y) {
632
694
  var row = {};
633
695
 
634
696
  // save tr's id, class and data-* attributes
@@ -636,20 +698,38 @@
636
698
  row._class = $(this).attr('class');
637
699
  row._data = getRealDataAttr($(this).data());
638
700
 
639
- $(this).find('td').each(function (i) {
640
- var field = that.columns[i].field;
701
+ $(this).find('>td').each(function (x) {
702
+ var $this = $(this),
703
+ cspan = +$this.attr('colspan') || 1,
704
+ rspan = +$this.attr('rowspan') || 1,
705
+ tx, ty;
706
+
707
+ for (; m[y] && m[y][x]; x++); //skip already occupied cells in current row
708
+
709
+ for (tx = x; tx < x + cspan; tx++) { //mark matrix elements occupied by current cell with true
710
+ for (ty = y; ty < y + rspan; ty++) {
711
+ if (!m[ty]) { //fill missing rows
712
+ m[ty] = [];
713
+ }
714
+ m[ty][tx] = true;
715
+ }
716
+ }
717
+
718
+ var field = that.columns[x].field;
641
719
 
642
720
  row[field] = $(this).html();
643
721
  // save td's id, class and data-* attributes
644
722
  row['_' + field + '_id'] = $(this).attr('id');
645
723
  row['_' + field + '_class'] = $(this).attr('class');
646
724
  row['_' + field + '_rowspan'] = $(this).attr('rowspan');
725
+ row['_' + field + '_colspan'] = $(this).attr('colspan');
647
726
  row['_' + field + '_title'] = $(this).attr('title');
648
727
  row['_' + field + '_data'] = getRealDataAttr($(this).data());
649
728
  });
650
729
  data.push(row);
651
730
  });
652
731
  this.options.data = data;
732
+ if (data.length) this.fromHtml = true;
653
733
  };
654
734
 
655
735
  BootstrapTable.prototype.initHeader = function () {
@@ -672,7 +752,7 @@
672
752
  $.each(this.options.columns, function (i, columns) {
673
753
  html.push('<tr>');
674
754
 
675
- if (i == 0 && !that.options.cardView && that.options.detailView) {
755
+ if (i === 0 && !that.options.cardView && that.options.detailView) {
676
756
  html.push(sprintf('<th class="detail" rowspan="%s"><div class="fht-cell"></div></th>',
677
757
  that.options.columns.length));
678
758
  }
@@ -769,8 +849,11 @@
769
849
  });
770
850
  this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) {
771
851
  var target = $(this);
772
- if (target.closest('.bootstrap-table')[0] !== that.$container[0])
773
- return false;
852
+
853
+ if (that.options.detailView) {
854
+ if (target.closest('.bootstrap-table')[0] !== that.$container[0])
855
+ return false;
856
+ }
774
857
 
775
858
  if (that.options.sortable && target.parent().data().sortable) {
776
859
  that.onSort(event);
@@ -786,6 +869,7 @@
786
869
  }
787
870
  });
788
871
 
872
+ $(window).off('resize.bootstrap-table');
789
873
  if (!this.options.showHeader || this.options.cardView) {
790
874
  this.$header.hide();
791
875
  this.$tableHeader.hide();
@@ -796,6 +880,7 @@
796
880
  this.$tableLoading.css('top', this.$header.outerHeight() + 1);
797
881
  // Assign the correct sortable arrow
798
882
  this.getCaret();
883
+ $(window).on('resize.bootstrap-table', $.proxy(this.resetWidth, this));
799
884
  }
800
885
 
801
886
  this.$selectAll = this.$header.find('[name="btSelectAll"]');
@@ -848,7 +933,18 @@
848
933
  order = this.options.sortOrder === 'desc' ? -1 : 1,
849
934
  index = $.inArray(this.options.sortName, this.header.fields);
850
935
 
936
+ if (this.options.customSort !== $.noop) {
937
+ this.options.customSort.apply(this, [this.options.sortName, this.options.sortOrder]);
938
+ return;
939
+ }
940
+
851
941
  if (index !== -1) {
942
+ if (this.options.sortStable) {
943
+ $.each(this.data, function (i, row) {
944
+ if (!row.hasOwnProperty('_position')) row._position = i;
945
+ });
946
+ }
947
+
852
948
  this.data.sort(function (a, b) {
853
949
  if (that.header.sortNames[index]) {
854
950
  name = that.header.sortNames[index];
@@ -869,6 +965,11 @@
869
965
  bb = '';
870
966
  }
871
967
 
968
+ if (that.options.sortStable && aa === bb) {
969
+ aa = a._position;
970
+ bb = b._position;
971
+ }
972
+
872
973
  // IF both values are numeric, do a numeric comparison
873
974
  if ($.isNumeric(aa) && $.isNumeric(bb)) {
874
975
  // Convert numerical values form string to float.
@@ -934,13 +1035,13 @@
934
1035
  $search,
935
1036
  switchableCount = 0;
936
1037
 
937
- if (this.$toolbar.find('.bars').children().length) {
1038
+ if (this.$toolbar.find('.bs-bars').children().length) {
938
1039
  $('body').append($(this.options.toolbar));
939
1040
  }
940
1041
  this.$toolbar.html('');
941
1042
 
942
1043
  if (typeof this.options.toolbar === 'string' || typeof this.options.toolbar === 'object') {
943
- $(sprintf('<div class="bars pull-%s"></div>', this.options.toolbarAlign))
1044
+ $(sprintf('<div class="bs-bars pull-%s"></div>', this.options.toolbarAlign))
944
1045
  .appendTo(this.$toolbar)
945
1046
  .append($(this.options.toolbar));
946
1047
  }
@@ -954,14 +1055,18 @@
954
1055
  }
955
1056
 
956
1057
  if (this.options.showPaginationSwitch) {
957
- html.push(sprintf('<button class="btn btn-default" type="button" name="paginationSwitch" title="%s">',
1058
+ html.push(sprintf('<button class="btn' +
1059
+ sprintf(' btn-%s', this.options.buttonsClass) +
1060
+ sprintf(' btn-%s', this.options.iconSize) +
1061
+ '" type="button" name="paginationSwitch" title="%s">',
958
1062
  this.options.formatPaginationSwitch()),
959
1063
  sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),
960
1064
  '</button>');
961
1065
  }
962
1066
 
963
1067
  if (this.options.showRefresh) {
964
- html.push(sprintf('<button class="btn btn-default' +
1068
+ html.push(sprintf('<button class="btn' +
1069
+ sprintf(' btn-%s', this.options.buttonsClass) +
965
1070
  sprintf(' btn-%s', this.options.iconSize) +
966
1071
  '" type="button" name="refresh" title="%s">',
967
1072
  this.options.formatRefresh()),
@@ -970,7 +1075,8 @@
970
1075
  }
971
1076
 
972
1077
  if (this.options.showToggle) {
973
- html.push(sprintf('<button class="btn btn-default' +
1078
+ html.push(sprintf('<button class="btn' +
1079
+ sprintf(' btn-%s', this.options.buttonsClass) +
974
1080
  sprintf(' btn-%s', this.options.iconSize) +
975
1081
  '" type="button" name="toggle" title="%s">',
976
1082
  this.options.formatToggle()),
@@ -981,7 +1087,8 @@
981
1087
  if (this.options.showColumns) {
982
1088
  html.push(sprintf('<div class="keep-open btn-group" title="%s">',
983
1089
  this.options.formatColumns()),
984
- '<button type="button" class="btn btn-default' +
1090
+ '<button type="button" class="btn' +
1091
+ sprintf(' btn-%s', this.options.buttonsClass) +
985
1092
  sprintf(' btn-%s', this.options.iconSize) +
986
1093
  ' dropdown-toggle" data-toggle="dropdown">',
987
1094
  sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.columns),
@@ -994,7 +1101,7 @@
994
1101
  return;
995
1102
  }
996
1103
 
997
- if (that.options.cardView && (!column.cardVisible)) {
1104
+ if (that.options.cardView && !column.cardVisible) {
998
1105
  return;
999
1106
  }
1000
1107
 
@@ -1048,8 +1155,7 @@
1048
1155
  $keepOpen.find('input').off('click').on('click', function () {
1049
1156
  var $this = $(this);
1050
1157
 
1051
- that.toggleColumn(getFieldIndex(that.columns,
1052
- $(this).data('field')), $this.prop('checked'), false);
1158
+ that.toggleColumn($(this).val(), $this.prop('checked'), false);
1053
1159
  that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));
1054
1160
  });
1055
1161
  }
@@ -1067,10 +1173,12 @@
1067
1173
  this.$toolbar.append(html.join(''));
1068
1174
  $search = this.$toolbar.find('.search input');
1069
1175
  $search.off('keyup drop').on('keyup drop', function (event) {
1070
- if (that.options.searchOnEnterKey) {
1071
- if (event.keyCode !== 13) {
1072
- return;
1073
- }
1176
+ if (that.options.searchOnEnterKey && event.keyCode !== 13) {
1177
+ return;
1178
+ }
1179
+
1180
+ if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
1181
+ return;
1074
1182
  }
1075
1183
 
1076
1184
  clearTimeout(timeoutId); // doesn't matter if it's 0
@@ -1114,17 +1222,20 @@
1114
1222
  var that = this;
1115
1223
 
1116
1224
  if (this.options.sidePagination !== 'server') {
1117
- var s = this.searchText && this.searchText.toLowerCase();
1225
+ if (this.options.customSearch !== $.noop) {
1226
+ this.options.customSearch.apply(this, [this.searchText]);
1227
+ return;
1228
+ }
1229
+
1230
+ var s = this.searchText && (this.options.escape ?
1231
+ escapeHTML(this.searchText) : this.searchText).toLowerCase();
1118
1232
  var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;
1119
1233
 
1120
1234
  // Check filter
1121
1235
  this.data = f ? $.grep(this.options.data, function (item, i) {
1122
1236
  for (var key in f) {
1123
- if ($.isArray(f[key])) {
1124
- if ($.inArray(item[key], f[key]) === -1) {
1125
- return false;
1126
- }
1127
- } else if (item[key] !== f[key]) {
1237
+ if ($.isArray(f[key]) && $.inArray(item[key], f[key]) === -1 ||
1238
+ item[key] !== f[key]) {
1128
1239
  return false;
1129
1240
  }
1130
1241
  }
@@ -1132,20 +1243,33 @@
1132
1243
  }) : this.options.data;
1133
1244
 
1134
1245
  this.data = s ? $.grep(this.data, function (item, i) {
1135
- for (var key in item) {
1136
- key = $.isNumeric(key) ? parseInt(key, 10) : key;
1137
- var value = item[key],
1138
- column = that.columns[getFieldIndex(that.columns, key)],
1139
- j = $.inArray(key, that.header.fields);
1140
-
1141
- // Fix #142: search use formatted data
1142
- if (column && column.searchFormatter) {
1143
- value = calculateObjectValue(column,
1144
- that.header.formatters[j], [value, item, i], value);
1246
+ for (var j = 0; j < that.header.fields.length; j++) {
1247
+
1248
+ if (!that.header.searchables[j]) {
1249
+ continue;
1250
+ }
1251
+
1252
+ var key = $.isNumeric(that.header.fields[j]) ? parseInt(that.header.fields[j], 10) : that.header.fields[j];
1253
+ var column = that.columns[getFieldIndex(that.columns, key)];
1254
+ var value;
1255
+
1256
+ if (typeof key === 'string') {
1257
+ value = item;
1258
+ var props = key.split('.');
1259
+ for (var prop_index = 0; prop_index < props.length; prop_index++) {
1260
+ value = value[props[prop_index]];
1261
+ }
1262
+
1263
+ // Fix #142: respect searchForamtter boolean
1264
+ if (column && column.searchFormatter) {
1265
+ value = calculateObjectValue(column,
1266
+ that.header.formatters[j], [value, item, i], value);
1267
+ }
1268
+ } else {
1269
+ value = item[key];
1145
1270
  }
1146
1271
 
1147
- var index = $.inArray(key, that.header.fields);
1148
- if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) {
1272
+ if (typeof value === 'string' || typeof value === 'number') {
1149
1273
  if (that.options.strictSearch) {
1150
1274
  if ((value + '').toLowerCase() === s) {
1151
1275
  return true;
@@ -1178,7 +1302,8 @@
1178
1302
  $first, $pre,
1179
1303
  $next, $last,
1180
1304
  $number,
1181
- data = this.getData();
1305
+ data = this.getData(),
1306
+ pageList = this.options.pageList;
1182
1307
 
1183
1308
  if (this.options.sidePagination !== 'server') {
1184
1309
  this.options.totalRows = data.length;
@@ -1228,7 +1353,8 @@
1228
1353
  sprintf('<span class="btn-group %s">',
1229
1354
  this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
1230
1355
  'dropdown' : 'dropup'),
1231
- '<button type="button" class="btn btn-default ' +
1356
+ '<button type="button" class="btn' +
1357
+ sprintf(' btn-%s', this.options.buttonsClass) +
1232
1358
  sprintf(' btn-%s', this.options.iconSize) +
1233
1359
  ' dropdown-toggle" data-toggle="dropdown">',
1234
1360
  '<span class="page-size">',
@@ -1237,8 +1363,7 @@
1237
1363
  ' <span class="caret"></span>',
1238
1364
  '</button>',
1239
1365
  '<ul class="dropdown-menu" role="menu">'
1240
- ],
1241
- pageList = this.options.pageList;
1366
+ ];
1242
1367
 
1243
1368
  if (typeof this.options.pageList === 'string') {
1244
1369
  var list = this.options.pageList.replace('[', '').replace(']', '')
@@ -1423,7 +1548,7 @@
1423
1548
  };
1424
1549
 
1425
1550
  BootstrapTable.prototype.onPagePre = function (event) {
1426
- if ((this.options.pageNumber - 1) == 0) {
1551
+ if ((this.options.pageNumber - 1) === 0) {
1427
1552
  this.options.pageNumber = this.options.totalPages;
1428
1553
  } else {
1429
1554
  this.options.pageNumber--;
@@ -1519,7 +1644,7 @@
1519
1644
  );
1520
1645
 
1521
1646
  if (this.options.cardView) {
1522
- html.push(sprintf('<td colspan="%s">', this.header.fields.length));
1647
+ html.push(sprintf('<td colspan="%s"><div class="card-views">', this.header.fields.length));
1523
1648
  }
1524
1649
 
1525
1650
  if (!this.options.cardView && this.options.detailView) {
@@ -1539,17 +1664,23 @@
1539
1664
  class_ = that.header.classes[j],
1540
1665
  data_ = '',
1541
1666
  rowspan_ = '',
1667
+ colspan_ = '',
1542
1668
  title_ = '',
1543
- column = that.columns[getFieldIndex(that.columns, field)];
1669
+ column = that.columns[j];
1670
+
1671
+ if (that.fromHtml && typeof value === 'undefined') {
1672
+ return;
1673
+ }
1544
1674
 
1545
1675
  if (!column.visible) {
1546
1676
  return;
1547
1677
  }
1548
1678
 
1549
- style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; '));
1679
+ if (that.options.cardView && !column.cardVisible) {
1680
+ return;
1681
+ }
1550
1682
 
1551
- value = calculateObjectValue(column,
1552
- that.header.formatters[j], [value, item, i], value);
1683
+ style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; '));
1553
1684
 
1554
1685
  // handle td's id and class
1555
1686
  if (item['_' + field + '_id']) {
@@ -1561,11 +1692,14 @@
1561
1692
  if (item['_' + field + '_rowspan']) {
1562
1693
  rowspan_ = sprintf(' rowspan="%s"', item['_' + field + '_rowspan']);
1563
1694
  }
1695
+ if (item['_' + field + '_colspan']) {
1696
+ colspan_ = sprintf(' colspan="%s"', item['_' + field + '_colspan']);
1697
+ }
1564
1698
  if (item['_' + field + '_title']) {
1565
1699
  title_ = sprintf(' title="%s"', item['_' + field + '_title']);
1566
1700
  }
1567
1701
  cellStyle = calculateObjectValue(that.header,
1568
- that.header.cellStyles[j], [value, item, i], cellStyle);
1702
+ that.header.cellStyles[j], [value, item, i, field], cellStyle);
1569
1703
  if (cellStyle.classes) {
1570
1704
  class_ = sprintf(' class="%s"', cellStyle.classes);
1571
1705
  }
@@ -1577,6 +1711,9 @@
1577
1711
  style = sprintf('style="%s"', csses_.concat(that.header.styles[j]).join('; '));
1578
1712
  }
1579
1713
 
1714
+ value = calculateObjectValue(column,
1715
+ that.header.formatters[j], [value, item, i], value);
1716
+
1580
1717
  if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {
1581
1718
  $.each(item['_' + field + '_data'], function (k, v) {
1582
1719
  // ignore data-index
@@ -1617,7 +1754,8 @@
1617
1754
  getPropertyFromOther(that.columns, 'field', 'title', field)) : '',
1618
1755
  sprintf('<span class="value">%s</span>', value),
1619
1756
  '</div>'
1620
- ].join('') : [sprintf('<td%s %s %s %s %s %s>', id_, class_, style, data_, rowspan_, title_),
1757
+ ].join('') : [sprintf('<td%s %s %s %s %s %s %s>',
1758
+ id_, class_, style, data_, rowspan_, colspan_, title_),
1621
1759
  value,
1622
1760
  '</td>'
1623
1761
  ].join('');
@@ -1633,7 +1771,7 @@
1633
1771
  });
1634
1772
 
1635
1773
  if (this.options.cardView) {
1636
- html.push('</td>');
1774
+ html.push('</div></td>');
1637
1775
  }
1638
1776
 
1639
1777
  html.push('</tr>');
@@ -1659,7 +1797,8 @@
1659
1797
  $tr = $td.parent(),
1660
1798
  item = that.data[$tr.data('index')],
1661
1799
  index = $td[0].cellIndex,
1662
- field = that.header.fields[that.options.detailView && !that.options.cardView ? index - 1 : index],
1800
+ fields = that.getVisibleFields(),
1801
+ field = fields[that.options.detailView && !that.options.cardView ? index - 1 : index],
1663
1802
  column = that.columns[getFieldIndex(that.columns, field)],
1664
1803
  value = getItemField(item, field, that.options.escape);
1665
1804
 
@@ -1668,7 +1807,7 @@
1668
1807
  }
1669
1808
 
1670
1809
  that.trigger(e.type === 'click' ? 'click-cell' : 'dbl-click-cell', field, value, item, $td);
1671
- that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row', item, $tr);
1810
+ that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row', item, $tr, field);
1672
1811
 
1673
1812
  // if click to select - then trigger the checkbox/radio click
1674
1813
  if (e.type === 'click' && that.options.clickToSelect && column.clickToSelect) {
@@ -1769,10 +1908,10 @@
1769
1908
  this.updateSelected();
1770
1909
  this.resetView();
1771
1910
 
1772
- this.trigger('post-body');
1911
+ this.trigger('post-body', data);
1773
1912
  };
1774
1913
 
1775
- BootstrapTable.prototype.initServer = function (silent, query) {
1914
+ BootstrapTable.prototype.initServer = function (silent, query, url) {
1776
1915
  var that = this,
1777
1916
  data = {},
1778
1917
  params = {
@@ -1782,13 +1921,13 @@
1782
1921
  },
1783
1922
  request;
1784
1923
 
1785
- if(this.options.pagination) {
1924
+ if (this.options.pagination) {
1786
1925
  params.pageSize = this.options.pageSize === this.options.formatAllRows() ?
1787
1926
  this.options.totalRows : this.options.pageSize;
1788
1927
  params.pageNumber = this.options.pageNumber;
1789
1928
  }
1790
1929
 
1791
- if (!this.options.url && !this.options.ajax) {
1930
+ if (!(url || this.options.url) && !this.options.ajax) {
1792
1931
  return;
1793
1932
  }
1794
1933
 
@@ -1798,16 +1937,17 @@
1798
1937
  sort: params.sortName,
1799
1938
  order: params.sortOrder
1800
1939
  };
1940
+
1801
1941
  if (this.options.pagination) {
1802
- params.limit = this.options.pageSize === this.options.formatAllRows() ?
1803
- this.options.totalRows : this.options.pageSize;
1804
1942
  params.offset = this.options.pageSize === this.options.formatAllRows() ?
1805
1943
  0 : this.options.pageSize * (this.options.pageNumber - 1);
1944
+ params.limit = this.options.pageSize === this.options.formatAllRows() ?
1945
+ this.options.totalRows : this.options.pageSize;
1806
1946
  }
1807
1947
  }
1808
1948
 
1809
1949
  if (!($.isEmptyObject(this.filterColumnsPartial))) {
1810
- params['filter'] = JSON.stringify(this.filterColumnsPartial, null);
1950
+ params.filter = JSON.stringify(this.filterColumnsPartial, null);
1811
1951
  }
1812
1952
 
1813
1953
  data = calculateObjectValue(this.options, this.options.queryParams, [params], data);
@@ -1824,7 +1964,7 @@
1824
1964
  }
1825
1965
  request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {
1826
1966
  type: this.options.method,
1827
- url: this.options.url,
1967
+ url: url || this.options.url,
1828
1968
  data: this.options.contentType === 'application/json' && this.options.method === 'post' ?
1829
1969
  JSON.stringify(data) : data,
1830
1970
  cache: this.options.cache,
@@ -1846,7 +1986,10 @@
1846
1986
  if (this.options.ajax) {
1847
1987
  calculateObjectValue(this, this.options.ajax, [request], null);
1848
1988
  } else {
1849
- $.ajax(request);
1989
+ if (this._xhr && this._xhr.readyState !== 4) {
1990
+ this._xhr.abort();
1991
+ }
1992
+ this._xhr = $.ajax(request);
1850
1993
  }
1851
1994
  };
1852
1995
 
@@ -1971,7 +2114,8 @@
1971
2114
  that.$header_.find(sprintf('th[data-field="%s"]', $(this).data('field'))).data($(this).data());
1972
2115
  });
1973
2116
 
1974
- var visibleFields = this.getVisibleFields();
2117
+ var visibleFields = this.getVisibleFields(),
2118
+ $ths = this.$header_.find('th');
1975
2119
 
1976
2120
  this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) {
1977
2121
  var $this = $(this),
@@ -1984,8 +2128,12 @@
1984
2128
  index = i - 1;
1985
2129
  }
1986
2130
 
1987
- that.$header_.find(sprintf('th[data-field="%s"]', visibleFields[index]))
1988
- .find('.fht-cell').width($this.innerWidth());
2131
+ var $th = that.$header_.find(sprintf('th[data-field="%s"]', visibleFields[index]));
2132
+ if ($th.length > 1) {
2133
+ $th = $($ths[$this[0].cellIndex]);
2134
+ }
2135
+
2136
+ $th.find('.fht-cell').width($this.innerWidth());
1989
2137
  });
1990
2138
  // horizontal scroll event
1991
2139
  // TODO: it's probably better improving the layout than binding to scroll event
@@ -2013,8 +2161,11 @@
2013
2161
  }
2014
2162
 
2015
2163
  $.each(this.columns, function (i, column) {
2016
- var falign = '', // footer align style
2017
- style = '',
2164
+ var key,
2165
+ falign = '', // footer align style
2166
+ valign = '',
2167
+ csses = [],
2168
+ style = {},
2018
2169
  class_ = sprintf(' class="%s"', column['class']);
2019
2170
 
2020
2171
  if (!column.visible) {
@@ -2026,9 +2177,17 @@
2026
2177
  }
2027
2178
 
2028
2179
  falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);
2029
- style = sprintf('vertical-align: %s; ', column.valign);
2180
+ valign = sprintf('vertical-align: %s; ', column.valign);
2030
2181
 
2031
- html.push('<td', class_, sprintf(' style="%s"', falign + style), '>');
2182
+ style = calculateObjectValue(null, that.options.footerStyle);
2183
+
2184
+ if (style && style.css) {
2185
+ for (key in style.css) {
2186
+ csses.push(key + ': ' + style.css[key]);
2187
+ }
2188
+ }
2189
+
2190
+ html.push('<td', class_, sprintf(' style="%s"', falign + valign + csses.concat().join('; ')), '>');
2032
2191
  html.push('<div class="th-inner">');
2033
2192
 
2034
2193
  html.push(calculateObjectValue(column, column.footerFormatter, [data], '&nbsp;') || '&nbsp;');
@@ -2040,6 +2199,7 @@
2040
2199
  });
2041
2200
 
2042
2201
  this.$tableFooter.find('tr').html(html.join(''));
2202
+ this.$tableFooter.show();
2043
2203
  clearTimeout(this.timeoutFooter_);
2044
2204
  this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this),
2045
2205
  this.$el.is(':hidden') ? 100 : 0);
@@ -2148,6 +2308,7 @@
2148
2308
  // remove the element css
2149
2309
  this.$el.css('margin-top', '0');
2150
2310
  this.$tableContainer.css('padding-bottom', '0');
2311
+ this.$tableFooter.hide();
2151
2312
  return;
2152
2313
  }
2153
2314
 
@@ -2306,19 +2467,25 @@
2306
2467
  };
2307
2468
 
2308
2469
  BootstrapTable.prototype.updateByUniqueId = function (params) {
2309
- var rowId;
2470
+ var that = this;
2471
+ var allParams = $.isArray(params) ? params : [ params ];
2310
2472
 
2311
- if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) {
2312
- return;
2313
- }
2473
+ $.each(allParams, function(i, params) {
2474
+ var rowId;
2314
2475
 
2315
- rowId = $.inArray(this.getRowByUniqueId(params.id), this.options.data);
2476
+ if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) {
2477
+ return;
2478
+ }
2316
2479
 
2317
- if (rowId === -1) {
2318
- return;
2319
- }
2480
+ rowId = $.inArray(that.getRowByUniqueId(params.id), that.options.data);
2481
+
2482
+ if (rowId === -1) {
2483
+ return;
2484
+ }
2485
+ $.extend(that.options.data[rowId], params.row);
2486
+ });
2320
2487
 
2321
- $.extend(this.data[rowId], params.row);
2488
+ this.initSearch();
2322
2489
  this.initSort();
2323
2490
  this.initBody(true);
2324
2491
  };
@@ -2335,10 +2502,17 @@
2335
2502
  };
2336
2503
 
2337
2504
  BootstrapTable.prototype.updateRow = function (params) {
2338
- if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
2339
- return;
2340
- }
2341
- $.extend(this.data[params.index], params.row);
2505
+ var that = this;
2506
+ var allParams = $.isArray(params) ? params : [ params ];
2507
+
2508
+ $.each(allParams, function(i, params) {
2509
+ if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
2510
+ return;
2511
+ }
2512
+ $.extend(that.options.data[params.index], params.row);
2513
+ });
2514
+
2515
+ this.initSearch();
2342
2516
  this.initSort();
2343
2517
  this.initBody(true);
2344
2518
  };
@@ -2418,7 +2592,7 @@
2418
2592
  BootstrapTable.prototype.getSelections = function () {
2419
2593
  var that = this;
2420
2594
 
2421
- return $.grep(this.data, function (row) {
2595
+ return $.grep(this.options.data, function (row) {
2422
2596
  return row[that.header.stateField];
2423
2597
  });
2424
2598
  };
@@ -2544,10 +2718,11 @@
2544
2718
 
2545
2719
  BootstrapTable.prototype.refresh = function (params) {
2546
2720
  if (params && params.url) {
2547
- this.options.url = params.url;
2548
2721
  this.options.pageNumber = 1;
2549
2722
  }
2550
- this.initServer(params && params.silent, params && params.query);
2723
+ this.initServer(params && params.silent,
2724
+ params && params.query, params && params.url);
2725
+ this.trigger('refresh', params);
2551
2726
  };
2552
2727
 
2553
2728
  BootstrapTable.prototype.resetWidth = function () {
@@ -2573,6 +2748,38 @@
2573
2748
  });
2574
2749
  };
2575
2750
 
2751
+ BootstrapTable.prototype.getVisibleColumns = function () {
2752
+ return $.grep(this.columns, function (column) {
2753
+ return column.visible;
2754
+ });
2755
+ };
2756
+
2757
+ BootstrapTable.prototype.toggleAllColumns = function (visible) {
2758
+ $.each(this.columns, function (i, column) {
2759
+ this.columns[i].visible = visible;
2760
+ });
2761
+
2762
+ this.initHeader();
2763
+ this.initSearch();
2764
+ this.initPagination();
2765
+ this.initBody();
2766
+ if (this.options.showColumns) {
2767
+ var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
2768
+
2769
+ if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
2770
+ $items.filter(':checked').prop('disabled', true);
2771
+ }
2772
+ }
2773
+ };
2774
+
2775
+ BootstrapTable.prototype.showAllColumns = function () {
2776
+ this.toggleAllColumns(true);
2777
+ };
2778
+
2779
+ BootstrapTable.prototype.hideAllColumns = function () {
2780
+ this.toggleAllColumns(false);
2781
+ };
2782
+
2576
2783
  BootstrapTable.prototype.filterBy = function (columns) {
2577
2784
  this.filterColumns = $.isEmptyObject(columns) ? {} : columns;
2578
2785
  this.options.pageNumber = 1;
@@ -2740,7 +2947,8 @@
2740
2947
  'resetWidth',
2741
2948
  'destroy',
2742
2949
  'showLoading', 'hideLoading',
2743
- 'showColumn', 'hideColumn', 'getHiddenColumns',
2950
+ 'showColumn', 'hideColumn', 'getHiddenColumns', 'getVisibleColumns',
2951
+ 'showAllColumns', 'hideAllColumns',
2744
2952
  'filterBy',
2745
2953
  'scrollTo',
2746
2954
  'getScrollPosition',
@@ -2796,7 +3004,10 @@
2796
3004
  sprintf: sprintf,
2797
3005
  getFieldIndex: getFieldIndex,
2798
3006
  compareObjects: compareObjects,
2799
- calculateObjectValue: calculateObjectValue
3007
+ calculateObjectValue: calculateObjectValue,
3008
+ getItemField: getItemField,
3009
+ objectKeys: objectKeys,
3010
+ isIEBrowser: isIEBrowser
2800
3011
  };
2801
3012
 
2802
3013
  // BOOTSTRAP TABLE INIT
@@ -2805,4 +3016,4 @@
2805
3016
  $(function () {
2806
3017
  $('[data-toggle="table"]').bootstrapTable();
2807
3018
  });
2808
- }(jQuery);
3019
+ })(jQuery);