1

I use angularjs with "ui_select2" directive. Select2 draws new tags with formatting function, there are "" elements with "ng-click" attribute. How to tell angularjs about new DOM elements? Otherwise new "ng-clicks" wont work.

HTML:

<input type="text" name="contact_ids" ui-select2="unit.participantsOptions" ng-model="unit.contactIds" />

JS (angular controller):

anyFunction = function(id) {
    console.log(id)
}

formatContactSelection = function(state) {
    return "<a class=\"select2-search-choice-favorite\" tabindex=\"-1\" href=\"\" ng-click=\"anyFunction(state.id)\"></a>"
}

return $scope.unit.participantsOptions = {
    tags: [],
    formatSelection: formatContactSelection,
    escapeMarkup: function(m) {
        return m
    },
    ajax: {
        url: '/contacts/search',
        quietMillis: 100,
        data: function(term, page) {
            return {
                term: term,
                limit: 20,
                page: page
            }
        },
        results: function(data, page) {
            return {
                results: data,
                more: (page * 10) < data.total
            }
        }
    }

}

The problem is that select2 creates DOM elements, that not yet discovered by angularjs, I read that new DOM elements need to be appended to some element with using angularjs $compile function, but I cannot use it in controller.

1 Answer 1

1

I found a solution - I created the directive, that watches for changes in ngModel and apply it on the element, that has already ui_select2 directive. "uiRequiredTags" implements custom behavior I need for my select2 tag choices. The solution is to watch changes in ngModel attribute.

angular.module("myAppModule", []).directive("uiRequiredTags", function() {
    return {
        restrict: 'A',
        require: "ngModel",
        link: function(scope, el, attrs) {
            var opts;
            opts = scope.$eval("{" + attrs.uiRequiredTags + "}");
            return scope.$watch(attrs.ngModel, function(val) {
                var $requireLink;
                $requireLink = el.parent().find(opts.path);
                $requireLink.off('click');
                $requireLink.on('click', function() {
                    var id, n, tagIds;
                    id = "" + ($(this).data('requiredTagId'));
                    if (opts.removeLinkPath && opts.innerContainer) {
                    $(this).parents(opts.innerContainer).find(opts.removeLinkPath).data('requiredTagId', id);
                }
                tagIds = scope.$eval(opts.model).split(',');
                n = tagIds.indexOf(id);
                if (n < 0) {
                    tagIds.push(id);
                } else {
                    tagIds.splice(n, 1);
                }
                scope.$eval("" + opts.model + " = '" + tagIds + "'");
                scope.$apply();
                return $(this).toggleClass('active');
            });

        });
    }
};
Sign up to request clarification or add additional context in comments.

Comments

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.