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...
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 am working on JSF application in primefaces in that i am showing an information to the user via <p:messages> .
So when the user click submit the page will processed and the p:messages dialog will triggered to show the information to the user ,
I referred Primefaces p:messages showcase Page
It is working fine..But after it displayed the messages , it is not closing automatically either we need to close that dialog manually or it remains in open stage.
I need it should it close automatically after it displayed the message to user...
How can i do that ...Can anybody give suggestion that how can i do ?
<p:messages id="msgs"> is ultimately rendered as <div id="msgs"> and its contents is then updated with the factual messages to the user.
If you want to clear the message screen after some delay you should use the JavaScript setTimeout function after ajax call has been completed:
<p:commandButton ...
oncomplete="setTimeout(function() { $('#msgs").html(''); }, 3000);" />
The second parameter of setTimeout function is the delay in milliseconds.
The other alternative is to use <p:growl> instead.
Worked for me for <p:fileUpload>, which was in <p:dataList> and <h:panelGrid> elements.
<p:fileUpload...
oncomplete="setTimeout(function() { $('[id$=mr-upload-messages]').hide(1000); }, 2000);">
...
<p:messages id="mr-upload-messages" showDetail="true" showSummary="false" closable="true"/>
I have used jQuery $('[id$=mr-upload-messages]' to find id's which ends with mr-upload-messages, because Primefaces adds it's unique identifier at the beginning of id.
$('#msgs').html(''); immediately hide in 3 seconds but if you want to hide slowly as jquery hide method do this..
<p:commandButton ...
oncomplete="setTimeout(function() { $('#msgs').hide(1000); }, 3000);" />
hide(1000); hiding motion will be completed in 1 second
I came across the attention, and did it this way:
function hideMsg(){
$("#msg").delay(1000).hide(1000);
}
oncomplete="hideMsg()"
I want to script a click on an input box.
Here is an example where the focus() should do just that, but it doesn't! Why?
Code.gs:
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('myFile');
}
myFile.html:
<input type="text" id="new" onchange="adding(this)"/>
<div id="data"></div>
<script>
document.getElementById('new').focus();
function adding(a){
document.getElementById('data').innerHTML += a.value;
a.value = '';
}
</script>
I have also tried without success putting the focus() in its own function and having a body element whose onload calls that function.
What DOES work is having a button whose onclick calls that function, so focus() does eventually become active. Is there some other event I can use to trigger it?
I am using a Chromebook. Could that be the problem?
This is an intentional security decision in Caja. Certain functions that are prone (across the web) to serious malicious misuse, such as submit() and focus(), can only be executed while in the context of a user-initiated event (such as a button click).
I have a custom component location. I want that, when a change is done, the model is update so another component (an autocomplete) is to show only results related to the location value. Also, that component is rerendered to reset it.
I have a page with the following code (simplified):
<h:form id="ticketForm">
...
<loc:location id="locationId" <-- CUSTOM COMPONENT
hiddenFieldValue="#{ticketCtrl.ticket.location}"
visibleFieldValue="#{ticketCtrl.ticket.locationDescription}"
rendered="#{ticketCtrl.ticketModifiable}">
<f:ajax event="changeLocation" render=":ticketForm:gfhId" <-- AJAX CALL.
execute=":ticketForm:locationId" listener="#{ticketCtrl.locationListener}"/>
</loc:location>
...
</h:form>
When the value in the component is changed, the model is updated and :ticketForm:gfhId is rendered as needed, but the listener(which performs additional resets) is not executed.
Attaching the ajax to a simpler control results in the listener being executed; v.g.
<h:inputText id="contactId"
value="#{ticketCtrl.ticket.contactPerson}"
disabled="#{not ticketCtrl.ticketModifiable}">
<f:ajax event="change" render=":ticketForm:gfhId"
execute=":ticketForm:locationId" listener="#{ticketCtrl.locationListener}"/>
</h:inputText>
works perfectly.
I do not know if it may be related as how the changeLocation event is fired; inside my component I define it as
<composite:interface>
...
<composite:clientBehavior name="changeLocation" event="change" targets="visibleId"/>
</composite:interface>
with visibleId being a readonly text; when it is changed by javascript I fire the change event on it with JS.
function launchEvent(fieldName) {
if ("fireEvent" in fieldName) {
fieldName.fireEvent("onchange");
} else {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
fieldName.dispatchEvent(evt);
}
}
The info I find in other questions is about making ajax an inner part of the composite component, here I want ajax detached because I probably won't need it in other uses of the component.
I am using JBoss 6.1 wih Mojarra 2.1.9 and Richfaces 4.
Thanks in advance.
UPDATE:
Even after finding jarek.jpa's answer right, if someone wants to check the code it is here:
The composite component
http://pastebin.com/9wqMVfR5
The main form
http://pastebin.com/i39ys2D9
This may have to do with the "readonly" attribute set to true. Though you manage to send the change-event by hand (JS), the server-side processing of the listener may be dropped due to the readonly state. See e.g. jsf (richfaces) readonly input text validation.
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');