Question

I have created custom select2 directive for angular it works perfect for my usecase and works like charm when i use template and it sets and get the values from input/ngModel but when i use it on view page it do not resolve ngModel via scope.$eval

this is something scope issue please help me on this please find directive mentioned below:

(function () {
'use strict';
var directiveId = 'snSelect2';
angular.module('app').directive(directiveId, ['datacontext', snSelect2]);

function snSelect2(datacontext) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, controller) {
            var urlPrefix =datacontext.urlPrefix;
            $(function () {
                element.select2({
                    placeholder: element.attr('placeholder'),
                    multiple: angular.isDefined(attrs.multiple),
                    minimumInputLength: 3,
                    blurOnChange: true,
                    ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
                        url: urlPrefix + "/Employees",
                        dataType: 'json',
                        data: function (term) {
                            return {
                                term: term
                            };
                        },
                        results: function (data) { // parse the results into the format expected by Select2.
                            // since we are using custom formatting functions we do not need to alter remote JSON data
                            return { results: data };
                        }
                    },
                    initSelection: function (element, callback) {
                        var id = scope.$eval(attrs.ngModel);//$(element).val();
                        if (id != "") {
                            $.ajax(urlPrefix + "/EmployeeById",
                                {
                                    data: {
                                        id: id,
                                        format: 'json'
                                    },
                                    datatype: 'json'
                                }).done(function (data) {
                                    if (angular.isDefined(attrs.multiple)) {
                                        callback(data);
                                    }
                                    else {
                                        callback(data[0]);
                                    }
                                });
                        }
                        //var data = {id: element.val(), text: element.val()};
                        //callback(data);
                    },
                    dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
                    escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
                }).select2('val', scope.$eval(attrs.ngModel))
                    .on("change", function (e) {
                        scope.$apply(function () {
                            controller.$setViewValue(attrs.ngModel);
                        });
                    });
                element.bind("change", function (e) {
                    scope.$apply(function () {
                        scope[attrs.ngModel] = e.val;
                    });
                });
            });
        }
    }
}})();
Was it helpful?

Solution

http://snag.gy/lcizI.jpg

<!-- html element -->
<input type="hidden" class="form-control" data-ng-model="show" ui-select2="getShow">


  $scope.getShow = {
    placeholder: "Enter Show Code",
    minimumInputLength: 3,
    escapeMarkup: function (m) { return m; },
    formatSelection: function(obj, container) {
      return "ID: " + obj.showid + " - " + obj.name;
    },
    formatResult: function(obj, container, query) {
      var start = obj.startdate ? moment(obj.startdate).format("DD/MM/YYYY") : "Unknown";
      var end = obj.enddate ? moment(obj.enddate).format("DD/MM/YYYY") : "Unknown";
      return '<div class="list-group-item small">' +
                '<i><span class="label label-default pull-right">ID: ' + obj.showid + '</span></i>' +
                '<i><span class="label label-info">(' + obj.code + ')</span></i>' + 
                '<div style="padding-top: 4px"><strong>' + obj.name + '</strong></div>' +
                '<i>' + start + " - " + end + '</i>' +
              '</div>';
    },
    query: function(options) {
      if (!options.context)
        options.context = {};

      // status == processing means http request is in process, so don't do it again 
      if (options.context.status === "processing")
        return;
      options.context.status = "processing";

      // this is just like ajax $http.get("/search"). 
      model.show.search("search", {code: options.term, limit: 10, sort: 'ts desc'} )
      .then(function(result) {

        // set status = completed to indicate http request finished.
        options.context.status = "completed";

        // when you get the result from ajax, callback require you to call with
        // an object { results: your result } as result
        $scope.list.datalist.show = result;
        options.callback({
          results: result
        });

      });

    }

  }


Data from server looks like
[{
code: "MELCCS"
enddate: "2014-03-10T14:00:00.000Z"
id: "5329c28087b375a4d8a2af43"
name: "Melbourne Caravan and Camping Show"
openinghour: ""
showid: 1810
startdate: "2014-03-05T14:00:00.000Z"
state: "VIC"
status: "Research"
ts: 1395245779280
updatedAt: "2014-03-21T09:16:56.859Z"
warehouse: "52ecd53b673a5fba428e21a7"
}]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top