Call a function defined in controller on a keydown event.

9,380 views
Skip to first unread message

curiou...@gmail.com

unread,
Aug 14, 2012, 4:06:03 PM8/14/12
to ang...@googlegroups.com
I have the following code in my slides.js file:

// Angular code to increase and decrease counter value.
function myctrl($scope) {
$scope.countervalue = 0;

$scope.increasecounter = function (){
$scope.countervalue = $scope.countervalue + 1;
};

$scope.decreasecounter = function() {
$scope.countervalue = $scope.countervalue - 1;
}

};

I have an increase and decrease buttons in my view, which increase and decrease the countervalue by calling the increasecounter and decreasecounter function respectively. Specifically, in the html file I have:

<button ng-click="increasecounter()">Increase</button>
<button ng-click="decreasecounter()">Decrease</button>

I want to also decrease the countervalue when left arrow key is pressed. I tried including the following jquery in both the html file as well as the js file which contains the above angular code:

$(document).keydown(function(event) {

});

curiou...@gmail.com

unread,
Aug 14, 2012, 4:09:26 PM8/14/12
to ang...@googlegroups.com, curiou...@gmail.com

Sorry. The previous post was incomplete (pressed tab then enter by mistake)

     if (event.which == 37) {
          decreasecounter();
     }
});

But in both cases I get the error that function decreasecounter() is not defined. I also tried $scope.decreasecounter() instead of just decreasecounter(). I still get the same error. How can I have decreasecounter() function be triggered when the user presses left arrow key.

Thank you.

Will Kriski

unread,
Aug 14, 2012, 4:11:01 PM8/14/12
to ang...@googlegroups.com, curiou...@gmail.com
I used the angular ui library to handle keystrokes (see the keypress section). 

Will

curiou...@gmail.com

unread,
Aug 14, 2012, 6:52:47 PM8/14/12
to ang...@googlegroups.com, curiou...@gmail.com
Will, thanks for your response. Do you know of a simple example that shows how angular-ui is used to handle keystrokes? Other than adding the ui-keypress directive and the corresponding function, what else do I need to include in my code. Which files I need to call?

Also, is there a solution for this in angularJS. Information about AngularJS suggests that it is supposed to play well with jquery. Given that there must be a relatively simple way to call angularJS function from jquery and vice-versa.

Thanks.

Will Kriski

unread,
Aug 14, 2012, 8:20:27 PM8/14/12
to ang...@googlegroups.com, curiou...@gmail.com
I did a jsfiddle for you that works with enter key http://jsfiddle.net/willkriski/nZC9y/16/

so the enter key triggers the say() function in my controller. That's it!

I just linked to the minified file in my html file -    <script src="lib/angular-ui.min.js"></script> 
also I added it to my module var myModule = angular.module('myApp',['ngResource','ui']); and set the ng-app to "myApp"

The angular-ui creators might be able to improve upon this but it works.

W

Will Kriski

unread,
Aug 14, 2012, 9:13:02 PM8/14/12
to ang...@googlegroups.com
I thought it might be a jsfiddle issue. My app is working fine.

curiou...@gmail.com

unread,
Aug 14, 2012, 9:57:54 PM8/14/12
to ang...@googlegroups.com
Will, thanks a ton for creating the jsFiddle. Really appreciate your help; it works great. 

ProLoser thanks a lot for creating and working on angular-ui. I will look at the code to see how this works. Will hopefully help me learn angularJS. Just as in case of Will, it works fine (i.e., I do not have an issue with event firing twice). 

Thanks again.

Pawel Kozlowski

unread,
Aug 15, 2012, 4:47:40 AM8/15/12
to ang...@googlegroups.com
hi!

On Wed, Aug 15, 2012 at 2:56 AM, Dean Sofer <dean...@gmail.com> wrote:
> Am I the only one noticing 2 alerts instead of one? I think we may need to
> fix the keypress directive sooner than I realized.

So, had a very quick look at what is going on and the problem was
jsFiddle itself, here is the working one:
http://jsfiddle.net/pkozlowski_opensource/taxK9/2/

What was happening was that there were 2 version of AngularJS included
(1.0.0rc2 - in the resource panel) and the latest one (1.0.1 in the
choose framework panel). Both were running side-by-side and both were
processing the app, registering listeners etc.

Funny thing, when I was writing the blog post about using jsFiddle
with AngularJS (http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/)
I though that I'm covering basic stuff :-) But aparently it is
relativelly easy to get wrong with jsFiddle :-)

Anyway, I think that rewrite of ui-kepress is not that super-urgent,
but the implementation should be improved at some point.

