Update Angular model after setting input value with jQuery

Michal J. picture Michal J. · Jun 14, 2013 · Viewed 182.4k times · Source

I have this simple scenario:

Input element which value is changed by jQuery's val() method.

I am trying to update the angular model with the value that jQuery set. I tried to write a simple directive, but it's not doing what I want.

Here's the directive:

var myApp = angular.module('myApp', []);
myApp.directive('testChange', function() {
    return function(scope, element, attrs) {        
        element.bind('change', function() {
            console.log('value changed');
        })
    }
})

this is the jQuery part:

$(function(){
    $('button').click(function(){
        $('input').val('xxx');
    })
})

and html:

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
        <input test-change ng-model="foo" />
        <span>{{foo}}</span>
    </div>
</div>

<button>clickme</button>

Here is the fiddle with my try:
http://jsfiddle.net/U3pVM/743/

Can someone please point me in the right direction?

Answer

Stewie picture Stewie · Jun 14, 2013

ngModel listens for "input" event, so to "fix" your code you'd need to trigger that event after setting the value:

$('button').click(function(){
    var input = $('input');
    input.val('xxx');
    input.trigger('input'); // Use for Chrome/Firefox/Edge
    input.trigger('change'); // Use for Chrome/Firefox/Edge + IE11
});

For the explanation of this particular behaviour check out this answer that I gave a while ago: "How does AngularJS internally catch events like 'onclick', 'onchange'?"


But unfortunately, this is not the only problem you have. As pointed out with other post comments, your jQuery-centric approach is plain wrong. For more info take a look at this post: How do I “think in AngularJS” if I have a jQuery background?).