Skip to content

Commit 92f46b6

Browse files
committed
fix(orderBy): support string predicates containing non-ident characters
The orderBy filter now allows string predicates passed to the orderBy filter to make use property name predicates containing non-ident strings, such as spaces or percent signs, or non-latin characters. This behaviour requires the predicate string to be double-quoted. In markup, this might look like so: ```html <div ng-repeat="item in items | orderBy:'\"Tip %\"'"> ... </div> ``` Or in JS: ```js var sorted = $filter('orderBy')(array, ['"Tip %"', '-"Subtotal $"'], false); ``` Closes angular#6143
1 parent a8c1d9c commit 92f46b6

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

src/ng/filter/orderBy.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,28 @@
6262
*/
6363
orderByFilter.$inject = ['$parse'];
6464
function orderByFilter($parse){
65+
var STRING_REGEXP = /^\s*(['"])([^'"]*)(['"])\s*$/;
6566
return function(array, sortPredicate, reverseOrder) {
67+
var locals;
6668
if (!isArray(array)) return array;
6769
if (!sortPredicate) return array;
6870
sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
6971
sortPredicate = map(sortPredicate, function(predicate){
70-
var descending = false, get = predicate || identity;
72+
var descending = false, get = predicate || identity, match;
7173
if (isString(predicate)) {
7274
if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) {
7375
descending = predicate.charAt(0) == '-';
7476
predicate = predicate.substring(1);
7577
}
78+
if ((match = predicate.match(STRING_REGEXP)) && match[1] === match[3]) {
79+
locals = locals || {item: null};
80+
get = $parse('item["'+match[2]+'"]');
81+
return reverseComparator(function(a,b) {
82+
locals.item = a, a = get(a, locals), locals.item = b, b = get(b, locals);
83+
return compare(a, b);
84+
}, descending);
85+
}
86+
7687
get = $parse(predicate);
7788
}
7889
return reverseComparator(function(a,b){

test/ng/filter/orderBySpec.js

+6
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@ describe('Filter: orderBy', function() {
3131
toEqual([{a:2, b:1},{a:15, b:1}]);
3232
});
3333

34+
it('should support string predicates with names containing non-identifier characters', function() {
35+
expect(orderBy([{"Tip %": .25}, {"Tip %": .15}, {"Tip %": .40}], '"Tip %"'))
36+
.toEqualData([{"Tip %": .15}, {"Tip %": .25}, {"Tip %": .40}]);
37+
expect(orderBy([{"원": 76000}, {"원": 31000}, {"원": 156000}], '"원"'))
38+
.toEqualData([{"원": 31000}, {"원": 76000}, {"원": 156000}])
39+
});
3440
});

0 commit comments

Comments
 (0)