diff --git a/dist/angular-selectize.js b/dist/angular-selectize.js index a009975..eb41aa0 100755 --- a/dist/angular-selectize.js +++ b/dist/angular-selectize.js @@ -17,12 +17,12 @@ angular.module('selectize', []).value('selectizeConfig', {}).directive("selectiz scope.config = scope.config || {}; var isEmpty = function(val) { - return val === undefined || val === null || !val.length; //support checking empty arrays + return val === undefined || val === null || val.length === 0; // support checking empty arrays / strings }; var toggle = function(disabled) { disabled ? selectize.disable() : selectize.enable(); - } + }; var validate = function() { var isInvalid = (scope.ngRequired() || attrs.required || settings.required) && isEmpty(scope.ngModel); @@ -30,18 +30,26 @@ angular.module('selectize', []).value('selectizeConfig', {}).directive("selectiz }; var setSelectizeOptions = function(curr, prev) { - angular.forEach(prev, function(opt){ - if(curr.indexOf(opt) === -1){ + if (!curr) + return; + if (scope._noUpdate) { // Internal changes to scope.options, eschew the watch mechanism + scope._noUpdate = false; + return; + } + scope._skipRemove = true; + angular.forEach(prev, function(opt) { + if (curr.indexOf(opt) === -1) { var value = opt[settings.valueField]; selectize.removeOption(value, true); } }); - - selectize.addOption(curr, true); - - selectize.refreshOptions(false); // updates results if user has entered a query - setSelectizeValue(); - } + scope._skipRemove = false; + angular.forEach(curr, function(opt) { + selectize.registerOption(opt); + }); + selectize.lastQuery = undefined; // Hack because of a Selectize bug... + selectize.refreshOptions(false); // Update the content of the drop-down + }; var setSelectizeValue = function() { validate(); @@ -52,30 +60,77 @@ angular.module('selectize', []).value('selectizeConfig', {}).directive("selectiz selectize.$control.toggleClass('ng-pristine', modelCtrl.$pristine); if (!angular.equals(selectize.items, scope.ngModel)) { - selectize.setValue(scope.ngModel, true); + if (scope.config.create && angular.isArray(scope.ngModel)) { + scope._silentChanges = true; // addOption / createItem has no silent option! + selectize.clear(true); + // Items might be in model but not in options: we create them in both, as user options + for (var i = 0; i < scope.ngModel.length; i++) { + var item = scope.ngModel[i]; + var found = false; + for (var j = 0; j < scope.options.length; j++) { + if (scope.options[j][settings.valueField] === item) { + found = true; + break; + } + } + if (found) { // Existing option, just add it to the item list + selectize.addItem(item, true); + } else { // Not a known option, create it along with the item + selectize.createItem(item, false); + } + } + scope._silentChanges = false; + settings.onChange(scope.ngModel); + } else { + selectize.setValue(scope.ngModel, true); + } } - } + }; settings.onChange = function(value) { - var value = angular.copy(selectize.items); - if (settings.maxItems == 1) { - value = value[0] + if (scope._silentChanges) + return; // Avoid intermediary updates and side effects + var items = angular.copy(selectize.items); + if (settings.maxItems === 1) { + items = items[0]; } - modelCtrl.$setViewValue( value ); + modelCtrl.$setViewValue(items); if (scope.config.onChange) { scope.config.onChange.apply(this, arguments); } }; + // User entered a new tag. settings.onOptionAdd = function(value, data) { - if( scope.options.indexOf(data) === -1 ) { + if (scope.options.indexOf(data) === -1) { + scope._noUpdate = true; scope.options.push(data); + } + if (scope.config.onOptionAdd) { + scope.config.onOptionAdd.apply(this, arguments); + } + }; - if (scope.config.onOptionAdd) { - scope.config.onOptionAdd.apply(this, arguments); + // User removed a tag they entered, or we called removeOption(). + // Note: it is not called if persist is true. + settings.onOptionRemove = function(value) { + if (scope._skipRemove) + return; + var idx = -1; + for (var i = 0; i < scope.options.length; i++) { + if (scope.options[i][scope.config.valueField] === value) { + idx = i; + break; } } + if (idx !== -1) { + scope._noUpdate = true; + scope.options.splice(idx, 1); + } + if (scope.config.onOptionRemove) { + scope.config.onOptionRemove.apply(this, arguments); + } }; settings.onInitialize = function() { @@ -90,7 +145,7 @@ angular.module('selectize', []).value('selectizeConfig', {}).directive("selectiz } scope.$watchCollection('options', setSelectizeOptions); - scope.$watch('ngModel', setSelectizeValue); + scope.$watchCollection('ngModel', setSelectizeValue); scope.$watch('ngDisabled', toggle); };