2
0
Эх сурвалжийг харах

make array filters work with objects

Evan You 12 жил өмнө
parent
commit
5eddfd0514

+ 1 - 17
src/directives/repeat.js

@@ -305,7 +305,7 @@ module.exports = {
 
         this.object = object
         var self = this,
-            collection = objectToArray(object)
+            collection = utils.objectToArray(object)
 
         this.syncRepeater = function (key, val) {
             if (key in object) {
@@ -376,22 +376,6 @@ module.exports = {
 
 // Helpers --------------------------------------------------------------------
 
-/**
- *  Convert an Object to a v-repeat friendly Array
- */
-function objectToArray (obj) {
-    var res = [], val, data
-    for (var key in obj) {
-        val = obj[key]
-        data = utils.typeOf(val) === 'Object'
-            ? val
-            : { $value: val }
-        data.$key = key
-        res.push(data)
-    }
-    return res
-}
-
 /**
  *  Find an object or a wrapped data object
  *  from an Array

+ 38 - 26
src/filters.js

@@ -14,32 +14,6 @@ var keyCodes = {
     esc      : 27
 }
 
-/**
- *  String contain helper
- */
-function contains (val, search) {
-    /* jshint eqeqeq: false */
-    if (utils.typeOf(val) === 'Object') {
-        for (var key in val) {
-            if (contains(val[key], search)) {
-                return true
-            }
-        }
-    } else if (val != null) {
-        return val.toString().toLowerCase().indexOf(search) > -1
-    }
-}
-
-/**
- *  Test whether a string is in quotes,
- *  if yes return stripped string
- */
-function stripQuotes (str) {
-    if (QUOTE_RE.test(str)) {
-        return str.slice(1, -1)
-    }
-}
-
 var filters = module.exports = {
 
     /**
@@ -131,6 +105,11 @@ var filters = module.exports = {
         // get the optional dataKey
         dataKey = dataKey && (stripQuotes(dataKey) || get(this, dataKey))
 
+        // convert object to array
+        if (!Array.isArray(arr)) {
+            arr = utils.objectToArray(arr)
+        }
+
         return arr.filter(function (item) {
             return dataKey
                 ? contains(get(item, dataKey), search)
@@ -144,6 +123,11 @@ var filters = module.exports = {
         var key = stripQuotes(sortKey) || get(this, sortKey)
         if (!key) return arr
 
+        // convert object to array
+        if (!Array.isArray(arr)) {
+            arr = utils.objectToArray(arr)
+        }
+
         var order = 1
         if (reverseKey) {
             if (reverseKey === '-1') {
@@ -167,6 +151,34 @@ var filters = module.exports = {
 
 }
 
+// Array filter helpers -------------------------------------------------------
+
+/**
+ *  String contain helper
+ */
+function contains (val, search) {
+    /* jshint eqeqeq: false */
+    if (utils.typeOf(val) === 'Object') {
+        for (var key in val) {
+            if (contains(val[key], search)) {
+                return true
+            }
+        }
+    } else if (val != null) {
+        return val.toString().toLowerCase().indexOf(search) > -1
+    }
+}
+
+/**
+ *  Test whether a string is in quotes,
+ *  if yes return stripped string
+ */
+function stripQuotes (str) {
+    if (QUOTE_RE.test(str)) {
+        return str.slice(1, -1)
+    }
+}
+
 // mark computed filters
 filters.filterBy.computed = true
 filters.orderBy.computed = true

+ 17 - 0
src/utils.js

@@ -256,6 +256,23 @@ var utils = module.exports = {
             }
             el.className = cur.trim()
         }
+    },
+
+    /**
+     *  Convert an object to Array
+     *  used in v-repeat and array filters
+     */
+    objectToArray: function (obj) {
+        var res = [], val, data
+        for (var key in obj) {
+            val = obj[key]
+            data = utils.typeOf(val) === 'Object'
+                ? val
+                : { $value: val }
+            data.$key = key
+            res.push(data)
+        }
+        return res
     }
 }
 

+ 11 - 3
test/functional/fixtures/array-filters.html

@@ -19,10 +19,10 @@
         </tr>
     </table>
     <hr></hr>
-    Filter by input in all fields and reversed
+    Object, filtered by input in all fields and reversed
     <table id="t2">
         <tr><th>Name</th><th>Phone</th></tr>
-        <tr v-repeat="friends | filterBy searchText | orderBy sortKey !reverse" class="item">
+        <tr v-repeat="friendsObj | filterBy searchText | orderBy sortKey !reverse" class="item">
             <td>{{name}}</td>
             <td>{{phone}}</td>
         </tr>
@@ -58,7 +58,15 @@ new Vue({
             {name:'Adam', phone:'555-5678'},
             {name:'Julie', phone:'555-8765'},
             {name:'Juliette', phone:'555-5678'}
-        ]
+        ],
+        friendsObj: {
+            a: {name:'John', phone:'555-1276', hidden: { id: 'hidden!' } },
+            b: {name:'Mary', phone:'800-BIG-MARY'},
+            c: {name:'Mike', phone:'555-4321'},
+            d: {name:'Adam', phone:'555-5678'},
+            e: {name:'Julie', phone:'555-8765'},
+            f: {name:'Juliette', phone:'555-5678'}
+        }
     }
 })
 </script>

+ 9 - 1
test/functional/specs/array-filters.js

@@ -1,4 +1,4 @@
-casper.test.begin('Array Filters', 53, function (test) {
+casper.test.begin('Array Filters', 55, function (test) {
 
     var names = ['Adam', 'John', 'Julie', 'Juliette', 'Mary', 'Mike'],
         namesReversed = names.slice().reverse(),
@@ -56,6 +56,14 @@ casper.test.begin('Array Filters', 53, function (test) {
         test.assertElementCount('#t1 .item', 0)
         test.assertElementCount('#t2 .item', 5)
     })
+    // enter search filter for nested properties
+    .then(function () {
+        this.sendKeys('#search', 'hidden', { reset: true })
+    })
+    .then(function () {
+        test.assertElementCount('#t1 .item', 0)
+        test.assertElementCount('#t2 .item', 1)
+    })
     // change filterkey
     .thenEvaluate(function () {
         var dropdown = document.getElementById('filterby')

+ 23 - 0
test/unit/specs/filters.js

@@ -166,6 +166,17 @@ describe('Filters', function () {
             assert.strictEqual(res[0], arr[0])
         })
 
+        it('should work with objects', function () {
+            var obj = {
+                a: arr[0],
+                b: arr[1],
+                c: arr[2]
+            }
+            var res = filter.call(vm, obj, "'a'", "'$key'")
+            assert.strictEqual(res.length, 1)
+            assert.strictEqual(res[0], arr[0])
+        })
+
     })
 
     describe('orderBy', function () {
@@ -211,6 +222,18 @@ describe('Filters', function () {
             assert.strictEqual(res[2].c, 'c')
         })
 
+        it('should work with objects', function () {
+            var obj = {
+                a: arr[0],
+                b: arr[1],
+                c: arr[2]
+            }
+            var res = filter.call({}, obj, "'$key'", '-1')
+            assert.strictEqual(res[0].c, 'a')
+            assert.strictEqual(res[1].c, 'c')
+            assert.strictEqual(res[2].c, 'b')
+        })
+
     })
 
 })