Wrapping ui-select with angularjs custom directive -
yes, there couple of similar questions on so, none seem address issue (or work recent versions of angular 1.5.8 , angular ui-select 1.4.x).
the problem i'm having bi-directional data binding. when try bind model ui-select, if without directive wrapped ui-select, works. when use wrapped ui-select, updated in 1 direction, until modify model within directive.
index.html
<div class="form-group"> <label class="control-label" for="test">test</label> <ui-select id="test" multiple="" ng-model="vm.selectedinstrument.gradelevels" theme="bootstrap" close-on-select="false" append-to-body="true" style="min-width: 250px"> <ui-select-match placeholder="this test">{{$item.name}}</ui-select-match> <ui-select-choices repeat="opt in vm.gradelevellist | filter:$select.search"> <div ng-bind-html="opt.name | highlight: $select.search"></div> </ui-select-choices> </ui-select> <span class="help-block"> {{vm.selectedinstrument | json}} </span> </div> <tag-input ng-model="vm.selectedinstrument.gradelevels" placeholder="select 1 or more..." label-text="grade levels" options="vm.gradelevellist" ele-id="gradeleveltaginput"></tag-input>
tag-input-directive.js
(function () { 'use strict'; angular.module('surveyexplorer') .directive('taginput', taginput); function taginput() { return { restrict: 'e', templateurl: 'tag-input.html', scope: { options: '=', editmode: '=', labeltext: '@', eleid: '@s', placeholder: "@" }, require: ['?ngmodel'], link: function (scope, elem, attrs, ctrls) { var ngmodelctrl = ctrls[0]; ngmodelctrl.$render = function() { scope.innermodel = ngmodelctrl.$viewvalue; }; scope.$watch('innermodel', function(newval, oldval){ if (newval !== oldval) { ngmodelctrl.$setviewvalue(newval); } }); } }; } })();
tag-input.html
<div class="form-group"> <label class="control-label" for="{{eleid}}">{{labeltext}}</label> <ui-select id="{{eleid}}" multiple ng-model="innermodel" theme="bootstrap" close-on-select="false" append-to-body="true" style="min-width: 250px"> <ui-select-match placeholder="{{placeholder}}">{{$item.name}}</ui-select-match> <ui-select-choices repeat="opt in options | filter:$select.search" class="scrollable-menu"> <div ng-bind-html="opt.name | highlight: $select.search"></div> </ui-select-choices> </ui-select> <span class="help-block"> {{innermodel}} </span> </div>
script.js
(function(angular) { 'use strict'; angular.module('surveyexplorer', [ 'ngsanitize', 'nganimate', 'ui.bootstrap', 'ui.select', ]) .controller('instrumentctrl', [function() { var vm = this; vm.selectedinstrument = { gradelevels: [] }; vm.gradelevellist = [{ "code": "it", "name": "infant/toddler", "sortorder": 1000, "gradelevelid": 1 }, { "code": "pr", "name": "preschool", "sortorder": 2000, "gradelevelid": 2 }, { "code": "pk", "name": "prekindergarten", "sortorder": 3000, "gradelevelid": 3 }, { "code": "tk", "name": "transitional kindergarten", "sortorder": 4000, "gradelevelid": 4 }, { "code": "kg", "name": "kindergarten", "sortorder": 5000, "gradelevelid": 5 }, { "code": "1", "name": "first grade", "sortorder": 6000, "gradelevelid": 6 }, { "code": "2", "name": "second grade", "sortorder": 7000, "gradelevelid": 7 }, { "code": "3", "name": "third grade", "sortorder": 8000, "gradelevelid": 8 }, { "code": "4", "name": "fourth grade", "sortorder": 9000, "gradelevelid": 9 }, { "code": "5", "name": "fifth grade", "sortorder": 10000, "gradelevelid": 10 }]; }]); })(window.angular);
i've created plunker of problem here: https://plnkr.co/edit/yn1qhmjkuij7fm8unpad
notice when add tags top control, updates data model in bottom control. when add tags bottom control, stops updating data model. suspect has how model getting bound using ng-model
.
any graciously appreciated.
fwiw, thread similar problem: angularjs pass ngmodel wrapper directive wrapped directive when try mimic solution, gets me point right now.
so found solution, understand "why" works not 100% sure why.
so first off, simplified directive:
tag-input-directive.html
(function () { 'use strict'; angular.module('surveyexplorer') .directive('taginput', taginput); function taginput() { return { restrict: 'e', templateurl: 'tag-input.html', scope: { ngmodel: '=', options: '=', editmode: '=', labeltext: '@', eleid: '@s', placeholder: "@" }, controller: function($scope) { $scope.innermodel = $scope; } }; } })();
where assign passed in scope property on scope within controller function:
controller: function($scope) { $scope.innermodel = $scope; }
then updated references ngmodel
in template use innermodel.ngmodel
:
tag-input.html
<div class="form-group"> <label class="control-label" for="{{eleid}}">{{labeltext}}</label> <ui-select id="{{eleid}}" multiple ng-model="innermodel.ngmodel" theme="bootstrap" close-on-select="false" append-to-body="true" style="min-width: 250px"> <ui-select-match placeholder="{{placeholder}}">{{$item.name}}</ui-select-match> <ui-select-choices repeat="opt in options | filter:$select.search" class="scrollable-menu"> <div ng-bind-html="opt.name | highlight: $select.search"></div> </ui-select-choices> </ui-select> <span class="help-block"> {{innermodel.ngmodel}} </span> </div>
here's link functioning plunkr: https://plnkr.co/edit/eq9pil8kohz2puta2plu?p=preview
i suspect within ui-select clobbering scope, not quite sure how prove or track down without lot of additional effort.
Comments
Post a Comment