ソースを参照

Merge branch 'master' of https://github.com/djhvscf/bootstrap-table

Dennis Hernández 10 年 前
コミット
54bce9617c

+ 18 - 1
CHANGELOG.md

@@ -1,6 +1,6 @@
 ## ChangeLog
 
-### 1.8.2
+### 1.9.0
 
 - [enh] Update bootstrap-table-cookie.js.
 - [enh] Use options for detailView's open/close icons.
@@ -11,6 +11,23 @@
 - [bug] Fix #938, fix #940: Multiple Sort and Hide/Show column.
 - [bug] Fix #970: click and dblclick bug on no-rows table.
 - [bug] Fix #967: unselected column while column sorted display error.
+- [enh] Support title feature in cells.
+- [enh] Improved cookie, mobile extension.
+- [enh] Added groupby, angular extension.
+- [enh] Added option for setting locale.
+- [enh] Added `exportDataType` option for export extension.
+- [enh] Add fa-IR, ca-ES, es-ES, et-EE and af-ZA locales.
+- [enh] Supported complex header with rowspans and colspans.
+- [enh] Added `searchFomatter` column option.
+- [bug] Fixed ResetRow function and undefined column search bug.
+- [bug] Fixed #639: footer resizing problem.
+- [enh] Added resetSearch method to reset the search text.
+- [enh] Supported flat json.
+- [enh] Improved reorder-columns extension.
+- [enh] Added multiple-search, accent-neutralise extension.
+- [enh] Added fixed-columns extension.
+- [enh] Added `$.fn.bootstrapTable.utils` tools.
+- [enh] Added `expandRow` and `collapseRow` methods.
 
 ### 1.8.1
 

+ 1 - 1
docs/_i18n/en/documentation/events.md

@@ -146,7 +146,7 @@
     <tr>
         <td>onLoadError</td>
         <td>load-error.bs.table</td>
-        <td>status</td>
+        <td>status, res</td>
         <td>Fires when some errors occur to load remote data.</td>
     </tr>
     <tr>

+ 7 - 0
docs/_i18n/en/documentation/table-options.md

@@ -108,6 +108,13 @@ The table options are defined in `jQuery.fn.bootstrapTable.defaults`.
         <td>The data to be loaded.</td>
     </tr>
     <tr>
+        <td>dataField</td>
+        <td>data-data-field</td>
+        <td>String</td>
+        <td>'rows'</td>
+        <td>Key in incoming json containing rows data list.</td>
+    </tr>
+    <tr>
         <td>ajax</td>
         <td>data-ajax</td>
         <td>Function</td>

+ 2 - 2
docs/_includes/nav/main.html

@@ -28,8 +28,8 @@
                     <a href="http://issues.wenzhixin.net.cn/bootstrap-table/" target="_blank">Examples</a>
                 </li>
                 <li>
-                    <a href="http://bootstrap-group-select.wenzhixin.net.cn" target="_blank">
-                        Bootstrap Group Select
+                    <a href="https://github.com/wenzhixin/bootstrap-table-fixed-columns" target="_blank">
+                        Fixed Columns
                         <span class="badge">New</span>
                     </a>
                 </li>

+ 83 - 42
src/bootstrap-table.js

@@ -4,7 +4,7 @@
  * https://github.com/wenzhixin/bootstrap-table/
  */
 
-! function ($) {
+!function ($) {
     'use strict';
 
     // TOOLS DEFINITION
@@ -95,7 +95,7 @@
                 }
             }
         }
-    }
+    };
 
     var getScrollBarWidth = function () {
         if (cachedWidth === null) {
@@ -211,6 +211,15 @@
         return dataAttr;
     };
 
+    var getItemField = function (item, field) {
+        var props = field.split('.');
+        var value = item;
+        for (var p in props) {
+            value = value[props[p]];
+        }
+        return value;
+    }
+
     // BOOTSTRAP TABLE CLASS DEFINITION
     // ======================
 
@@ -234,6 +243,7 @@
         striped: false,
         columns: [[]],
         data: [],
+        dataField: 'rows',
         method: 'get',
         url: undefined,
         ajax: undefined,
@@ -514,26 +524,26 @@
             }
         }
     };
