Update multiple components ajax [duplicate] - ajax

This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
I want to update two components after ajax action but don't know how to do this (if it is even possible).
I have three pages:
<h:form id="loginForm">
<p:panelGrid columns="2" >
<h:outputText value="Login: "/>
<p:inputText value="#{bean.person.username}" requiredMessage="*" />
<h:outputText value="Hasło: "/>
<p:password value="#{bean.person.password}" requiredMessage="*"/>
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage"/>
</p:panelGrid>
</h:form>
Menu page is similar to this above with menu items with rendered atribute (fe. show logout button when user is logged in) and loginConfirmationPage on which i want to show username.
I need to update both of these pm:pages to get logout button on menu page and also display username on confirmation page.
How can I do this? For now i can only update one page. I tried to type statement similar to these:
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage,menuPage"/>
or
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage;menuPage"/>
Both not working. How can i do this?

var name = "";
$.post("Path/To/Server/File", {'serverFileVariableName' : clientElementID},
//data is what the server file will return
function(data){
//In this case, the data is the username.
name = data;
//invoke the show method to display
logOut.show();
}
);
//done

Related

<p:spinner> max value won't change anymore into other value after getting error validation form [duplicate]

This question already has answers here:
How can I populate a text field using PrimeFaces AJAX after validation errors occur?
(3 answers)
How to reset input fields in a form after validation fail when updating it with new values
(2 answers)
Closed 3 years ago.
So, it worked fine, until it get error required validation in form. myMaxDuration won't change anymore in xhtml, but when I sysout it in console it changed.
If, the myMaxDuration I send into bean is 30, Ajax worked fine.
But, if myMaxDuration when I send into bean is 10, ajax won't work.
already tried using ajax update in bean
<p:panelGrid columns="1" columnClasses="ui-grid-col-6" layout="grid" styleClass="ui-panelgrid-blank">
<p:outputLabel value="Name"/>
<p:inputText value="#{myBean.nEmp.name}" required="true"/>
<p:outputLabel value="Status" styleClass="labelSmall"/>
<p:selectOneMenu required="true" value="#{myBean.nEmp.employmentStatusID}"
<f:selectItem itemValue="10" itemLabel="10"/>
<f:selectItem itemValue="20" itemLabel="20"/>
<f:selectItem itemValue="30" itemLabel="30"/>
<p:ajax listener="#{myBean.maxDuration()}" update=":form:durasiID"></p:ajax>
</p:selectOneMenu>
</p:panelGrid>
<p:outputPanel>
<p:panelGrid columns="1" columnClasses="ui-grid-col-3" layout="grid" styleClass="ui-panelgrid-blank" rendered="#{myBean.nEmp.employmentStatusID != 6}">
<p:outputLabel value="Durasi" styleClass="labelSmall"/>
<p:spinner min="1" max="#{myBean.myMaxDuration}" id="durasiID" value="{myBean.nEmp.monthDuration}"/>
</p:panelGrid>
</p:outputPanel>
<p:commandButton value="save" action="#{myBean.saveNewDecreeEmployee()}" />
on my bean
public void maxDuration() {
if(nEmp.getEmploymentStatusID() == 10) {
myMaxDuration = 10;
}
else if(nEmp.getEmploymentStatusID() == 20) {
myMaxDuration = 20;
}
else {
myMaxDuration = 30;
}
nEmp.setMonthDuration(myMaxDuration);
System.out.println(myMaxDuration + " - maxDuration");
}
the value of in xhtml should be changed like in console, after someone get error form validation field name required.
So, I solved this problem by reference of #Kukeltje
Based on this, How can I populate a text field using PrimeFaces AJAX after validation errors occur?
I just add resetValues="true" into my <p:ajax>
and it's worked fine.

How to Trigger Ajax To Load Nested Dropdowns After Loading A Form?

