ソースを参照

Merge pull request #2089 from jewway/develop

Add select2 filter & i18n enhance extensions
wenzhixin 9 年 前
コミット
5ea957fb8f

+ 28 - 0
src/extensions/i18n-enhance/README.md

@@ -0,0 +1,28 @@
+# Table i18n Enhance
+
+Use Plugin: [bootstrap-table-i18n-enhance](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter) 
+
+## Usage
+
+```html
+<script src="extensions/select2-filter/bootstrap-table-i18n-enhance.js"></script>
+```
+
+## Methods
+
+### changeLocale
+
+* Change table locale.
+	* Parameters
+		* String : localeId
+	* Example: <code> $table.bootstrapTable("changeLocale", "zh_TW");</code>
+
+### changeTitle
+
+* Change column's title.
+	* Parameters
+		* Object : object's key is column field , value is new title.
+	* Example: <code> $table.bootstrapTable("changeTitle", {
+          columnA.field: "New column A title.",
+          columnB.field: "New column B title."          
+        });</code>

+ 34 - 0
src/extensions/i18n-enhance/bootstrap-table-i18n-enhance.js

@@ -0,0 +1,34 @@
+/**
+ * @author: Jewway
+ * @version: v1.0.0
+ */
+
+!function ($) {
+  'use strict';
+
+  var BootstrapTable = $.fn.bootstrapTable.Constructor;
+
+  BootstrapTable.prototype.changeTitle = function (locale) {
+    $.each(this.options.columns, function (idx, columnList) {
+      $.each(columnList, function (idx, column) {
+        if (column.field) {
+          column.title = locale[column.field];
+        }
+      });
+    });
+
+    this.initHeader();
+    this.initBody();
+    this.initToolbar();
+  };
+
+  BootstrapTable.prototype.changeLocale = function (localeId) {
+    this.options.locale = localeId;
+    this.initLocale();
+    this.initPagination();
+  };
+
+  $.fn.bootstrapTable.methods.push('changeTitle');
+  $.fn.bootstrapTable.methods.push('changeLocale');
+
+}(jQuery);

+ 17 - 0
src/extensions/i18n-enhance/extension.json

@@ -0,0 +1,17 @@
+{
+  "name": "i18n Enhance",
+  "version": "1.0.0",
+  "description": "Plugin to add i18n API in order to change column's title and table locale.",
+  "url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/i18n-enhance",
+  "example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/i18n-enhance.html",
+
+  "plugins": [{
+    "name": "bootstrap-table-i18n-enhance",
+    "url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/i18n-enhance"
+  }],
+
+  "author": {
+    "name": "Jewway",
+    "image": "https://avatars0.githubusercontent.com/u/3501899"
+  }
+}

+ 69 - 0
src/extensions/i18n-enhance/i18n-enhance.html

@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>i18n Enhance</title>
+  <meta charset="utf-8">
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css"/>
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/locale/bootstrap-table-zh-TW.min.js"></script>
+
+  <script src="bootstrap-table-i18n-enhance.js"></script>
+  <script>
+    $(function () {
+      var $table = $("#table"),
+          $buttons = $("button");
+
+      $("#tw_Btn").click(function () {
+        $buttons.removeClass("active");
+        $(this).addClass("active");
+
+        $table.bootstrapTable("changeLocale", "zh-TW");
+        $table.bootstrapTable("changeTitle", {
+          id: "代碼",
+          name: "項目名稱",
+          price: "項目金額"
+        });
+      });
+
+      $("#us_Btn").click(function () {
+        $buttons.removeClass("active");
+        $(this).addClass("active");
+
+        $table.bootstrapTable("changeLocale", "en_US");
+        $table.bootstrapTable("changeTitle", {
+          id: "ID",
+          name: "Item Name",
+          price: "Item Price"
+        });
+      });
+
+    });
+  </script>
+</head>
+<body>
+<div class="container">
+  <h1>i18n Enhance</h1>
+  <label>Language:</label>
+  <div class="btn-group" role="group" style="margin-bottom: 4px">
+    <button id="tw_Btn" type="button" class="btn btn-default btn-sm active">zh_TW</button>
+    <button id="us_Btn" type="button" class="btn btn-default btn-sm">en_US</button>
+  </div>
+
+  <table id="table"
+         data-toggle="table"
+         data-url="data.json"
+         data-pagination="true">
+    <thead>
+    <tr>
+      <th data-field="id">代碼</th>
+      <th data-field="name">項目名稱</th>
+      <th data-field="price">項目金額</th>
+    </tr>
+    </thead>
+  </table>
+</div>
+</body>
+</html>

+ 45 - 0
src/extensions/select2-filter/README.md

