PLUNKR example here
I\'m using some version of jquery autocomplete as an angularjs direcitve.
When the jquery updates the input\'s value using element.val()
Your jQuery plugin is updating the view value of the input, but not the model.
You will have to modify the plugin to have access to your model or scope or you will have to bind an event to update the model from the view value manually. Maybe something like this:
$scope.format_tags = function () {
$scope.selected_tags = $('#myInput').val();
$scope.selected_final = _.omit($scope.selected_tags.split(','),_.isEmpty);
};
Here is an updated version of your code using this.
You could bind an event to the click of the actual suggested tag element for a better effect.
As you already knew, the problem is angular doesn't aware of the update made by jquery plugin. Luckily, you can use the plugin's onSelect
callback to update ngModel, like this:
.directive("autoComplete", function() {
return {
restrict: "A" ,
require: 'ngModel', // require ngModel controller
scope: {
AutoCompleteOptions : "=autoCompleteOptions", // use '=' instead of '&'
},
link: function (scope, element, attrs, ngModelCtrl) {
// prevent html5/browser auto completion
attrs.$set('autocomplete','off');
// add onSelect callback to update ngModel
scope.AutoCompleteOptions.onSelect = function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(element.val());
});
};
scope.autocomplete = $(element).autocomplete(scope.AutoCompleteOptions);
}
}
});
The plugin you're using has an onSelect
callback, so you can simply modify your autocomplete parameters to include a callback which updates the scope
{
lookup : $scope.current,
width : 448,
delimiter : /,/,
tabDisabled : true,
minChars : 1,
onSelect: function(v, data) {
$scope.selected_tags = v.value;
$scope.$apply();
}
To further improve this you can remove the need to use the model name in the callback:
function(v, data) {
var model = $(this).attr("ng-model");
$scope[model] = v.value;
$scope.$apply();
}
I don't recommend updating the plugin itself you can change your directive instead to something like this..
app.directive("autoComplete", function() {
return {
restrict : "A" ,
require : '^ngModel',
scope :
{
ngModel: '=',
AutoCompleteOptions : "&autoCompleteOptions"
},
link : function (scope, element,
// prevent html5/browser auto
attrs.$set('autocomplete','off');
var options = scope.
options.onSelect = function(elem) {
scope.$apply(function() {
scope.ngModel = elem.value;
});
};
scope.autocomplete = $(element).autocomplete(scope.AutoCompleteOptions());
}
}
});
As you've noticed in the scope object initialization of the directive I have selected the ngModel attribute as something to be used by the onSelect
event of the AutoComplete Jquery Plugin, where I have updated the model using the scope.$apply() method. Use scope.$apply in a directive so that the scope.$digest() will be invoked and have the model affected directly.