I have a button to display an edit dialog form with a selectOneMenu that holds prefix number values in it and, after selecting one of those prefix values, three selectCheckboxMenu are loaded with employees data. This is workinkg fine.
<p:outputLabel value="prefix" for="prefixo" />
<h:panelGroup>
<p:selectOneMenu id="prefixo" value="#{demandasController.selected.prefixo}" converter="prefixosConverter" filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="#{adeBundle.SelectOneMessage}" itemValue="#{null}" />
<f:selectItems value="#{prefixosController.items}"
var="prefixoItem"
itemValue="#{prefixoItem}"
itemLabel="#{prefixoItem.prefixo} - #{prefixoItem.nomePrefixo}"
/>
<p:ajax event="valueChange" update="uorPosCollection uorPosCollection1 uorPosCollection2" listener="#{demandasController.changePrefixo}"/>
</p:selectOneMenu>
</h:panelGroup>
<p:outputLabel value="Executivo(s)" for="uorPosCollection" />
<p:selectCheckboxMenu id="uorPosCollection" value="#{demandasController.selected.uorPosCollection}" label="Executivo(s)" multiple="true" converter="uorPosConverter" filter="true" filterMatchMode="contains" >
<f:selectItems value="#{demandasController.availableExecutivos}"
var="uorPosCollectionItem"
itemValue="#{uorPosCollectionItem}"
itemLabel="#{uorPosCollectionItem.matricula} - #{uorPosCollectionItem.nome} (#{uorPosCollectionItem.prefixo.prefixo})" />
</p:selectCheckboxMenu>
<!-- analogous code ommited -->
The Listener:
public void changePrefixo(AjaxBehaviorEvent event) {
availableExecutivos = LoadExecutivosListCombo(super.getSelected().getPrefixo());
//analogous methods ommited
}
The methods to load the employees lists:
private List<UorPos> LoadExecutivosListCombo(Prefixos prefixos) {
List<SelectItem> listExecutivosCombo = new ArrayList<>();
List<UorPos> listExecutivos = uorPosFacade.findUorPosExecutivosByPrefixo(prefixos);
for (int i = 0; i < listExecutivos.size(); i++) {
listExecutivosCombo.add(new SelectItem(listExecutivos.get(i)));
}
return listExecutivos;
}
//analagous methods ommited
Native queries to retrieve database:
public List<UorPos> findUorPosExecutivosByPrefixo(Prefixos prefixo) {
return (List<UorPos>) getEntityManager().createNativeQuery("SELECT * FROM UorPos WHERE prefixo=9951", UorPos.class).setParameter(1, prefixo.getPrefixo()).getResultList();
}
//analagous methods ommited
But when editing a register that already has prefix and employee values (saved earlier by some user), the 3 selectCheckboxMenu are loaded showing (undesired) id's entity class name on its labels value and empty dropdowns:
e.g.: in the figure above, when the edit form was loaded, it shows the values saved earlier by some user: the prefix 9882 (displayed as expected) and the three (empty) dropdowns for employees (displayed with the undesired class names in it). If I select a different value than 9882, the dropdowns are (ajax) filled as expected and if I select 9882 again, the employees are displayed as expected (without the class names):
I'm trying to resolve it by activating the ajax as below, but don't know how to call it in the function:
<p:dialog onShow="CallAjaxFunction()" modal="true" >
<script>
function CallAjaxFunction() {
<!-- how to call the ajax here ? -->
alert("displaying after form was loaded.")
}
</script>
...
</p:dialog>
Does anyone knows how to trigger ajax to load nested dropdowns after loading a form?
Or if someone has any other solution to display the values in the labels (without the class name) and automattically load the nested dropdowns, I appreciate that.
Thanks in advance.
After researching, I've used the listener to update the combos, using for this the open ajax event in the dialog:
<p:dialog onShow="PF('prefixowv').selectValue(':selected').click();" update= DemandasEditForm:uorPosCollection DemandasEditForm:uorPosCollection1 DemandasEditForm:uorPosCollection2 />
And changed the ajax event to selectItem, instead of valueChange:
<p:selectOneMenu id="prefixo" value="#{demandasController.selected.prefixo}" converter="prefixosConverter" filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="#{adeBundle.SelectOneMessage}" itemValue="#{null}" />
<f:selectItems value="#{prefixosController.items}"
var="prefixoItem"
itemValue="#{prefixoItem}"
itemLabel="#{prefixoItem.prefixo} - #{prefixoItem.nomePrefixo}"
/>
<p:ajax event="selectItem" update="uorPosCollection uorPosCollection1 uorPosCollection2" listener="#{demandasController.changePrefixo}"/>
</p:selectOneMenu>
Regards,

How Can I Use Ajax To Update A GraphicImage Without Blinking?