-    
+
     BootstrapTable.prototype.initContainer = function () {
         this.$container = $([
             '<div class="bootstrap-table">',
-                '<div class="fixed-table-toolbar"></div>',
-                    this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
-                    '<div class="fixed-table-pagination" style="clear: both;"></div>' :
-                    '',
-                '<div class="fixed-table-container">',
-                '<div class="fixed-table-header"><table></table></div>',
-                '<div class="fixed-table-body">',
-                    '<div class="fixed-table-loading">',
-                        this.options.formatLoadingMessage(),
-                    '</div>',
-                '</div>',
-                '<div class="fixed-table-footer"><table><tr></tr></table></div>',
-                this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?
+            '<div class="fixed-table-toolbar"></div>',
+            this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
+                '<div class="fixed-table-pagination" style="clear: both;"></div>' :
+                '',
+            '<div class="fixed-table-container">',
+            '<div class="fixed-table-header"><table></table></div>',
+            '<div class="fixed-table-body">',
+            '<div class="fixed-table-loading">',
+            this.options.formatLoadingMessage(),
+            '</div>',
+            '</div>',
+            '<div class="fixed-table-footer"><table><tr></tr></table></div>',
+            this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?
                 '<div class="fixed-table-pagination"></div>' :
                 '',
-                '</div>',
+            '</div>',
             '</div>'
         ].join(''));
 
@@ -704,12 +714,13 @@
 
                 html.push('<th' + sprintf(' title="%s"', column.titleTooltip),
                     column.checkbox || column.radio ?
-                    sprintf(' class="bs-checkbox %s"', column['class'] || '') :
-                    class_,
+                        sprintf(' class="bs-checkbox %s"', column['class'] || '') :
+                        class_,
                     sprintf(' style="%s"', halign + style),
                     sprintf(' rowspan="%s"', column.rowspan),
                     sprintf(' colspan="%s"', column.colspan),
                     sprintf(' data-field="%s"', column.field),
+                    "tabindex='0'",
                     '>');
 
                 html.push(sprintf('<div class="th-inner %s">', that.options.sortable && column.sortable ?
@@ -748,6 +759,15 @@
             }
         });
 
+        this.$header.children().children().off('keypress').on('keypress', function (event) {
+            if (that.options.sortable && $(this).data().sortable) {
+                var code = event.keyCode || event.which;
+                if (code == 13) { //Enter keycode
+                    that.onSort(event);
+                }
+            }
+        });
+
         if (!this.options.showHeader || this.options.cardView) {
             this.$header.hide();
             this.$tableHeader.hide();
@@ -815,8 +835,8 @@
                 if (that.header.sortNames[index]) {
                     name = that.header.sortNames[index];
                 }
-                var aa = a[name],
-                    bb = b[name],
+                var aa = getItemField(a, name),
+                    bb = getItemField(b, name),
                     value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);
 
                 if (value !== undefined) {
@@ -861,7 +881,7 @@
     };
 
     BootstrapTable.prototype.onSort = function (event) {
-        var $this = $(event.currentTarget).parent(),
+        var $this = event.type === "keypress" ? $(event.currentTarget) : $(event.currentTarget).parent(),
             $this_ = this.$header.find('th').eq($this.index());
 
         this.$header.add(this.$header_).find('span.order').remove();
@@ -1083,7 +1103,7 @@
                             }
                         } else {
                             if ((value + '').toLowerCase().indexOf(s) !== -1) {
-                               return true;
+                                return true;
                             }
                         }
                     }
@@ -1156,10 +1176,10 @@
         var pageNumber = [
                 sprintf('<span class="btn-group %s">',
                     this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
-                    'dropdown' : 'dropup'),
+                        'dropdown' : 'dropup'),
                 '<button type="button" class="btn btn-default ' +
-                    (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) +
-                    ' dropdown-toggle" data-toggle="dropdown">',
+                (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) +
+                ' dropdown-toggle" data-toggle="dropdown">',
                 '<span class="page-size">',
                 $allSelected ? this.options.formatAllRows() : this.options.pageSize,
                 '</span>',
