How to manually fire an input event?

15,160 views
Skip to first unread message

José Rodolfo Freitas

unread,
Feb 12, 2013, 8:03:02 PM2/12/13
to ang...@googlegroups.com
Hello,

I'm developing my first directive and I just found out that $(someElement).trigger('change') won't change the model value in angular.

At reference [1]  the author points that we have to manually fire an input event.
how are you guys achieving that inside your directives? I've digged around and could find a simple way of doing that.

Actually at whe using directive link function, I can't event trigger the change method through jquery $(someElement).trigger('change').

for example. After mapping  the bind above

link: function(scope, element, attrs) {
                element.bind('change', function () {
                    alert("change");
                })
            }

Changing the component value through normal inputs calls the alert("change") inside the bind function, but with a $(component).trigger('change') call won't work.
Could anyone give any light about my problem?

Best Regards,
José


References:
[1] http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED#trigger-change:

"If you've worked with form inputs containing ng-model, you may at a certain point start to wonder why some plugins or even $.fn.trigger('change') isn't updating the model. After some digging through the source, we found that Angular doesn't actually watch the change event by default. Instead it watches the new input event. Read up about the differences here.

A simple hack we did for the AngularUI passthrough directive was to bind to the change event and manually fire an input event, however I recommend instead trying to leverage the new input event where you can instead."


Peter Bacon Darwin

unread,
Feb 13, 2013, 4:36:43 AM2/13/13
to ang...@googlegroups.com
Can you give the context in which you want to do this?  There are many ways of skinning a cat but it depends upon the type of cat.



--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

José Rodolfo Freitas

unread,
Feb 13, 2013, 4:57:02 AM2/13/13
to ang...@googlegroups.com
Hi Peter,
I've just found out that I can bind on jquery change event.
{
angular.element(element).triggerHandler('change');
}

Basically my case is that I have a button that changes a select's value, and I can't simple change just the model value because that's the way a bootstrap plugin I am wrapping is working.

There are some problems with the bind function tha't I didnt find out yet, it doesn't work always as expected. The event work the first time and then it gets messy and consufed.

José Rodolfo Freitas

unread,
Feb 13, 2013, 5:02:09 AM2/13/13
to ang...@googlegroups.com
Fixed. :)
Still, if the way I used to solve the problem isn't the right way of doing it, please point me out.

Peter Bacon Darwin

unread,
Feb 13, 2013, 5:07:45 AM2/13/13
to ang...@googlegroups.com
Glad you got it working.  Without seeing the code it is difficult to know if it is the right way :-)

José Rodolfo Freitas

unread,
Feb 13, 2013, 5:14:20 AM2/13/13
to ang...@googlegroups.com
Hi Peter,
it's a really simple directive just to bind an event to the <select> that uses the attribute super-select.

directive("superSelect", function(){

        return {
            restrict: 'A',
            link: function(scope, element, attrs, controller) {
                $("#"+attrs['id']).bind('change', function () {
                    angular.element(element).triggerHandler('change');
                });
            }
        }
    });

Peter Bacon Darwin

unread,
Feb 13, 2013, 5:19:03 AM2/13/13
to ang...@googlegroups.com
Hold on...

Am I reading this wrong? You are asking it to trigger the change event whenever the change event occurs?

[by the way, angular.element(element) === element in the link function]

[also isn't $('#'+attrs.id) === element?]

José Rodolfo Freitas

unread,
Feb 13, 2013, 5:26:10 AM2/13/13
to ang...@googlegroups.com
hehehe calm down, Peter.

My initial problem is that  calling the jquery trigger() function like:

$(someElement).trigger('change')

would not call the angular change event.

So, what I did is that I binded to the jquery event change the call to the angular event change.

the #attrs[id] wasn't really necessary, I was just making sure to use a pure html element when using jquery, for testing purposes. but I'm using $(element) now.

José Rodolfo Freitas

unread,
Feb 13, 2013, 5:28:52 AM2/13/13
to ang...@googlegroups.com
oh, now I am confused.

element is the pure html element reference? or is an element powered up by angular?

I tested with
$(element).bind('change', function () {
                    element.triggerHandler('change');
});

and it worked, but it doesn't feel safe.

Peter Bacon Darwin

unread,
Feb 13, 2013, 5:48:42 AM2/13/13
to ang...@googlegroups.com
The element parameter passed to the link function is already wrapped in jQuery/jqLite

Peter Bacon Darwin

unread,
Feb 13, 2013, 5:49:13 AM2/13/13
to ang...@googlegroups.com
So you can write

element.bind('change', function() { element.triggerHandler('change'); });

if you want

José Rodolfo Freitas

unread,
Feb 13, 2013, 7:01:51 AM2/13/13
to ang...@googlegroups.com
Hi Peter,
that didn't work for me.
Although I've read that element is wrapped by some kind of jquerylite, element.bind() seems to be different as $(element).bind().
I've jquery1.9.1 loaded on my system, that could be the reason.

Peter Bacon Darwin

unread,
Feb 13, 2013, 7:05:14 AM2/13/13
to ang...@googlegroups.com
Again, without seeing your code it is difficult.  Is jQuery being loaded before AngularJS?

Mikal Madsen

unread,
Sep 5, 2016, 6:07:22 PM9/5/16
to AngularJS
In my use case I could not bind, and triggering "input" or "change" did not work. After digging and testing a variety of approaches, I finally found it:

Inside the link function, do:

element.controller('ngModel').$viewChangeListeners[0]();

In my case the directive is on an <input>.

Full example: trigger ng-change on blur:

wpModule.directive('triggerChangeOnBlur', function () {
   
return {
        restrict
: 'A',
            link
: function (scope, element, attrs) {
                element
.on('blur', function () {
                    element
.controller('ngModel').$viewChangeListeners[0]();
               
});
           
}
   
};
}]);
Reply all
Reply to author
Forward
0 new messages