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

Popular posts from this blog

mongodb - How to keep track of users making Stripe Payments -

javascript - Fire on return from form "Submit" -

javascript - Thinglink image not visible until browser resize -