0

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;
                    });
                });
            });
        }
    }
}})();
3
  • have you take a look at ui-select2 src first to see how it implement. Commented Mar 24, 2014 at 6:06
  • Yes i have looked into ui-select2 but usage with ajax is not straight forward so i wrote my own on top of jquery select2 the only issue i am facing is scope issue that to on view page not when i used this with view template Commented Mar 24, 2014 at 6:14
  • I am not discourage you to write directive, but I just put my code for ui-select2 if you want to look at it. I think it is not hard to make it work. Commented Mar 24, 2014 at 6:26

1 Answer 1

1

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"
}]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Wayne It is working for me except it is showing initSelection() is not defined

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.