@@ -0,0 +1,45 @@
+# Table Select2 Filter
+
+Use Plugin: [bootstrap-table-select2-filter](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter) </br>
+Dependence if you use the select2 option: [Select2](https://select2.github.io/) v4.0.0
+
+## Usage
+
+```html
+<script src="extensions/select2-filter/bootstrap-table-select2-filter.js"></script>
+```
+
+## Options
+
+### filter
+
+* type: Boolean
+* description: enabled select2 filter exetension.
+* default: `false`
+
+### filterValues
+
+* type: Object
+* description: Set default selected value. <br>Example: {columnA.field.:'Column A Selected Value',columnB.field:'Column B Selected Value'}
+* default: `undefined`
+
+## Column options
+
+### filter
+
+* type: Object
+* description: Set filter option to configure the filter. <br>Example: {type:'select', data:["itemA", "itemB", "itemC"]}
+	* type: add an `input` or `select` into the column.
+	* data: need to set when type is `select` , filter data list. (The same as [Select2 Options](http://select2.github.io/examples.html#data))
+* default: `undefined`
+
+## Methods
+
+### setFilterData
+
+
+* Set column's filter data.
+  * Parameters
+      * String : column field.
+      * Object : filter data list.
+  * Example: <code> $table.bootstrapTable("setFilterData", "columnA.filed", ["itemA", "itemB", "itemC"]);</code>

+ 303 - 0
src/extensions/select2-filter/bootstrap-table-select2-filter.js

@@ -0,0 +1,303 @@
+/**
+ * @author: Jewway
+ * @version: v1.0.0
+ */
+
+!function ($) {
+  'use strict';
+
+  function getCurrentHeader(that) {
+    var header = that.$header;
+    if (that.options.height) {
+      header = that.$tableHeader;
+    }
+
+    return header;
+  }
+
+  function getFilterFields(that) {
+    return getCurrentHeader(that).find('[data-filter-field]');
+  }
+
+  function setFilterValues(that) {
+    var $filterElms = getFilterFields(that);
+    if (!$.isEmptyObject(that.filterColumnsPartial)) {
+      $filterElms.each(function (index, ele) {
+        var $ele = $(ele),
+            field = $ele.attr('data-filter-field'),
+            value = that.filterColumnsPartial[field];
+
+        if ($ele.is("select")) {
+          $ele.val(value).trigger('change');
+        }
+        else {
+          $ele.val(value);
+        }
+      });
+    }
+  }
+
+  function createFilter(that, header) {
+    var enableFilter = false,
+        isVisible,
+        html,
+        timeoutId = 0;
+
+    $.each(that.columns, function (i, column) {
+      isVisible = 'hidden';
+      html = [];
+
+      if (!column.visible) {
+        return;
+      }
+
+      if (!column.filter) {
+        html.push('<div class="no-filter"></div>');
+      } else {
+        var filterClass = column.filter.class ? ' ' + column.filter.class : '';
+        html.push('<div style="margin: 0px 2px 2px 2px;" class="filter' + filterClass + '">');
+
+        if (column.searchable) {
+          enableFilter = true;
+          isVisible = 'visible'
+        }
+
+        switch (column.filter.type.toLowerCase()) {
+          case 'input' :
+            html.push('<input type="text" data-filter-field="' + column.field + '" style="width: 100%; visibility:' + isVisible + '">');
+            break;
+          case 'select':
+            html.push('<select data-filter-field="' + column.field + '" style="width: 100%; visibility:' + isVisible + '"></select>');
+            break;
+        }
+      }
+
+      $.each(header.children().children(), function (i, tr) {
+        tr = $(tr);
+        if (tr.data('field') === column.field) {
+          tr.find('.fht-cell').append(html.join(''));
+          return false;
+        }
+      });
+    });
+
+    if (enableFilter) {
+      var $inputs = header.find('input'),
+          $selects = header.find('select');
+
+
+      if ($inputs.length > 0) {
+        $inputs.off('keyup').on('keyup', function (event) {
+          clearTimeout(timeoutId);
+          timeoutId = setTimeout(function () {
+            that.onColumnSearch(event);
+          }, that.options.searchTimeOut);
+        });
+
+
+        $inputs.off('mouseup').on('mouseup', function (event) {
+          var $input = $(this),
+              oldValue = $input.val();
+
+          if (oldValue === "") {
+            return;
+          }
+
+          setTimeout(function () {
+            var newValue = $input.val();
+
+            if (newValue === "") {
+              clearTimeout(timeoutId);
+              timeoutId = setTimeout(function () {
+                that.onColumnSearch(event);
+              }, that.options.searchTimeOut);
+            }
+          }, 1);
+        });
+      }
+
+      if ($selects.length > 0) {
+        $selects.on('select2:select', function (event) {
+          that.onColumnSearch(event);
+        });
+      }
+    } else {
+      header.find('.filter').hide();
+    }
+  }
+
+  function initSelect2(that) {
+    var $header = getCurrentHeader(that);
+
+    $.each(that.columns, function (idx, column) {
+      if (column.filter && column.filter.type === 'select') {
+        var $selectEle = $header.find('select[data-filter-field=' + column.field + ']');
+
+        if ($selectEle.length > 0 && !$selectEle.data().select2) {
+          column.filter.data.unshift("");
+
+          var select2Opts = {
+            placeholder: "",
+            allowClear: true,
+            data: column.filter.data,
+            dropdownParent: that.$el.closest(".bootstrap-table")
+          };
+
+          $selectEle.select2(select2Opts);
+          $selectEle.on("select2:unselecting", function (event) {
+            event.preventDefault();
+            $selectEle.val(null).trigger('change');
+            that.searchText = undefined;
+            that.onColumnSearch(event);
+          });
+        }
+      }
+    });
+  }
+
+  $.extend($.fn.bootstrapTable.defaults, {
+    filter: false,
+    filterValues: {}
+  });
+
+  $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
+    filter: undefined
+  });
+
+  var BootstrapTable = $.fn.bootstrapTable.Constructor,
+      _init = BootstrapTable.prototype.init,
+      _initHeader = BootstrapTable.prototype.initHeader,
+      _initSearch = BootstrapTable.prototype.initSearch;
+
+  BootstrapTable.prototype.init = function () {
+    //Make sure that the filtercontrol option is set
+    if (this.options.filter) {
+      var that = this;
+
+      if (!$.isEmptyObject(that.options.filterValues)) {
+        that.filterColumnsPartial = that.options.filterValues;
+        that.options.filterValues = {};
+      }
+
+      this.$el.on('reset-view.bs.table', function () {
+        //Create controls on $tableHeader if the height is set
+        if (!that.options.height) {
+          return;
+        }
+
+        //Avoid recreate the controls
+        if (that.$tableHeader.find('select').length > 0 || that.$tableHeader.find('input').length > 0) {
+          return;
+        }
+
+        createFilter(that, that.$tableHeader);
+      }).on('post-header.bs.table', function () {
+        var timeoutId = 0;
+
+        initSelect2(that);
+        clearTimeout(timeoutId);
+        timeoutId = setTimeout(function () {
+          setFilterValues(that);
+        }, that.options.searchTimeOut - 1000);
+      }).on('column-switch.bs.table', function (field, checked) {
+        setFilterValues(that);
+      });
+    }
+
+    _init.apply(this, Array.prototype.slice.apply(arguments));
+  };
+
+  BootstrapTable.prototype.initHeader = function () {
+    _initHeader.apply(this, Array.prototype.slice.apply(arguments));
+    if (this.options.filter) {
+      createFilter(this, this.$header);
+    }
+  };
+
+  BootstrapTable.prototype.initSearch = function () {
+    _initSearch.apply(this, Array.prototype.slice.apply(arguments));
+
+    var that = this,
+        filterValues = that.filterColumnsPartial;
+
+    // Filter for client
+    if (that.options.sidePagination === 'client') {
+      this.data = $.grep(this.data, function (row, idx) {
+        for (var field in filterValues) {
+          var column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, field)],
+              filterValue = filterValues[field].toLowerCase(),
+              rowValue = row[field];
+
+          rowValue = $.fn.bootstrapTable.utils.calculateObjectValue(
+              that.header,
+              that.header.formatters[$.inArray(field, that.header.fields)],
+              [rowValue, row, idx], rowValue);
+
+          if (column.filterStrictSearch) {
+            if (!($.inArray(field, that.header.fields) !== -1 &&
+                (typeof rowValue === 'string' || typeof rowValue === 'number') &&
+                rowValue.toString().toLowerCase() === filterValue.toString().toLowerCase())) {
+              return false;
+            }
+          } else {
+            if (!($.inArray(field, that.header.fields) !== -1 &&
+                (typeof rowValue === 'string' || typeof rowValue === 'number') &&
+                (rowValue + '').toLowerCase().indexOf(filterValue) !== -1)) {
+              return false;
+            }
+          }
+        }
+
+        return true;
+      });
+    }
+  };
+
+  BootstrapTable.prototype.onColumnSearch = function (event) {
+    var field = $(event.currentTarget).attr('data-filter-field'),
+        value = $.trim($(event.currentTarget).val());
+
+    if ($.isEmptyObject(this.filterColumnsPartial)) {
+      this.filterColumnsPartial = {};
+    }
+
+    if (value) {
+      this.filterColumnsPartial[field] = value;
+    } else {
+      delete this.filterColumnsPartial[field];
+    }
+
+    this.options.pageNumber = 1;
+    this.onSearch(event);
+  };
+
+  BootstrapTable.prototype.setFilterData = function (field, data) {
+    var that = this,
+        $header = getCurrentHeader(that),
+        $selectEle = $header.find('select[data-filter-field=\"' + field + '\"]');
+
+    data.unshift("");
+    $selectEle.empty();
+    $selectEle.select2({
+      data: data,
+      placeholder: "",
+      allowClear: true,
+      dropdownParent: that.$el.closest(".bootstrap-table")
+    });
+
+    $.each(this.columns, function (idx, column) {
+      if (column.field === field) {
+        column.filter.data = data;
+        return false;
+      }
+    });
+  };
+
+  BootstrapTable.prototype.setFilterValues = function (values) {
+    this.filterColumnsPartial = values;
+  };
+
+  $.fn.bootstrapTable.methods.push('setFilterData');
+  $.fn.bootstrapTable.methods.push('setFilterValues');
+
+}(jQuery);

