Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chosen Angular directive doesn't get updated

I've followed this great tutorial (link) for Chosen and Angular (code is pretty much same)

Here is my directive:

app.angularModule.directive('chosen', function() {
    var linker = function (scope, element, attrs) {
        var list = attrs['chosen'];

        scope.$watch(list, function () {
            element.trigger('chosen:updated');
        });

        element.chosen({ width: '350px'});
    };

    return {
        restrict: 'A',
        link: linker
    };
});

Here is html:

<select data-placeholder="Choose a Category"  multiple class="col-lg-8 chosen-select" chosen="items"
                            ng-options="item._backingStore.Name for item in items"   ng-model="selectedCategories" >
                    </select>

What I want is, when user clicks edit button, modal window pops up, and categories that where selected before clicking edit button, are selected in modal window.

Here is that part of controller:

  $scope.$watch(function() { return adminCrudService.getCategoriesForUpdate(); }, function() {
                $scope.action = "edit";
                $scope.categoriesForUpdate = adminCrudService.getCategoriesForUpdate();
                if ($scope.categoriesForUpdate.length > null) {
                    $scope.selectedCategories = _.filter($scope.items, function (item) {
                        return _.contains($scope.categoriesForUpdate, item);
                    });
                }
            });

I've logged $scope.selectedCategories and everything is fine with them, but for some reason there is nothing selected in chosen.

So what am I doing wrong and how can I fix it ?

EDIT

I've noticed when I select some items, close modal, open it again, selected values are there again eve though i put this line inside $watch

$scope.selectedCategories = "";

EDIT 2

So I left this problem for a while, because I had more important things to deal with. I've tried without chosen, i.e. using "normal" select and code works. So Definitively my chosen directive doesn't work as it should.

like image 522
hyperN Avatar asked Aug 15 '13 21:08

hyperN


2 Answers

I've solved it, the solution is pretty easy and straightforward actually (when you get how Angular directives work). Here is whole code for directive:

app.angularModule.directive('chosen', function() {
    var linker = function (scope, element, attrs) {
        var list = attrs['chosen'];

        scope.$watch(list, function () {
            element.trigger('chosen:updated');
        });

        scope.$watch(attrs['ngModel'], function() {
            element.trigger('chosen:updated');
        });

        element.chosen({ width: '350px'});
    };

    return {
        restrict: 'A',
        link: linker
    };
});
like image 153
hyperN Avatar answered Nov 06 '22 17:11

hyperN


More expanded version of comment to previous solution. Same as author, in HTML markup I provide source collection like chosen="vm.myCollection", actually parsing ng-options or ng-repeat property with regexp is better, maybe later. In contrast with OP, I use $watchCollection for an array, and call unwatches when scope is about to destroy.

(function () {
    'use strict';
    angular.module('common.directives').directive('chosen', enterPressDirective);

    function enterPressDirective() {
        return {
            restrict: 'A',
            link: function (scope, elm, attrs) {
                var unwatchModel = scope.$watch(attrs.ngModel, function () {
                    elm.trigger('chosen:updated');
                });

                var unwatchSource = scope.$watchCollection(attrs.chosen, function () {
                    elm.trigger('chosen:updated');
                });

                elm.chosen();

                scope.$on('$destroy', function () {
                    unwatchModel();
                    unwatchSource();
                });
            }
        };
    }
}());
like image 40
Hikiko Avatar answered Nov 06 '22 17:11

Hikiko