5

I've been trying to implement Selectize with AngularJS (1.2.4). I'm using this directive to interface with the plugin and everything is working smoothly until now. When using the ngModel from a normal select box It works fine, and returns the expected object but when I try to use it with the multiple attribute, it won't set the model.

I've inspected the DOM and appears the script removes unselected options from the hidden select and that might be messing with the angular binding.

I've created a Plunkr to demonstrate the behaviour.

http://plnkr.co/It6C2EPFHTMWOifoYEYA

Thanks

4
  • You're going to need far more than a one-liner in your directive to stitch this jQuery plugin together with Angular.JS. You need to explicitly handle the "change" event triggered by Selectize, so that it can inform Angular.JS what just happened. Commented Jun 7, 2014 at 9:07
  • When you look at the plunker example for selectize.js there are two states. 1) "$scope.options" [does not change] 2) selectizeModel [transient]. In your case you have only one state hence the effect of it being removed. Commented Jun 10, 2014 at 22:30
  • Is this an exercise? If not, why re-invent the wheel? Use github.com/angular-ui/ui-select Commented Jun 24, 2014 at 20:33
  • Try this repo : github.com/machineboy2045/angular-selectize I am using it and its working by default. Commented Jul 31, 2015 at 3:52

1 Answer 1

3

As mentioned in the comments above, your directive must listen to changes in the selectize plugin and then inform angular of what happened via ng-model.

First, your directive needs to ask for an optional reference to the ngModel controller with the following:

require: '?ngModel'.

It is injected into your link function as an argument in the 4th position:

function(scope,element,attrs,ngModel){}

Then, you must listen for changes in selectize with $(element).selectize().on('change',callback)

and inform ngModel with ngModel.$setViewValue(value)

Here is a modified version of your directive. It should get you started.

angular.module('angular-selectize').directive('selectize', function($timeout) {
    return {
        // Restrict it to be an attribute in this case
        restrict: 'A',
        // optionally hook-in to ngModel's API 
        require: '?ngModel',
        // responsible for registering DOM listeners as well as updating the DOM
        link: function(scope, element, attrs, ngModel) {
            var $element;
            $timeout(function() {
                $element = $(element).selectize(scope.$eval(attrs.selectize));
                if(!ngModel){ return; }//below this we interact with ngModel's controller
                //update ngModel when selectize changes
                $(element).selectize().on('change',function(){
                    scope.$apply(function(){
                        var newValue = $(element).selectize().val();
                        console.log('change:',newValue);                    
                        ngModel.$setViewValue(newValue);
                    });
                });
            });
        }
    };
});

Also:

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.