From 77be69603e45e204193edf5d1f30684329e77324 Mon Sep 17 00:00:00 2001 From: Grant Callaghan Date: Thu, 27 Jun 2013 10:06:53 -0700 Subject: [PATCH] feat(typeahead): Use model to hook into pipeline --- src/typeahead/test/integration.js | 23 +++++++++++++++++++++++ src/typeahead/test/typeahead.spec.js | 28 +++++++++++++++++++++++----- src/typeahead/typeahead.js | 18 ++++++++---------- 3 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 src/typeahead/test/integration.js diff --git a/src/typeahead/test/integration.js b/src/typeahead/test/integration.js new file mode 100644 index 0000000000..205d95f143 --- /dev/null +++ b/src/typeahead/test/integration.js @@ -0,0 +1,23 @@ +angular.module('ui.bootstrap.typeahead.test', []) + .directive('formatter', function(){ + return { + require:'ngModel', + link:function(scope, elm, attrs, ngModelCtrl){ + var prefix = attrs.fPrfx === undefined? '' : attrs.fPrfx; + + ngModelCtrl.$formatters.unshift(function(viewVal){ + viewVal = viewVal == null ? viewVal: prefix + viewVal; + return viewVal; + }); + + ngModelCtrl.$parsers.unshift(function(viewVal){ + if (angular.isString(viewVal)) { + if (viewVal.charAt(0) === '$'){ + viewVal = viewVal.slide(1); + } + } + return viewVal; + }); + } + }; + }); diff --git a/src/typeahead/test/typeahead.spec.js b/src/typeahead/test/typeahead.spec.js index 5ca28d0f76..e9f505a49b 100644 --- a/src/typeahead/test/typeahead.spec.js +++ b/src/typeahead/test/typeahead.spec.js @@ -1,6 +1,7 @@ describe('typeahead tests', function () { beforeEach(module('ui.bootstrap.typeahead')); + beforeEach(module('ui.bootstrap.typeahead.test')); beforeEach(module('template/typeahead/typeahead.html')); describe('syntax parser', function () { @@ -250,7 +251,7 @@ describe('typeahead tests', function () { $scope.states = [{code: 'AL', name: 'Alaska'}, {code: 'CL', name: 'California'}]; $scope.result = $scope.states[0]; - var element = prepareInputEl("
"); + var element = prepareInputEl("
"); var inputEl = findInput(element); expect(inputEl.val()).toEqual('Alaska'); @@ -406,14 +407,31 @@ describe('typeahead tests', function () { $scope.states = [{code: 'AL', name: 'Alaska'}, {code: 'CL', name: 'California'}]; - var element = prepareInputEl("
"); + var element = prepareInputEl("
"); var inputEl = findInput(element); changeInputValueTo(element, 'Alas'); triggerKeyDown(element, 13); - expect($scope.result).toEqual('AL'); - expect(inputEl.val()).toEqual('Alaska'); + expect($scope.result.name).toEqual($scope.states[0].code); + expect(inputEl.val()).toEqual('AL'); + }); + }); + + describe('ngModelController pipelines', function (){ + it('should update the input\'s value to reflect the output of the $formatters pipeline', function (){ + var prefix = '$'; + $scope.states = [ + {code: 'AL', name: 'Alaska'}, + {code: 'CL', name: 'California'} + ]; + $scope.result = $scope.states[0]; + element = prepareInputEl("
"), + inputEl = findInput(element); + + expect(inputEl.val()).toEqual(prefix + $scope.result.name); + + }); }); @@ -433,4 +451,4 @@ describe('typeahead tests', function () { }); }); -}); \ No newline at end of file +}); diff --git a/src/typeahead/typeahead.js b/src/typeahead/typeahead.js index c0a0baecb1..a5bb16bae4 100644 --- a/src/typeahead/typeahead.js +++ b/src/typeahead/typeahead.js @@ -47,6 +47,9 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position']) //expressions used by typeahead var parserResult = typeaheadParser.parse(attrs.typeahead); + + //underlying model + var modelGet = $parse(attrs.ngModel); //should it restrict model values to the ones selected from the popup only? var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false; @@ -150,22 +153,17 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position']) return isEditable ? inputValue : undefined; }); - modelCtrl.$render = function () { - var locals = {}; - locals[parserResult.itemName] = selected || modelCtrl.$viewValue; - element.val(parserResult.viewMapper(scope, locals) || modelCtrl.$viewValue); - selected = undefined; - }; scope.select = function (activeIdx) { //called from within the $digest() cycle - var locals = {}; - var model, item; + var locals = {}, model, item; + locals[parserResult.itemName] = item = selected = scope.matches[activeIdx].model; model = parserResult.modelMapper(scope, locals); - modelCtrl.$setViewValue(model); - modelCtrl.$render(); + modelGet.assign(originalScope, model); + selected = undefined; + onSelectCallback(scope, { $item: item, $model: model,