diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d3226e6..358a6ee3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ + +## [0.14.9](https://github.com/angular-ui/ui-select/compare/v0.14.9...v0.14.9) (2016-03-06) + + + + ## [0.14.8](https://github.com/angular-ui/ui-select/compare/v0.14.8...v0.14.8) (2016-02-18) diff --git a/package.json b/package.json index 02c1ad4a5..9846ad083 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "git://github.com/angular-ui/ui-select.git" }, "style": "dist/select.css", - "version": "0.14.9", + "version": "0.14.10", "devDependencies": { "bower": "~1.3", "conventional-changelog": "^0.5.3", diff --git a/src/uisRepeatParserService.js b/src/uisRepeatParserService.js index 5ee44bc72..1b5ce822b 100644 --- a/src/uisRepeatParserService.js +++ b/src/uisRepeatParserService.js @@ -22,38 +22,48 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE var match; - var isObjectCollection = /\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)/.test(expression); + //var isObjectCollection = /\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)/.test(expression); // If an array is used as collection // if (isObjectCollection){ - //00000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000556666660000077777777777755000000000000000000000088888880000000 - match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(([\w\.]+)?\s*(|\s*[\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); + // 000000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000055555555555000000000000000000000066666666600000000 + match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(\s*[\s\S]+?)?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); // 1 Alias // 2 Item // 3 Key on (key,value) // 4 Value on (key,value) - // 5 Collection expresion (only used when using an array collection) - // 6 Object that will be converted to Array when using (key,value) syntax - // 7 Filters that will be applied to #6 when using (key,value) syntax - // 8 Track by + // 5 Source expression (including filters) + // 6 Track by if (!match) { throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression); } - if (!match[6] && isObjectCollection) { - throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ as (_key_, _item_) in _ObjCollection_ [ track by _id_]' but got '{0}'.", - expression); + + var source = match[5], + filters = ''; + + // When using (key,value) ui-select requires filters to be extracted, since the object + // is converted to an array for $select.items + // (in which case the filters need to be reapplied) + if (match[3]) { + // Remove any enclosing parenthesis + source = match[5].replace(/(^\()|(\)$)/g, ''); + // match all after | but not after || + var filterMatch = match[5].match(/^\s*(?:[\s\S]+?)(?:[^\|]|\|\|)+([\s\S]*)\s*$/); + if(filterMatch && filterMatch[1].trim()) { + filters = filterMatch[1]; + source = source.replace(filters, ''); + } } return { itemName: match[4] || match[2], // (lhs) Left-hand side, keyName: match[3], //for (key, value) syntax - source: $parse(!match[3] ? match[5] : match[6]), - sourceName: match[6], - filters: match[7], - trackByExp: match[8], + source: $parse(source), + filters: filters, + trackByExp: match[6], modelMapper: $parse(match[1] || match[4] || match[2]), repeatExpression: function (grouped) { var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items'); diff --git a/test/select.spec.js b/test/select.spec.js index 7c4018638..97714af61 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -260,6 +260,32 @@ describe('ui-select tests', function() { }); + it('should parse simple property binding repeat syntax with a basic filter', function () { + + var locals = {}; + locals.people = [{ name: 'Wladimir' }, { name: 'Samantha' }]; + locals.person = locals.people[1]; + + var parserResult = uisRepeatParser.parse('person.name as person in people | filter: { name: \'Samantha\' }'); + expect(parserResult.itemName).toBe('person'); + expect(parserResult.modelMapper(locals)).toBe(locals.person.name); + expect(parserResult.source(locals)).toEqual([locals.person]); + + }); + + it('should parse simple property binding repeat syntax with track by', function () { + + var locals = {}; + locals.people = [{ name: 'Wladimir' }, { name: 'Samantha' }]; + locals.person = locals.people[0]; + + var parserResult = uisRepeatParser.parse('person.name as person in people track by person.name'); + expect(parserResult.itemName).toBe('person'); + expect(parserResult.modelMapper(locals)).toBe(locals.person.name); + expect(parserResult.source(locals)).toBe(locals.people); + + }); + it('should parse (key, value) repeat syntax', function() { var locals = {};