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()
angular does no notice the change until after the next digest ( i suppose ).
My first thought was to perform the action on the ng-model
post digest using $timeout
but as you can see it didn't help.
My second approach was to override the element's val
function to trigger an input
event but I haven`t managed to make it work.
Try to select a value from the autocomplete list and you'll see that the ng-model above is not updating.
UPDATE
Thanks for the response. I didn't know about the onSelect
option.
This is the code based on your recommendations
// clone user provided options
scope.options = _.extend({}, scope.AutoCompleteOptions());
// Wrap onSelect - Force update before manipulation on ng-model
var fn = _.has(scope.AutoCompleteOptions(), 'onSelect') ? scope.AutoCompleteOptions().onSelect : _.noop;
scope.options.onSelect = function () {
ngModelCtrl.$setViewValue(element.val());
scope.$apply(fn);
};
scope.autocomplete = $(element).autocomplete(scope.options);
This way i maintain the interface of the directive while guarantying that ng-model
will be up to date.
Thanks.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With