I'm trying to figure out how to pass event parameters from a component back to my class handling the event.
In my case, I'm trying to register a "KeyPressed" event in a component, like so:
<textarea ng-keypress="cmp.KeyPressed(event)" rows="1" cols="100"></textarea>
And the code handling the event looks like this:
void KeyPressed(event) {
print("keypressed!");
}
Whenever a key is pressed, the KeyPressed() function fires. However, the "event" being passed in is null. How do I pass in event parameters correctly, and what is the event type?
You need to use $event
<textarea ng-keypress="cmp.KeyPressed($event)" rows="1" cols="100"></textarea>
Related
I'm writing my own ESC handler because I need to do other actions when ESC is pressed, specifically I need to manage where focus goes for keyboard-only users. I have it working for all menus and some dialogs (both of which are using jQueryUI) but I'm having problems with dialogs that open on top of other dialogs (confirmation dialogs).
I'm using a Backbone View and adding my keydown handler on dialogcreate. this.$el.on('dialogcreate', this.bindKeydownEvent);
My handler:
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog().on('keydown', function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}
I've checked and this.$el.dialog() is the correct dialog when the second dialog calls this.bindKeydownEvent but for some reason the keydown handler is not being triggered no matter what I press in the dialog (Tab, Space, Enter, random letters, etc).
Any idea what I'm doing wrong or have a better way I could bind the keydown event?
EDIT:
I just noticed that this is also happening in some first-level dialogs. It looks like the only difference is the way we get the template and therefore create the interior of the dialog. In our Alert and Confirmation dialog classes, we define the template as an attribute on the object like this: template: _.template("<div><%= o.content %></div>"). In other views (in which the keydown binding works) we build the child elements and add them to the DOM of the dialog, set the template in the initialize function
this.options.template = 'navigation/CreateNewDialog.template';
or set it when we call the dialog
var closeConv = new views.CloseConversationDialogView({
confirm: this.closeConversationConfirmed,
content: i18n.t("closeConversationInput"),
template: "conversation/CloseConversationDialog.template"
});
closeConv.render();
Is there a reason that creating the template inline as an attribute on the view would not bind keydown correctly?
To understand why your event handler isn't being triggered you need first understand how event delegation works.
The key to event delegation in that events bubble up the DOM. So when you bind your event using this.$el.dialog().on('keydown',..., what you basically doing is listening to any keydown event that is triggered on your $el or it's descendants. In this case being that your second dialog isn't a descendant of your $el it's events won't bubble up to it and therefore don't trigger your handler.
To work around this you can either bind directly to your second dialog, or instead bind to a exisitng higher level element like the document. For example
$(document).on('keydown', '.myDialog', function() {...
The only thing my original attempt was missing was "widget". The widget method, according to api.jqueryui.com,
Returns a jQuery object containing the generated wrapper.
I don't see any documentation on what exactly $('.selector').dialog() returns but apparently it is not the same as $('.selector').dialog("widget"). I also changed on('keydown'... to just use the jQuery keydown instead.
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog("widget").keydown(function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}
I have multiple HTML fragments that are inserted into my DOM as the result of AJAX call-backs.
Each of these fragments will contain a text box whose class is "quantity".
What I want to do is to create an "on change" event handler that fires whenever one of these textbox's text value is changed. However, when that event is fired/handled, I need to know WHICH specific textbox was updated.
Okay, using jQuery, I have the following that fires in my "Lists.initHandlers" method:
$(document).on('change', $('#divABC').find(".quantity"), List.quantityChanged);
And my "List.quantityChanged" event handler happily fires when I update the quanity.
The problem is that when I reference "this" within the event handler, I get the whole document, and not the element that triggered the event.
I have tried to capture the element using syntax similar to:
$(document).on('change', $('#divABC').find(".quantity"), {ctrl: this}, List.quantityChanged);
but when I attempt this, the handler is never fired (even when I change the signature to expect an argument).
Any guidance here would be most appreciated.
Thanks
Griff
Try this:
$('.quantity').live('change', function(){
alert('New value: ' + $(this).val());
});
Pass this to your function:
$(document).on('change', $('#divABC').find(".quantity"), function () {
List.quantityChanged(this);
});
First of all, Thanks a lot all of you for your continuous support.
I have a problem releated .xhtml and 'f:ajax'.
I am setting richfaces:collapsiblepanel 'expanded' attribute by bean variable which is default collapsed and on blur event it gets expanded. I want to set focus a UIComponent after f:ajax request compeleted. And for that I have written a function in javascript and called it in 'onevent' of f:ajax.
But onevent function fires before panel open and I can not able to set focus on UIComponent which are define in that collapsible panel.
How can I setFocus or How can I fire that function after ajax request compeleted ?
Thanks in advance.
Your js function should look like this
function doTheFocus(data) {
if (data.status === 'success') {
//here goes the js code that will set the focus
//this code will be executed only when the ajax will be done
}
}
And here is how your f:ajax will look like
<f:ajax onevent="doTheFocus" />
If you want to call the js function of the focus when the panel is opened you can try
<rich:collapsiblePanel onswitch="doTheFocus"
or (I'm not sure...)
<rich:collapsiblePanel onswitch="doTheFocus()"
If you eventually will use the onswitch , you might be needed to add some logic inside doTheFocus function to check if the panel is expanded or not...
How do you invoke a bean method from Javascript in PrimeFaces?
I have the following menuItem:
<p:menuitem id="toggleAlarms" icon="ui-icon-cancel" rendered="#{navigationBean.admin}" value="Cancel Alert" update=":alarmMessages" action="#{alarmsBean.toggleAlertOff()}"/>
When I click on that item in the UI the method gets called.
But when I have this element:
<p:messages id="alarmMessages">
<script>
jQuery('#alarmMessages').effect("pulsate", {times:5}, 1000 );
jQuery('#alarmMessages').show();
$('#alarmMessages').click(function() {
jQuery('#toggleAlarms').click();
alert('fool');
})
</script>
</p:messages>
If I click on the messages object on the UI, I can see the alert message with fool in it.
However, I never see the toggleAlarms.click() method invoke the alarmsBean.toggleAlertOff() call.
Am I doing something wrong?
any chance that #{navigationBean.admin} returns false ?
cause if so you wont be able to find it in the DOM... (maybe better use style=display:none)
also , your selector might be wrong if the menuitem is inside form try jQuery('#someFormID\\:toggleAlarms').click(); do view source on your web page to see the right id of the menuitem
finally try the same with commandButton instead (not sure that menuitem will respond as expected to .click())
Update
in order to check if your jquery selector is right use alert($('#toggleAlarms').length) instead of alert('fool');
I'm trying to migrate from using inline event triggers to using event listeners using Prototype's Event.observe function. There are a few inline commands that I don't know how to handle using the function call.
I want to move from:
<form id='formFoo' action='whatever.php' onsubmit="return Foo.verify(this);">
To an event call:
Event.observe('formFoo', 'submit', Foo.verify);
This of course will not work, as I need a return value from the function I call to determine whether the form gets submitted or not.
How do I do this using event handlers?
The easiest way to do this is probably Event.Stop from prototype. This works for me (put this in any script block):
Foo = { verify: function(){ return false } };
Event.observe(window, 'load', function() {
Event.observe('formFoo', 'submit', function(e){
if(! Foo.verify($('formFoo'))){
e.stop();
}
});
});
It stops every form submission; you will just have to change Foo.verify to do what you wanted.
Explanation: When the submit event is triggered, prototype passes the handler a prototype Event object representing the event, and the stop method on that object prevents the submit. The rest is just setting up the event.
Minor note: Among other things, passing Foo.verify directly as a handler will cause verify to be called as a function, not a method (this will be the global object within the call, rather than Foo). That situation might be okay - if verify doesn't use this, you're fine. Be aware of the difference, though.