+ 107 - 0
src/extensions/select2-filter/data.json

@@ -0,0 +1,107 @@
+[
+  {
+    "id": 0,
+    "name": "Item 0",
+    "price": "$0"
+  },
+  {
+    "id": 1,
+    "name": "Item 1",
+    "price": "$1"
+  },
+  {
+    "id": 2,
+    "name": "Item 2",
+    "price": "$2"
+  },
+  {
+    "id": 3,
+    "name": "Item 3",
+    "price": "$3"
+  },
+  {
+    "id": 4,
+    "name": "Item 4",
+    "price": "$4"
+  },
+  {
+    "id": 5,
+    "name": "Item 5",
+    "price": "$5"
+  },
+  {
+    "id": 6,
+    "name": "Item 6",
+    "price": "$6"
+  },
+  {
+    "id": 7,
+    "name": "Item 7",
+    "price": "$7"
+  },
+  {
+    "id": 8,
+    "name": "Item 8",
+    "price": "$8"
+  },
+  {
+    "id": 9,
+    "name": "Item 9",
+    "price": "$9"
+  },
+  {
+    "id": 10,
+    "name": "Item 10",
+    "price": "$10"
+  },
+  {
+    "id": 11,
+    "name": "Item 11",
+    "price": "$11"
+  },
+  {
+    "id": 12,
+    "name": "Item 12",
+    "price": "$12"
+  },
+  {
+    "id": 13,
+    "name": "Item 13",
+    "price": "$13"
+  },
+  {
+    "id": 14,
+    "name": "Item 14",
+    "price": "$14"
+  },
+  {
+    "id": 15,
+    "name": "Item 15",
+    "price": "$15"
+  },
+  {
+    "id": 16,
+    "name": "Item 16",
+    "price": "$16"
+  },
+  {
+    "id": 17,
+    "name": "Item 17",
+    "price": "$17"
+  },
+  {
+    "id": 18,
+    "name": "Item 18",
+    "price": "$18"
+  },
+  {
+    "id": 19,
+    "name": "Item 19",
+    "price": "$19"
+  },
+  {
+    "id": 20,
+    "name": "Item 20",
+    "price": "$20"
+  }
+]

