浏览代码

Merge pull request #4847 from wenzhixin/feature/4784

feature/4784
文翼 5 年之前
父节点
当前提交
4d894b5c00

+ 2 - 0
CHANGELOG.md

@@ -38,8 +38,10 @@ ChangeLog
 - **New(cookie):** Added new options to get/set/delete the values by a custom function.
 - **New(cookie):** Added save re-order and resize support.
 - **New(filter-control):** Added `filterControlContainer` option.
+- **New(filter-control):** Added `filterCustomSearch` option.
 - **New(filter-control):** Added object and function support in `filterData` column option.
 - **New(filter-control):** Added support for using sticky-header extension.
+- **New(filter-control):** Added support comparisons search(<, >, <=, =<, >=, =>).
 - **New(fixed-columns):** Added all themes support.
 - **New(fixed-columns):** Added `fixedRightNumber` option.
 - **New(group-by):** Added `customSort` option supported.

+ 1 - 1
site/docs/api/table-options.md

@@ -999,7 +999,7 @@ The table options are defined in `jQuery.fn.bootstrapTable.defaults`.
 
 - **Detail:**
 
-  The custom search function is executed instead of built-in search function, takes two parameters:
+  The custom search function is executed instead of built-in search function, takes three parameters:
 
   * `data`: the table data.
   * `text`: the search text.

+ 26 - 5
site/docs/extensions/filter-control.md

@@ -128,11 +128,11 @@ Dependence if you use the datepicker option: [bootstrap-datepicker](https://gith
 
 - **Detail:**
 
-   Set custom select filter values, use   
-   `var:variable` to load from a variable   
-   `obj:variable.key` to load from a object   
-   `url:http://www.example.com/data.json` to load from a remote json file   
-   `json:{key:data}` to load from a json string.   
+   Set custom select filter values, use
+   `var:variable` to load from a variable
+   `obj:variable.key` to load from a object
+   `url:http://www.example.com/data.json` to load from a remote json file
+   `json:{key:data}` to load from a json string.
    `func:functionName` to load from a function.
 
 - **Default:** `undefined`
@@ -209,6 +209,27 @@ Dependence if you use the datepicker option: [bootstrap-datepicker](https://gith
 
 - **Default:** `'asc'`
 
+### filterCustomSearch
+
+- **Attribute:** `data-filter-custom-search`
+
+- **type:** `function`
+
+- **Detail:**
+
+   The custom search function is executed instead of built-in search function, takes four parameters:
+
+     * `text`: the search text.
+     * `value`: the the value of the column to compare.
+     * `field`: the column field name.
+     * `data`: the table data.
+
+   Return `false` to filter out the current column/row.
+   Return `true` to not filter out the current column/row.
+   Return `null` to skip the custom search for the current value.
+
+- **Default:** `undefined`
+
 ### Icons
 
 * clear: 'glyphicon-trash icon-clear'

+ 50 - 5
src/extensions/filter-control/bootstrap-table-filter-control.js

@@ -707,9 +707,10 @@ $.BootstrapTable = class extends $.BootstrapTable {
           const thisColumn = that.columns[that.fieldsColumnsIndex[key]]
           const fval = (fp[key] || '').toLowerCase()
           let value = Utils.getItemField(item, key, false)
+          let tmpItemIsExpected
 
           if (fval === '') {
-            itemIsExpected.push(true)
+            tmpItemIsExpected = true
           } else {
             // Fix #142: search use formatted data
             if (thisColumn && thisColumn.searchFormatter) {
@@ -723,18 +724,62 @@ $.BootstrapTable = class extends $.BootstrapTable {
 
             if ($.inArray(key, that.header.fields) !== -1) {
               if (value === undefined || value === null) {
-                itemIsExpected.push(false)
+                tmpItemIsExpected = false
               } else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
                 if (thisColumn.filterStrictSearch) {
-                  itemIsExpected.push(value.toString().toLowerCase() === fval.toString().toLowerCase())
+                  tmpItemIsExpected = value.toString().toLowerCase() === fval.toString().toLowerCase()
                 } else if (thisColumn.filterStartsWithSearch) {
-                  itemIsExpected.push((`${value}`).toLowerCase().indexOf(fval) === 0)
+                  tmpItemIsExpected = (`${value}`).toLowerCase().indexOf(fval) === 0
                 } else {
-                  itemIsExpected.push((`${value}`).toLowerCase().includes(fval))
+                  tmpItemIsExpected = (`${value}`).toLowerCase().includes(fval)
+                }
+
+                const largerSmallerEqualsRegex = /(?:(<=|=>|=<|>=|>|<)(?:\s+)?(\d+)?|(\d+)?(\s+)?(<=|=>|=<|>=|>|<))/gm
+                const matches = largerSmallerEqualsRegex.exec(fval)
+
+                if (matches) {
+                  const operator = matches[1] || `${matches[5]}l`
+                  const comparisonValue = matches[2] || matches[3]
+                  const int = parseInt(value, 10)
+                  const comparisonInt = parseInt(comparisonValue, 10)
+
+                  switch (operator) {
+                    case '>':
+                    case '<l':
+                      tmpItemIsExpected = int > comparisonInt
+                      break
+                    case '<':
+                    case '>l':
+                      tmpItemIsExpected = int < comparisonInt
+                      break
+                    case '<=':
+                    case '=<':
+                    case '>=l':
+                    case '=>l':
+                      tmpItemIsExpected = int <= comparisonInt
+                      break
+                    case '>=':
+                    case '=>':
+                    case '<=l':
+                    case '=<l':
+                      tmpItemIsExpected = int >= comparisonInt
+                      break
+                    default:
+                      break
+                  }
+                }
+
+                if (thisColumn.filterCustomSearch) {
+                  const customSearchResult = Utils.calculateObjectValue(that, thisColumn.filterCustomSearch, [fval, value, key, that.options.data], true)
+                  if (customSearchResult !== null) {
+                    tmpItemIsExpected = customSearchResult
+                  }
                 }
               }
             }
           }
+
+          itemIsExpected.push(tmpItemIsExpected)
         })
 
         return !itemIsExpected.includes(false)