initSelection fires when selection is made (not just at load time)
I'm trying to implement an input with options from Ajax, with single selection, with an ng-change callback. The following observation could be operator error, but oddly, I find function calls occurring in the following order:
- ng-change callback
- initSelection
- ng-change callback
My problem
This behavior is fouling my operation. My understanding (please correct me if I am wrong) is that initSelection should fire only once, when the select2 element is created.
As matters stand, the text to display for my selection gets overwritten when initSelection fires. (I.e. after the selection, the selected record's name cannot appear at the top of the select2 element because my initSelection function overwrites it, and I see no way to access the text for the selected option, so I can't even set the display text manually.)
My js
// global select2 options
$.extend(jQuery.fn.select2.defaults, {
allowClear: true,
width: 'resolve',
placeholder: '(autocomplete)',
minimumInputLength: 1,
dataType: 'json'
});
// select2 options for the html below
window.select2UserOptions = {
initSelection: function (element, callback) {
callback({id: element.val(), text: element.val()});
},
ajax: {
url: '/users.json',
data: function (term, page) {
return {}
},
results: function (data, page) {
var results = $.map(data, function(result, i) {
return { id:result['id'], text:result['text'] }
});
return {results: results}
}
}
}
// angular js module & controller & callback
angular.module('myModule', [])
.controller('MyAccountCtrl', function ($scope, miscFns) {
// $scope.user gets inherited from a higher controller
$scope.myCallback = function () { debugger }
})
My .html
<input ui-select2="window.select2UserOptions" ng-model="user.aor_id" data-selection="{{user.aor_id}}" ng-change="myCallback()">
Any solution to this? I experience the same problem...
Alas, no solution but to write my own directive:
js
angular.module('myModule', [])
.directive('mySelect2', function(){
return {
restrict: 'A',
scope: {
options: '&mySelect2',
},
link: function (scope, elem, attrs) { elem.select2(scope.options()) }
}
})
html
<input my-select2="{ajax:myAjaxOptions, width:'resolve'}" ng-model="myObj.myValue">
Unfortunately, I don't see how to create the initial selection in my directive (for records that already have the ng-model value set) when the ajax option is used. Do you have any idea?
Ok, I have a way, but it's a bit kludgy:
html
<input my-select2="window.mySelect2Options" ng-model="myObj.myValue" data-display="myObj.myText">
js
window.mySelect2Options = {
ajax: myAjaxOptions, // pretend this is defined somewhere
initSelection: function (element, callback) {
// get text by applying attrs['data-display'] against scope
var text = element.data('display').split('.').reduce(function(p,c){ return p[c]; }, element.scope());
// get value by applying attrs['ng-model'] against scope
var val = element.attr('ng-model').split('.').reduce(function(p,c){ return p[c]; }, element.scope());
if (text && val != null) callback({id:val, text:text});
}
};
angular.module('myModule', [])
.directive('mySelect2', function(){
return {
restrict: 'A',
scope: { options: '&drSelect2' },
link: function (scope, elem, attrs) {
if (!elem.attr('value')) elem.attr('value', 0); // This shall be ignored, but a value must be set for initSelection to fire
elem.select2(scope.options());
}
}
});