+ 17 - 0
src/extensions/select2-filter/extension.json

@@ -0,0 +1,17 @@
+{
+  "name": "Select2 Filter",
+  "version": "1.0.0",
+  "description": "Plugin to add select2 filter on the top of the columns in order to filter the data.",
+  "url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter",
+  "example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/select2-filter.html",
+
+  "plugins": [{
+    "name": "bootstrap-table-select2-filter",
+    "url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter"
+  }],
+
+  "author": {
+    "name": "Jewway",
+    "image": "https://avatars0.githubusercontent.com/u/3501899"
+  }
+}

+ 58 - 0
src/extensions/select2-filter/select2-filter.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Select2 Filter</title>
+  <meta charset="utf-8">
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css"/>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css"/>
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
+  <script src="bootstrap-table-select2-filter.js"></script>
+  <script>
+    $(function () {
+      var options = {
+        filterValues: {price: "$2"},
+        url: "data.json",
+        columns: [
+          {
+            field: "id",
+            title: "ID",
+            filter: {
+              type: "input"
+            }
+          },
+          {
+            field: "name",
+            title: "Item Name",
+            filter: {
+              type: "select",
+              data: []
+            }
+          },
+          {
+            field: "price",
+            title: "Item Price",
+            filter: {
+              type: "select",
+              data: ["$1", "$2", "$3"]
+            }
+          }
+        ],
+        filter: true
+      };
+
+      var $table = $("#table").bootstrapTable(options);
+      $table.bootstrapTable("setFilterData", "name", ["item 1", "item 2", "item 3"]);
+    });
+  </script>
+</head>
+<body>
+<div class="container">
+  <h1>Select2 Filter</h1>
+  <table id="table"></table>
+</div>
+</body>
+</html>