Please have a look at the following form. In particular, take note of the ajax and graphicImage elements. The ajax element is embedded in a selectOneMenu. When the menu selection is changed the image is correspondingly updated. The update will sometimes cause a "blink" (old image disappears, form resizes (shrinks), new image appears, form is back to original size). I am guessing that the not blink (blink) results from the speed (or lack thereof) with which the new image is fetched from the url (a server elsewhere on the web). Short of caching all the images locally, is there a way to address this? Cause old image to remain in place until the new image is ready? At least prevent the form from resizing?
<h:form rendered="#{orderController.addingNew}" styleClass="demo">
<fieldset>
<legend>New Order</legend>
<h:panelGrid columns="2">
<h:outputText value="Patient"></h:outputText>
<h:selectOneMenu validatorMessage="required" value="#{orderController.patientId}" onchange="submit()">
<f:selectItems value="#{orderController.patients}" />
</h:selectOneMenu>
<h:outputText value="Product"></h:outputText>
<h:selectOneMenu value="#{orderController.productId}">
<f:selectItems value="#{orderController.products}" var="product" itemValue="#{product.id}" itemLabel="#{product.name}" />
<f:ajax render="productImage" listener="#{orderController.productSelectionChanged}"/>
</h:selectOneMenu>
<h:graphicImage url="#{orderController.productImageUrl}" id="productImage"/>
</h:panelGrid>
<h:panelGroup>
<h:commandButton value="Save" action="#{orderController.save}" accesskey="s" styleClass="demo"/>
<h:commandButton value="Cancel" action="#{orderController.cancel}" accesskey="c" immediate="true" styleClass="demo"/>
</h:panelGroup>
</fieldset>
<h:outputText value=" " />
</h:form>
You could bind an onevent attribute to your ajax tag:
<f:ajax render="productImage" listener="#{orderController.productSelectionChanged}"
onevent="ajaxEventListener"/>
Then, you get notified whenever some phase of the ajax process happens. You might be interested in implementing something like this with jQuery:
function ajaxEventListener(data) {
var status = data.status; // Can be "begin", "complete" or "success".
var source = data.source; // The parent HTML DOM element.
//Give your form an id in order to access the image in JS
var $image = $(document.getElementById("yourFormId:productImage")); //Grab your image
switch (status) {
case "begin": // Before the ajax request is sent.
// Fade out your image
$image.fadeOut( "slow" );
break;
case "success": // After update of HTML DOM based on ajax response.
// You've got the url properly updated, start fading in the image again
$image.fadeIn( "slow" );
break;
}
}
In order to improve loading times, you should read some papers about how to cache resources in the web browser. That's not JSF specific, though, it's something you could do with a web filter.
See also:
Execute JavaScript before and after the f:ajax listener is invoked
How to select JSF components using jQuery?
http://api.jquery.com/fadeout/
http://api.jquery.com/fadeIn/

f:ajax reload content only after page reloaded

So, i have code:
<h:form id="newMessages" rendered="#{not empty welcome.letters and urlBean.welcome}" styleClass="infoNotes">
**some not important code here**
<ui:repeat id="data" value="#{welcome.letters}" var="letter" varStatus="status">
<h:panelGroup rendered="#{status.index lt 3}">
<div>
<h:commandLink styleClass="noticeClose" rendered="#{letter.content.IMPORTANCE ne '2'}">
<f:ajax listener="#{welcome.onMessageNoticeClose(letter)}" event="click" render="#{cc.clientId}:newMessages newLettersCount"/>
</h:commandLink>
</div>
</h:panelGroup>
**some not important code here**
</ui:repeat>
**some not important code here**
</h:form>
method used when we "click" on close button
public void onMessageNoticeClose(Document letter) {
try (RequestContext ctx = RequestContextFactory.create()) {
DocumentEngine.getInstance().markAsRead(letter, true, ctx);
}
Utils.getRolesBean().recalcMessageCount();
loadMessages();
}
and couple of methods that recalc message count and load new messages. So if we have new unread messages we show them on main page (3 of them). So, problem is when we click close button 'styleClass="noticeClose"', we mark letter as read and didnt show it on main page. But with that code have bug, if in list we have only one message and button close clicked, this letter mark as "read" and message count recalc correct, but it still showed on main page, and don`t rendered only after page will be reloaded. So, solution is if we h:form surround with h:panelgroup like:
<h:panelGroup id="newMessages">
<h:form rendered="#{not empty welcome.letters and urlBean.welcome}" styleClass="infoNotes">
but i don`t understand how it work... Can anyone help me understand this or just explain. Thank you.

How to customize the presentation of faces messages

I would like to customize the presentation of faces messages.
For this,
<h:inputText id="name" required="true" />
when validation is failed, then it will be shown in a
<h:message for="name" />
However, I would like to customize the presentation call JS as follows:
<div class="notification"></div>
function showNotification(msg){
$(".notification").html(msg);
$(".notification").fadeIn(1000, function(){
timeout = setTimeout(function(){
$(".notification").fadeOut(1000);
}, 5000);
});
}
How can I achieve this?
You can use FacesContext#getMessageList() to get the messages in the view, if necessary the ones for a specific client ID. You can iterate over them in a ui:repeat. Each item is a FacesMessage which has several getters. You can display any HTML in the message unescaped by using <h:outputText escape="false">.
So, in a nutshell:
<ui:repeat value="#{facesContext.messageList('form:name')}" var="message">
<div><h:outputText value="#{message.summary}" escape="false" /></div>
</ui:repeat>
(in the above example, I assume that your form has id="form")
Or, if that HTML help link is actually not part of the message, then so:
<ui:repeat value="#{facesContext.messageList('form:name')}" var="message">
<div>#{message.summary} help</div>
</ui:repeat>

Resources