Cheers,
Pawel

Will Kriski

unread,
Aug 15, 2012, 7:46:59 AM8/15/12
to ang...@googlegroups.com
Thanks. I started using the built in angular reference and body tag as you suggested in the blog, but somehow the resource was still there maybe I copied another fiddle or something...


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en.



curiou...@gmail.com

unread,
Aug 15, 2012, 9:48:44 AM8/15/12
to ang...@googlegroups.com
I have a follow up question. The solution suggested by Will worked great to get the functionality working. I put the ui-keypress directive in my body tag to have the countervalue increase when right arrow key is pressed:

     <body ng-controller="myctrl" ui-keypress="{39 : 'increasecounter()', 37: 'decreasecounter()'}" >

I put in the body tag  because I wanted this to work everywhere on the page. But now I realized that want this to work everywhere except one of the input boxes. So, I did the following:

    <input type="text" ui-keypress="{39 : 'donotchangecounter()'}">

with the following in the controller:

$scope.donotchangecounter = function() {
$('input').bind('keydown', function(e) {
e.stopPropagation();
});
}

The problem I have is that the first time I press right arrow in the above textbox , the increasecounter() function is still implemented. After that it works as expected; pressing right-arrow in the textbox does not increase countervalue. What do I need to do so that right arrow key does not increase the countervalue even the first time it is pressed when the cursor is in the textbox. 

In case it is helpful, the following is the entire js code for the controller. Thanks again for your help.

var myApp = angular.module('myApp', ['ui'])

// Angular code to increase and decrease counter value.
function myctrl($scope) {
$scope.countervalue = 0;

$scope.increasecounter = function (){
$scope.countervalue = parseInt($scope.countervalue,10) + 1;
};

$scope.decreasecounter = function() {
$scope.countervalue = parseInt($scope.countervalue,10) - 1;
}

$scope.donotchangecounter = function() {
$('input').bind('keydown', function(e) {
e.stopPropagation();
});
}


};

Pawel Kozlowski

unread,
Aug 15, 2012, 11:01:44 AM8/15/12
to ang...@googlegroups.com
Hi!

You don't need to use jQuery to stop even't propagation. The trick is
that you can pass $event to the handler function like this:

<input type="text" size="10" ui-keypress="{ 39 : 'prevent($event)', 37
: 'prevent($event)' }"/>

and then in your controller:

$scope.prevent = function($event) {
$event.stopPropagation();
}

Here is the working jsFiddle: http://jsfiddle.net/pkozlowski_opensource/taxK9/6/

The above will work but it is a bit cumbersome....

Cheers,
Pawel

curiou...@gmail.com

unread,
Aug 15, 2012, 11:30:30 AM8/15/12
to ang...@googlegroups.com, curiou...@gmail.com
This worked great! Thanks so much.

Dean Sofer

unread,
Aug 15, 2012, 2:18:04 PM8/15/12
to ang...@googlegroups.com

Timothy Bone

unread,
Nov 16, 2012, 11:53:25 AM11/16/12
to ang...@googlegroups.com
I was looking for a way to attach a keypress handler to the whole document, not just a text area. Sorry, but how would you do this using Angular? Jquery handled this fine, but I would prefer
to understand the Angular way.

Thank you!
Tim

Olivier Clément

unread,
Mar 22, 2013, 9:28:36 AM3/22/13
to ang...@googlegroups.com
Not in IE -> https://github.com/angular-ui/angular-ui/issues/502
Other browsers are fine

If you explicitly set focus on the body/div on which the directive is used, it will work, but as soon as you set focus elsewhere, it will stop working. It's as if the event won't bubble up properly in IE or something;

For app-wide keypress, I think the only way to have it work in IE would be to bind the listener to  the document object, which can't be done using a directive (isn't it?)

I am going to try that out

On Friday, November 16, 2012 3:17:35 PM UTC-5, ProLoser wrote:
Although it might be a little hackish, does <body ui-keypress="..."> work?


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en.
 
 



--
Dean J Sofer
Dean...@gmail.com

BS Computer Information Systems
California State Polytechnic University, Pomona
Telephone: 714-900-2254
Website: www.DeanSofer.com 

Joshua Petitt

unread,
Aug 13, 2013, 1:12:15 PM8/13/13
to ang...@googlegroups.com
@Olivier, did you get the app-wide keypress solution working?  This is the behavior I want for my single-page app.  I am trying to implement keystroke navigation and control of the app.  I can get the ui-keypress to work in an input, but that requires the user to first select the input.  Also, I cannot get it to work with div elements, or the body element?
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
Message has been deleted
0 new messages