@@ -1406,7 +1426,7 @@
 
             $.each(this.header.fields, function (j, field) {
                 var text = '',
-                    value = item[field],
+                    value = getItemField(item, field),
                     type = '',
                     cellStyle = {},
                     id_ = '',
@@ -1473,9 +1493,9 @@
                         sprintf(' type="%s"', type) +
                         sprintf(' value="%s"', item[that.options.idField]) +
                         sprintf(' checked="%s"', value === true ||
-                            (value && value.checked) ? 'checked' : undefined) +
+                        (value && value.checked) ? 'checked' : undefined) +
                         sprintf(' disabled="%s"', !column.checkboxEnabled ||
-                            (value && value.disabled) ? 'disabled' : undefined) +
+                        (value && value.disabled) ? 'disabled' : undefined) +
                         ' />',
                         that.options.cardView ? '</div>' : '</td>'
                     ].join('');
@@ -1533,7 +1553,7 @@
                 index = $td[0].cellIndex,
                 field = that.header.fields[that.options.detailView && !that.options.cardView ? index - 1 : index],
                 colomn = that.columns[getFieldIndex(that.columns, field)],
-                value = item[field];
+                value = getItemField(item, field);
 
             if ($td.find('.detail-icon').length) {
                 return;
@@ -1696,7 +1716,7 @@
                 that.trigger('load-success', res);
             },
             error: function (res) {
-                that.trigger('load-error', res.status);
+                that.trigger('load-error', res.status, res);
             },
             complete: function () {
                 if (!silent) {
@@ -1794,19 +1814,19 @@
         fixedBody = this.$tableBody.get(0);
 
         scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth &&
-            fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.outerHeight() ?
+        fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.outerHeight() ?
             getScrollBarWidth() : 0;
 
         this.$el.css('margin-top', -this.$header.outerHeight());
 
         focused = $(':focus');
-        if(focused.length > 0) {
+        if (focused.length > 0) {
             var $th = focused.parents('th');
-            if($th.length > 0) {
+            if ($th.length > 0) {
                 var dataField = $th.attr('data-field');
-                if(dataField !== undefined) {
+                if (dataField !== undefined) {
                     var $headerTh = this.$header.find("[data-field='" + dataField + "']");
-                    if($headerTh.length > 0) {
+                    if ($headerTh.length > 0) {
                         $headerTh.find(":input").addClass("focus-temp");
                     }
                 }
@@ -1823,7 +1843,7 @@
 
 
         focusedTemp = $('.focus-temp:visible:eq(0)');
-        if(focusedTemp.length > 0) {
+        if (focusedTemp.length > 0) {
             focusedTemp.focus();
             this.$header.find('.focus-temp').removeClass('focus-temp');
         }
@@ -1923,8 +1943,8 @@
         scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0;
 
         this.$tableFooter.css({
-                'margin-right': scrollWidth
-            }).find('table').css('width', elWidth)
+            'margin-right': scrollWidth
+        }).find('table').css('width', elWidth)
             .attr('class', this.$el.attr('class'));
 
         $footerTd = this.$tableFooter.find('td');
@@ -2045,7 +2065,7 @@
         if (this.options.sidePagination === 'server') {
             this.options.totalRows = data.total;
             fixedScroll = data.fixedScroll;
-            data = data.rows;
+            data = data[this.options.dataField];
         } else if (!$.isArray(data)) { // support fixedScroll
             fixedScroll = data.fixedScroll;
             data = data.data;
@@ -2383,7 +2403,7 @@
     };
 
     BootstrapTable.prototype.getHiddenColumns = function () {
-        return $.grep(this.columns, function( column ) {
+        return $.grep(this.columns, function (column) {
             return !column.visible;
         });
     };
@@ -2458,6 +2478,20 @@
         this.onSearch({currentTarget: $search});
     };
 
+    BootstrapTable.prototype.expandRow = function (index) {
+        var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', index));
+        if (!$tr.next().is('tr.detail-view')) {
+            $tr.find('> td > .detail-icon').click();
+        }
+    };
+
+    BootstrapTable.prototype.collapseRow = function (index) {
+        var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', index));
+        if ($tr.next().is('tr.detail-view')) {
+            $tr.find('> td > .detail-icon').click();
+        }
+    };
+
     // BOOTSTRAP TABLE PLUGIN DEFINITION
     // =======================
 
@@ -2484,7 +2518,8 @@
         'togglePagination',
         'toggleView',
         'refreshOptions',
-        'resetSearch'
+        'resetSearch',
+        'expandRow', 'collapseRow'
     ];
 
     $.fn.bootstrapTable = function (option) {
@@ -2526,6 +2561,12 @@
     $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;
     $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;
     $.fn.bootstrapTable.methods = allowedMethods;
+    $.fn.bootstrapTable.utils = {
+        sprintf: sprintf,
+        getFieldIndex: getFieldIndex,
+        compareObjects: compareObjects,
+        calculateObjectValue: calculateObjectValue
+    };
 
     // BOOTSTRAP TABLE INIT
     // =======================

+ 17 - 0
src/extensions/accent-neutralise/README.md

@@ -0,0 +1,17 @@
+# Table Accent Neutralise
+
+Use Plugin: [bootstrap-table-accent-neutralise](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/accent-neutralise)
+
+## Usage
+
+```html
+<script src="extensions/multiple-search/bootstrap-table-accent-neutralise.js"></script>
+```
+
+## Options
+
+### searchAccentNeutralise
+
+* type: Boolean
+* description: Set to true if you want to use accent neutralise feature.
+* default: `false`

+ 182 - 0
src/extensions/accent-neutralise/bootstrap-table-accent-neutralise.js

@@ -0,0 +1,182 @@
+/**
+ * @author: Dennis Hernández
+ * @webSite: http://djhvscf.github.io/Blog
+ * @version: v1.0.0
+ */
+
+!function ($) {
+
+    'use strict';
+
+    var diacriticsMap = {};
+    var defaultAccentsDiacritics = [
+        {'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'},
+        {'base':'AA','letters':'\uA732'},
+        {'base':'AE','letters':'\u00C6\u01FC\u01E2'},
+        {'base':'AO','letters':'\uA734'},
+        {'base':'AU','letters':'\uA736'},
+        {'base':'AV','letters':'\uA738\uA73A'},
+        {'base':'AY','letters':'\uA73C'},
+        {'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'},
+        {'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'},
+        {'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'},
+        {'base':'DZ','letters':'\u01F1\u01C4'},
+        {'base':'Dz','letters':'\u01F2\u01C5'},
+        {'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'},
+        {'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'},
+        {'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'},
+        {'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'},
+        {'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'},
+        {'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'},
+        {'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'},
+        {'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'},
+        {'base':'LJ','letters':'\u01C7'},
+        {'base':'Lj','letters':'\u01C8'},
+        {'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'},
+        {'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'},
+        {'base':'NJ','letters':'\u01CA'},
+        {'base':'Nj','letters':'\u01CB'},
+        {'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'},
+        {'base':'OI','letters':'\u01A2'},
+        {'base':'OO','letters':'\uA74E'},
+        {'base':'OU','letters':'\u0222'},
+        {'base':'OE','letters':'\u008C\u0152'},
+        {'base':'oe','letters':'\u009C\u0153'},
+        {'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'},
+        {'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'},
+        {'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'},
+        {'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'},
+        {'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'},
+        {'base':'TZ','letters':'\uA728'},
+        {'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'},
+        {'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'},
+        {'base':'VY','letters':'\uA760'},
+        {'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'},
+        {'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'},
+        {'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'},
+        {'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'},
+        {'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'},
+        {'base':'aa','letters':'\uA733'},
+        {'base':'ae','letters':'\u00E6\u01FD\u01E3'},
+        {'base':'ao','letters':'\uA735'},
+        {'base':'au','letters':'\uA737'},
+        {'base':'av','letters':'\uA739\uA73B'},
+        {'base':'ay','letters':'\uA73D'},
+        {'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'},
+        {'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'},
+        {'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'},
+        {'base':'dz','letters':'\u01F3\u01C6'},
+        {'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'},
+        {'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'},
+        {'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'},
+        {'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'},
+        {'base':'hv','letters':'\u0195'},
+        {'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'},
+        {'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'},
+        {'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'},
+        {'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'},
+        {'base':'lj','letters':'\u01C9'},
+        {'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'},
+        {'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'},
+        {'base':'nj','letters':'\u01CC'},
+        {'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'},
+        {'base':'oi','letters':'\u01A3'},
+        {'base':'ou','letters':'\u0223'},
+        {'base':'oo','letters':'\uA74F'},
+        {'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'},
+        {'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'},
+        {'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'},
+        {'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'},
+        {'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'},
+        {'base':'tz','letters':'\uA729'},
+        {'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'},
+        {'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'},
+        {'base':'vy','letters':'\uA761'},
+        {'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'},
+        {'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'},
+        {'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'},
+        {'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'}
+    ];
+
+    var initNeutraliser = function () {
+        for (var i=0; i < defaultAccentsDiacritics.length; i++){
+            var letters = defaultAccentsDiacritics[i].letters;
+            for (var j=0; j < letters.length ; j++){
+                diacriticsMap[letters[j]] = defaultAccentsDiacritics[i].base;
+            }
+        }
+    };
+
+    var removeDiacritics = function (str) {
+        return str.replace(/[^\u0000-\u007E]/g, function(a){
+            return diacriticsMap[a] || a;
+        });
+    };
+
+    $.extend($.fn.bootstrapTable.defaults, {
+        searchAccentNeutralise: false
+    });
+
+    var BootstrapTable = $.fn.bootstrapTable.Constructor,
+        _init = BootstrapTable.prototype.init,
+        _initSearch = BootstrapTable.prototype.initSearch;
+
+    BootstrapTable.prototype.init = function () {
+        if (this.options.searchAccentNeutralise) {
+            initNeutraliser();
+        }
+        _init.apply(this, Array.prototype.slice.apply(arguments));
+    };
+
+    BootstrapTable.prototype.initSearch = function () {
+        var that = this;
+
+        if (this.options.sidePagination !== 'server') {
+            var s = this.searchText && this.searchText.toLowerCase();
+            var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;
+
+            // Check filter
+            this.data = f ? $.grep(this.options.data, function (item, i) {
+                for (var key in f) {
+                    if (item[key] !== f[key]) {
+                        return false;
+                    }
+                }
+                return true;
+            }) : this.options.data;
+
+            this.data = s ? $.grep(this.data, function (item, i) {
+                for (var key in item) {
+                    key = $.isNumeric(key) ? parseInt(key, 10) : key;
+                    var value = item[key],
+                        column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)],
+                        j = $.inArray(key, that.header.fields);
+
+                    if (column && column.searchFormatter) {
+                        value = $.fn.bootstrapTable.utils.calculateObjectValue(column,
+                            that.header.formatters[j], [value, item, i], value);
+                    }
+
+                    var index = $.inArray(key, that.header.fields);
+                    if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) {
+                        if (that.options.searchAccentNeutralise) {
+                            value = removeDiacritics(value);
+                            s = removeDiacritics(s);
+                        }
+                        if (that.options.strictSearch) {
+                            if ((value + '').toLowerCase() === s) {
+                                return true;
+                            }
+                        } else {
+                            if ((value + '').toLowerCase().indexOf(s) !== -1) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+                return false;
+            }) : this.data;
+        }
+    };
+
+}(jQuery);

+ 9 - 62
src/extensions/filter-control/bootstrap-table-filter-control.js

@@ -8,61 +8,10 @@
 
     'use strict';
 
-    var sprintf = function (str) {
-        var args = arguments,
-            flag = true,
-            i = 1;
-
-        str = str.replace(/%s/g, function () {
-            var arg = args[i++];
-
-            if (typeof arg === 'undefined') {
-                flag = false;
-                return '';
-            }
-            return arg;
-        });
-        return flag ? str : '';
-    };
-
-    var getFieldIndex = function (columns, field) {
-        var index = -1;
-
-        $.each(columns, function (i, column) {
-            if (column.field === field) {
-                index = i;
-                return false;
-            }
-            return true;
-        });
-        return index;
-    };
-
-    var calculateObjectValue = function (self, name, args, defaultValue) {
-        if (typeof name === 'string') {
-            // support obj.func1.func2
-            var names = name.split('.');
-
-            if (names.length > 1) {
-                name = window;
-                $.each(names, function (i, f) {
-                    name = name[f];
-                });
-            } else {
-                name = window[name];
-            }
-        }
-        if (typeof name === 'object') {
-            return name;
-        }
-        if (typeof name === 'function') {
-            return name.apply(self, args);
-        }
-        return defaultValue;
-    };
+    var sprintf = $.fn.bootstrapTable.utils.sprintf;
 
     var addOptionToSelectControl = function (selectControl, value, text) {
-        //selectControl = $(selectControl.get(0));
+        selectControl = $(selectControl.get(selectControl.length - 1));
         if (existsOptionInSelectControl(selectControl, value)) {
             selectControl.append($("<option></option>")
                 .attr("value", value)
@@ -87,11 +36,9 @@
     };
 
     var existsOptionInSelectControl = function (selectControl, value) {
-        var options = selectControl.get(0).options,
-            iOpt = 0;
-
-        for (; iOpt < options.length; iOpt++) {
-            if (options[iOpt].value === value) {
+        var options = selectControl.get(selectControl.length - 1).options;
+        for (var i = 0; i < options.length; i++) {
+            if (options[i].value === value.toString()) {
                 //The value is nor valid to add
                 return false;
             }
@@ -386,16 +333,16 @@
 
             $.each(this.header.fields, function (j, field) {
                 var value = item[field],
-                    column = that.columns[getFieldIndex(that.columns, field)];
+                    column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, field)];
 
-                value = calculateObjectValue(that.header, that.header.formatters[j], [value, item, i], value);
+                value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[j], [value, item, i], value);
 
                 if ((!column.checkbox) || (!column.radio)) {
                     if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select' && column.searchable) {
                         if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') {
                             var selectControl = $('.' + column.field);
                             if (selectControl !== undefined && selectControl.length > 0) {
-                                if (selectControl.get(0).options.length === 0) {
+                                if (selectControl.get(selectControl.length - 1).options.length === 0) {
                                     //Added the default option
                                     addOptionToSelectControl(selectControl, '', '');
                                 }
@@ -421,7 +368,7 @@
             for (var key in fp) {
                 var fval = fp[key].toLowerCase();
                 var value = item[key];
-                value = calculateObjectValue(that.header,
+                value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
                     that.header.formatters[$.inArray(key, that.header.fields)],
                     [value, item, i], value);
 

+ 30 - 72
src/extensions/group-by/bootstrap-table-group-by.js

@@ -14,48 +14,6 @@
         obj = {},
         parentId = undefined;
 
-    var compareObjects = function (objectA, objectB, compareLength) {
-        // Create arrays of property names
-        var objectAProperties = Object.getOwnPropertyNames(objectA),
-            objectBProperties = Object.getOwnPropertyNames(objectB),
-            propName = '';
-
-        if (compareLength) {
-            // If number of properties is different, objects are not equivalent
-            if (objectAProperties.length !== objectBProperties.length) {
-                return false;
-            }
-        }
-
-        for (var i = 0; i < objectAProperties.length; i++) {
-            propName = objectAProperties[i];
-
-            // If the property is not in the object B properties, continue with the next property
-            if ($.inArray(propName, objectBProperties) > -1) {
-                // If values of same property are not equal, objects are not equivalent
-                if (objectA[propName] !== objectB[propName]) {
-                    return false;
-                }
-            }
-        }
-
-        // If we made it this far, objects are considered equivalent
-        return true;
-    };
-
-    var getFieldIndex = function (columns, field) {
-        var index = -1;
-
-        $.each(columns, function (i, column) {
-            if (column.field === field) {
-                index = i;
-                return false;
-            }
-            return true;
-        });
-        return index;
-    };
-
     var getParentRowId = function (that, id) {
         var parentRows = that.$body.find('tr').not('[' + 'data-tt-parent-id]');
 
@@ -72,15 +30,15 @@
         var sumRow = {};
         $.each(data, function (i, row) {
             if (!row.IsParent) {
-                for(var prop in row) {
-                        if (!isNaN(parseFloat(row[prop]))) {
-                            if (that.columns[getFieldIndex(that.columns, prop)].groupBySumGroup) {
-                                if (sumRow[prop] === undefined) {
-                                    sumRow[prop] = 0;
-                                }
-                                sumRow[prop] += +row[prop];
+                for (var prop in row) {
+                    if (!isNaN(parseFloat(row[prop]))) {
+                        if (that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, prop)].groupBySumGroup) {
+                            if (sumRow[prop] === undefined) {
+                                sumRow[prop] = 0;
                             }
+                            sumRow[prop] += +row[prop];
                         }
+                    }
                 }
             }
         });
@@ -105,19 +63,19 @@
 
     var setObjectKeys = function () {
         // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
-       Object.keys = function (o) {
-           if (o !== Object(o)) {
-               throw new TypeError('Object.keys called on a non-object');
-           }
-           var k = [],
-               p;
-           for (p in o) {
-               if (Object.prototype.hasOwnProperty.call(o, p)) {
-                   k.push(p);
-               }
-           }
-           return k;
-       }
+        Object.keys = function (o) {
+            if (o !== Object(o)) {
+                throw new TypeError('Object.keys called on a non-object');
+            }
+            var k = [],
+                p;
+            for (p in o) {
+                if (Object.prototype.hasOwnProperty.call(o, p)) {
+                    k.push(p);
+                }
+            }
+            return k;
+        }
     };
 
     var getDataArrayFromItem = function (that, item) {
@@ -140,16 +98,16 @@
         return newRow;
     };
 
-    var groupBy = function (array , f) {
-       var groups = {};
-       $.each(array, function(i, o) {
-           var group = JSON.stringify(f(o));
-           groups[group] = groups[group] || [];
-           groups[group].push(o);
-       });
-       return Object.keys(groups).map(function (group) {
+    var groupBy = function (array, f) {
+        var groups = {};
+        $.each(array, function (i, o) {
+            var group = JSON.stringify(f(o));
+            groups[group] = groups[group] || [];
+            groups[group].push(o);
+        });
+        return Object.keys(groups).map(function (group) {
             return groups[group];
-       });
+        });
     };
 
     var makeGrouped = function (that, data) {
@@ -277,7 +235,7 @@
     };
 
     BootstrapTable.prototype.refreshGroupByField = function (groupByFields) {
-        if (!compareObjects(this.options.groupByField, groupByFields)) {
+        if (!$.fn.bootstrapTable.utils.compareObjects(this.options.groupByField, groupByFields)) {
             this.options.groupByField = groupByFields;
             this.load(this.options.originalData);
         }

+ 1 - 14
src/extensions/mobile/bootstrap-table-mobile.js

@@ -8,25 +8,12 @@
 
     'use strict';
 
-    var getFieldIndex = function (columns, field) {
-        var index = -1;
-
-        $.each(columns, function (i, column) {
-            if (column.field === field) {
-                index = i;
-                return false;
-            }
-            return true;
-        });
-        return index;
-    };
-
     var showHideColumns = function (that, checked) {
         if (that.options.columnsHidden.length > 0 ) {
             $.each(that.columns, function (i, column) {
                 if (that.options.columnsHidden.indexOf(column.field) !== -1) {
                     if (column.visible !== checked) {
-                        that.toggleColumn(getFieldIndex(that.columns, column.field), checked, true);
+                        that.toggleColumn($.fn.bootstrapTable.utils.getFieldIndex(that.columns, column.field), checked, true);
                     }
                 }
             });

+ 2 - 43
src/extensions/multiple-search/bootstrap-table-multiple-search.js

@@ -8,47 +8,6 @@
 
     'use strict';
 
-    var getFieldIndex = function (columns, field) {
-        var index = -1;
-
-        $.each(columns, function (i, column) {
-            if (column.field === field) {
-                index = i;
-                return false;
-            }
-            return true;
-        });
-        return index;
-    };
-
-    var calculateObjectValue = function (self, name, args, defaultValue) {
-        var func = name;
-
-        if (typeof name === 'string') {
-            // support obj.func1.func2
-            var names = name.split('.');
-
-            if (names.length > 1) {
-                func = window;
-                $.each(names, function (i, f) {
-                    func = func[f];
-                });
-            } else {
-                func = window[name];
-            }
-        }
-        if (typeof func === 'object') {
-            return func;
-        }
-        if (typeof func === 'function') {
-            return func.apply(self, args);
-        }
-        if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {
-            return sprintf.apply(this, [name].concat(args));
-        }
-        return defaultValue;
-    };
-
     $.extend($.fn.bootstrapTable.defaults, {
         multipleSearch: false
     });
@@ -72,12 +31,12 @@
                         for (var key in item) {
                             key = $.isNumeric(key) ? parseInt(key, 10) : key;
                             var value = item[key],
-                                column = that.columns[getFieldIndex(that.columns, key)],
+                                column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)],
                                 j = $.inArray(key, that.header.fields);
 
                             // Fix #142: search use formated data
                             if (column && column.searchFormatter) {
-                                value = calculateObjectValue(column,
+                                value = $.fn.bootstrapTable.utils.calculateObjectValue(column,
                                     that.header.formatters[j], [value, item, i], value);
                             }
 

+ 1 - 14
src/extensions/reorder-columns/bootstrap-table-reorder-columns.js

@@ -8,19 +8,6 @@
 
     'use strict';
 
-    var getFieldIndex = function (columns, field) {
-        var index = -1;
-
-        $.each(columns, function (i, column) {
-            if (column.field === field) {
-                index = i;
-                return false;
-            }
-            return true;
-        });
-        return index;
-    };
-
     $.extend($.fn.bootstrapTable.defaults, {
         reorderableColumns: false,
         maxMovingRows: 10,
@@ -116,7 +103,7 @@
                 }
 
                 for (var i = 0; i < ths.length; i++ ) {
-                    columnIndex = getFieldIndex(that.columns, ths[i]);
+                    columnIndex = $.fn.bootstrapTable.utils.getFieldIndex(that.columns, ths[i]);
                     if (columnIndex !== -1) {
                         columns.push(that.columns[columnIndex]);
                         that.columns.splice(columnIndex, 1);

+ 2 - 40
src/extensions/toolbar/bootstrap-table-toolbar.js

@@ -10,45 +10,7 @@
 
     var firstLoad = false;
 
-    var sprintf = function(str) {
-        var args = arguments,
-            flag = true,
-            i = 1;
-
-        str = str.replace(/%s/g, function() {
-            var arg = args[i++];
-
-            if (typeof arg === 'undefined') {
-                flag = false;
-                return '';
-            }
-            return arg;
-        });
-        return flag ? str : '';
-    };
-
-    var calculateObjectValue = function (self, name, args, defaultValue) {
-        if (typeof name === 'string') {
-            // support obj.func1.func2
-            var names = name.split('.');
-
-            if (names.length > 1) {
-                name = window;
-                $.each(names, function (i, f) {
-                    name = name[f];
-                });
-            } else {
-                name = window[name];
-            }
-        }
-        if (typeof name === 'object') {
-            return name;
-        }
-        if (typeof name === 'function') {
-            return name.apply(self, args);
-        }
-        return defaultValue;
-    };
+    var sprintf = $.fn.bootstrapTable.utils.sprintf;
 
     var showAvdSearch = function(pColumns, searchTitle, searchText, that) {
         if (!$("#avdSearchModal" + "_" + that.options.idTable).hasClass("modal")) {
@@ -214,7 +176,7 @@
             for (var key in fp) {
                 var fval = fp[key].toLowerCase();
                 var value = item[key];
-                value = calculateObjectValue(that.header,
+                value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
                     that.header.formatters[$.inArray(key, that.header.fields)],
                     [value, item, i], value);
 

+ 40 - 0
src/locale/bootstrap-table-af-ZA.js

@@ -0,0 +1,40 @@
+/**
+ * Bootstrap Table Afrikaans translation
+ * Author: Phillip Kruger <phillip.kruger@gmail.com>
+ */
+(function ($) {
+    'use strict';
+
+    $.fn.bootstrapTable.locales['af-ZA'] = {
+        formatLoadingMessage: function () {
+            return 'Besig om te laai, wag asseblief ...';
+        },
+        formatRecordsPerPage: function (pageNumber) {
+            return pageNumber + ' rekords per bladsy';
+        },
+        formatShowingRows: function (pageFrom, pageTo, totalRows) {
+            return 'Resultate ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' rye';
+        },
+        formatSearch: function () {
+            return 'Soek';
+        },
+        formatNoMatches: function () {
+            return 'Geen rekords gevind nie';
+        },
+        formatPaginationSwitch: function () {
+            return 'Wys/verberg bladsy nummering';
+        },
+        formatRefresh: function () {
+            return 'Herlaai';
+        },
+        formatToggle: function () {
+            return 'Wissel';
+        },
+        formatColumns: function () {
+            return 'Kolomme';
+        }
+    };
+
+    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['af-ZA']);
+
+})(jQuery);