ui-select2 icon indicating copy to clipboard operation
ui-select2 copied to clipboard

initSelection fires when selection is made (not just at load time)

Open entrity opened this issue 11 years ago • 3 comments

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:

  1. ng-change callback
  2. initSelection
  3. 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()">

entrity avatar Jun 24 '14 18:06 entrity

Any solution to this? I experience the same problem...

cime avatar Jul 02 '14 07:07 cime

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?

entrity avatar Jul 02 '14 14:07 entrity

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());
        }
    }
});

entrity avatar Jul 02 '14 15:07 entrity