JSF AJAX Request not working with hx:panelDialog - ajax

I wrote the following code,
<h:form id="PrefForm" >
<hx:commandExButton id="preferenceButton" type="button" style="align:right;" value="#{nls.preferenceLink }" title="#{nls.preferenceLinkTitle}" >
<hx:behavior event="onclick" behaviorAction="get" targetAction="prefPanelGroup"></hx:behavior>
<hx:behavior event="onclick" behaviorAction="show;stop" targetAction="preferenceSet"></hx:behavior>
</hx:commandExButton>
<hx:panelDialog id="preferenceSet" type="modal" styleClass="panelDialog" title="#{nls.preferenceDialogTitle}" >
<h:outputText styleClass="panelStartMessage" style="display:block;" value="#{nls.preferenceDialogWindowText}" />
<h:panelGroup id="prefPanelGroup" rendered="#{neoReport.hasSelectItem }" style="display:block;width:300px;height:360px;overflow:auto;" >
<hx:ajaxRefreshRequest id="refreshform" />
<h:selectManyCheckbox value="#{neoReport.selectedItems}" layout="pageDirection">
<f:selectItems value="#{neoReport.selectItems}" />
</h:selectManyCheckbox>
</h:panelGroup>
<hx:panelBox id="noCommandWindow" rendered="#{!neoReport.hasSelectItem }" style="display:block;width:300px;height:50px;" layout="lineDirection">
<h:outputText styleClass="outputText" id="cmdInfo" value="#{nls.noCommands}" />
</hx:panelBox>
<h:panelGroup id="buttonBox1" styleClass="panelStartBox" >
<hx:commandExButton id="submitPref" styleClass="commandExButton" type="submit" value="#{nls.submit}" action="#{neoReport.action}">
<hx:behavior event="onclick" behaviorAction="hide" targetAction="preferenceSet" id="behaviorSubmitPref" />
</hx:commandExButton>
<hx:commandExButton id="CancelPref" styleClass="commandExButton" type="submit" value="#{nls.cancel}" action="neoReport">
<hx:behavior event="onclick" behaviorAction="hide" targetAction="preferenceSet" id="behaviorCancelPref" />
</hx:commandExButton>
</h:panelGroup>
</hx:panelDialog>
</h:form>
Basic idea behind this code is to have a button on the page,when user click,it should get the latest data from bean( by extracting a file,which is continuously getting updated) and fill the List object in databean,so that h:selectManyCheckBox can render that. So i added a behavior with the commandExButton,so that it will get the new data and it should render the latest options in selectManyCheckBox. BUT out of these two hx:behavior,only the first one is working,its calling the getter function of
<f:selectItems value="#{neoReport.selectItems}"
but its not rendering the panelDialog further.If i remove the behavior for "get" it will show the panel dialog but not with the updated data. So i am not able to find out,what exactly wrong i am doing here.Can anyone help?

First of all I don't know what type of tag library is this. You should point it out in the tags and/or in the question.
You should have only one <hx:behavior> tag, which does all the job for you. If doing so, you should have a method that calls all three methods. Is it possible with these tags to rerender multiple components with AJAX - like targetAction="prefPanelGroup, preferenceSet"?
As far as I know, rerendering preferenceSet will cause prefPanelGroup to rerender too, so it's pointless to rerender separately.
Also, rerendering prefPanelGroup will work only by telling the <hx:behavior> tag a more precise id, like "PrefForm:prefPanelGroup".
Hope this helps,
Daniel

Related

Primefaces - ui:repeat component does not update

I have a problem to ajax update an ui:repeat. The update is triggered from a commandButton outside the ui:repeat (see the code below). The variable priceHour is required to calculate the other prices (week, Monat..)
<h:form id="myForm">
<ui:repeat id="alvs" var="alv" value="#{myBean.allV}" >
<h:panelGroup rendered="#{alv.status == 'ON'}" >
<div class="pricing">
<h:outputText styleClass="bold" value="#{alv.shortName}: "/>
<p:inputText value="#{alv.priceHour}" id="hour" required="true" >
<f:convertNumber pattern="#.##" type="currency" />
</p:inputText>
<p:inputText value="#{alv.priceDay}" id="day" >
<f:convertNumber pattern="#.##" type="currency" />
</p:inputText>
<p:inputText value="#{alv.priceWeek}" id="week" >
<f:convertNumber pattern="#.##" type="currency" />
</p:inputText>
<p:inputText value="#{alv.priceMonth}" id="month" >
<f:convertNumber pattern="#.##" type="currency" />
</p:inputText>
</div>
</h:panelGroup>
<p:messages />
</ui:repeat>
<p:commandButton value="Calculator" actionListener="#{myBean.priceCalc}" process="#this,alvs:hour" update="alvs" />
</h:form >
When I click the button nothing happens and the ui:repeat and the prices are not updated. What is wrong? I tried also update"myForm:alvs", update":myForm:alvs": nothing!
I'm using primefaces 3.5
Thanks in advance
ui:repeat is not a rendered component, so you won't see anything in HTML about it. You can't update something that is not rendered. Also the ui:repeat doesn't even have an id attribute.
You need to wrap your ui:repeat inside a component such as h:panelGroup for example like this :
<h:panelGroup id="alvs">
<ui:repeat ...>
</ui:repeat>
</h:panelGroup>
And update the panelgroup in your button :
<p:commandButton value="Calculator" actionListener="#{myBean.priceCalc}" process="#this,alvs" update="alvs" />
Notice that I've removed the :hour since you can't spectify it, each IDs will be different for each repeat.
More info :
JSF 2.0 ui:repeat
I had the same problem. The proposed answers didn't work for me: the ui:repeat doesn't want to be updated by ajax, whatever I do. I used PrimeFaces data list instead and it worked like a charm.
http://www.primefaces.org/showcase/ui/data/dataList.xhtml
I'm afraid I don't know the reason for it to not work, I hate when that kind of stuff happens to me working with JSF. As I workaround, you can try surrounding the ui:repeat with a p:outputPanel and then update that panel.

Refresh a form skipping validation when press a button for close: jsf+richfaces

I am using JSF and richfaces. And I am new.
I am looking for information about reset a form in a popup after close it, I do not need to validate the form neither render it. I want to close it and then when I open it again I want the form to be clean.
I have looked information about this, however I do not find the answer to my case. What I have is :
<rich:popupPanel ....
<a4j:outputPanel id="editPaneRegion">
<h:form id="form2EditPane">
<h:panelGrid columns="2" id="edit" ...>
<rich:validator>
<h:outputLabel for="nameContact" value="... " />
<h:panelGrid>
<h:inputText id="nameVontact" value="xbean.selected.name" label="..." required="true" size="20" tabindex="1">
<f:validator validatorId="personNameValidator" />
</h:inputText>
<rich:message for="nameContact" ajaxRendered="true"/>
</h:panelGrid>
</rich:validator>
</h:panelGrid>
....
<a4j:commandButton id="update" value="..." action="#{xBean.edit}" render="form1EditPane:tableContacts, form1EditPane:contactSelect" execute="editPaneRegion" tabindex="6"/>
...
<a4j:commandButton id="close" value="..." oncomplete="#{rich:component('editPane')}.hide();return false;" execute="#this" ajaxSingle="true" immediate="true" tabindex="7"/>
The close button does not works as should be. If I oppen the popup, edit the inputtext and then I close the popup, when I oppen the popup again, it is edited the inputtext, however I want the original as it should be without the edition.
I have found the same question but anything solves my case : I have tried, using a4j:region, different combination of attributes for the button: inmediate= true, action={...clean}, ajaxSimple=true, .. however it doesn't work.
Have someone a solution for this case, I think I miss something obvious as this behaviour should be a common thing, though.
You just need to rerender the form. Whatever you use to make the popup appear make it render the popup as well:
<a4j:commandLink …
render="popupPanel" oncomplete="#{rich:component('popupPanel')}.show();" />
And do not nest forms, you don't have to wrap inputboxes into a <form> like you do in HTML.

Richfaces <a4j:ajax> and <rich:popupPanel> "conflict"

I've stumbled upon a strage behavior of richfaces. Some background about my view structure:
It's mainly a <rich:extendedDataTable> where a click on a row displays info about it on a <a4j:outputPanel>
Also, each row has a context menu with items like "Create", "Edit", etc... that pops a <rich:popupPanel>
The component structure is this:
<h:panelGrid columns="2">
<h:column>
<rich:dataScroller for="testTable" maxPages="7"/>
<rich:extendedDataTable id="testTable" value="#{testController.items}" rendered="#{testController.items.rowCount != 0}"
selection="#{testController.selectedRow}" noDataLabel="No results to show" var="test" rows="20"
style="width: 790px" selectionMode="single">
<a4j:ajax execute="#form"
event="selectionchange"
listener="#{testController.selectionListener}"
render=":res"/>
{columns to display}
</rich:extendedDataTable>
</h:column>
<a4j:outputPanel id="res">
<rich:panel header="Selected Rows:" rendered="#{not empty testController.selectedRows}">
<rich:list type="unordered" value="#{testController.selectedRows}" var="t">
<h:outputText value="#{t.name}"/>
<br/>
<h:outputText value="#{t.details}" converter="#{testConverter}"/>
</rich:list>
</rich:panel>
</a4j:outputPanel>
</h:panelGrid>
<rich:contextMenu target="testTable" mode="ajax" id="contextMenu">
<rich:menuItem label="Edit" render="popupEdit" oncomplete="#{rich:component('popupEdit')}.show();" mode="ajax"/>
</rich:contextMenu>
<rich:popupPanel id="popupEdit" modal="true" autosized="true" resizeable="false" moveable="false" domElementAttachment="form">
<rich:hotKey key="esc" onkeyup="#{rich:component('popupEdit')}.hide(); return false;"/>
<f:facet name="header">
<h:outputText value="Edit Test"/>
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('popupEditar')}.hide(); return false;">
<h:graphicImage value="/resources/css/images/fechar_janela.png" width="20" height="20"/>
</h:outputLink>
</f:facet>
<h:panelGrid id="popupEditContent" columns="2">
... {display of info}
<a4j:commandButton value="Salvar" actionListener="#{testeController.update()}" render="tabelaTestes, contextMenu"/>
<h:panelGroup id="messagePanel" layout="block">
<rich:messages ajaxRendered="true" />
</h:panelGroup>
</h:panelGrid>
</rich:popupPanel>
And now the strange behaviour (using NetBeans):
Deploy the app from NetBeans;
Open the URL of the deployed project on browser (Firefox) . The <a4j:ajax> inlined in the table doesn't work, I know this because the 'testController.selectionListener' is not called and the details are not displayed (it sets the attribute current in the backing bean). The contextMenu works but the popupPanel shows null or empty properties in all fields (the current attribute is not set);
Go back to the IDE, remove all the <rich:popupPanel> section and save the file;
Back in the browser, hit F5 and click a row. Now the <a4j:ajax> works and calls testController.selectionListener, showing the details in <a4j:outputPanel>. The context menu works but (obviously) the panel does not pop;
In the IDE, put back the <rich:popupPanel> section and save the file;
Now refresh the page again, and everything works, details are shown and the Edit pop up shows the right info of the selected row.
I have tried deploying it without the <rich:popupPanel> section and the selecionListener gets called. I think that the problem is deploying the page with both <a4j:ajax> and <rich:popupPanel> sections, hence the "conflict".
I took the structure from the richfaces showcase and made changes. I noticed that in the showcase, the <rich:popupPanel> is placed outside the <h:form> tag, wich in my project is placed in the template.xhtml (so a topmenu page works). Is it possible that the error is caused by this placement?
Could this be considered a bug to file in the richfaces project or am I missing something there?
Is there a workaround or solution?
Thank you very much!
I think I have solved it. I set the id attribute to "form" in the <h:form> tag, in template.xhtml, so now it looks like this:
<h:body>
<h:form id="form">
<div id="top" class="top">
<ui:insert name="top">Top</ui:insert>
</div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
</h:form>
</h:body>
It was the only change I made and now all the components work at first post-deploy.
Edit: Found the solution when searching for another problem: JSF action call on secon click

How to use <f:ajax> in a plain <form> instead of <h:form>?

I have a search form which uses standard HTML <form> tag and sends a GET request like so search.jsf?country=x&city=y. They are set as view parameters in a view scoped bean.
The search form contains two cascading dropdowns, one for countries and one for cities. How can I update the cities dropdown by <f:ajax> without changing <form> to <h:form> and thus breaking the GET functionality? Do I have to use "plain vanilla" ajax by XMLHttpRequest? How could I use it on a JSF backing bean?
I'd just keep using <h:form> and ask some assistance to JavaScript to turn it into a GET form whenever it's been submitted by the submit button.
Something like:
<h:form prependId="false" onsubmit="doGet(this)">
<h:selectOneMenu id="country" value="#{bean.country}">
<f:selectItems value="#{bean.countries}" />
<f:ajax listener="#{bean.loadCities}" render="city" />
</h:selectOneMenu>
<h:selectOneMenu id="city">
<f:selectItems value="#{bean.cities}" />
</h:selectOneMenu>
<input type="submit" value="Search" />
</h:form>
with this JS to turn it into a GET form and removing the two <h:form> specific hidden fields:
function doGet(form) {
form.method = "get";
form.removeChild(document.getElementsByName(form.name)[1]);
form.removeChild(document.getElementById("javax.faces.ViewState"));
}

How to skip validation on certain fields in JSF 2 when required

I have two p:dialog. Each one contains some input fields which are marked as required. Only one dialog is shown at a time but when I submit on any of the dialog, JSF also validates the input fields of the dialog which is not shown. What is the best approach to skip the validations in JSF 2 for the dialog which is not shown. One approach could be that I set the required="condation". But dont know what that condition could be and is it goin to work.
Each dialog is initially hidden. Each one has its own button to show. When one is active and I click the save button there is a validation error even when the required field has values. The validation error comes from the inactive dialog panel. May be it give some idea what i am trying to do.
UPDATE
<p:dialog header="Edit Group" widgetVar="dialog_groupEdit" resizable="false"
width="300" showEffect="bounce" hideEffect="explode" modal="true" position="center">
<h:panelGrid id="panel_groupEdit" columns="2">
<h:outputText value="Group Name: "/>
<h:inputText id="input_gnameEdit" size="26" value="#{groupBean.selectionGroup.gname}" required="true" requiredMessage="Edit Group: Name is required."/>
<h:outputText value="Description:"/>
<h:inputTextarea rows="6" cols="23" value="#{groupBean.selectionGroup.description}"/>
<div></div>
<p:commandButton value="Save" action="#{groupBean.saveGroupChanges}" oncomplete="#{args.validationFailed ? '':'dialog_groupEdit.hide()'}"
update="panel_groups panel_groupEdit" style="float:right;"/>
<div></div>
<p:message for="input_gnameEdit"/>
</h:panelGrid>
</p:dialog>
<p:dialog header="New Group" widgetVar="dialog_groupCreate" resizable="false"
width="300" showEffect="bounce" hideEffect="explode" modal="true" position="center">
<h:panelGrid id="panel_groupCreate" columns="2">
<h:outputText value="Group Name: "/>
<h:inputText id="input_gnameCreate" size="26" value="#{groupBean.createGroup.gname}" required="true" requiredMessage="New Group: Name is reqired."/>
<h:outputText value="Description:"/>
<h:inputTextarea rows="6" cols="23" value="#{groupBean.createGroup.description}"/>
<div></div>
<p:commandButton value="Save" actionListener="#{groupBean.saveGroupCreate}" oncomplete="#{empty groupBean.createGroup.gname ? ' ':'dialog_groupCreate.hide()'}"
update="panel_groupCreate panel_groups" style="float:right;"/>
<div></div>
<p:message for="input_gnameCreate"/>
</h:panelGrid>
</p:dialog>
One approach could be that I set the required="condation".
This is going to be clumsy. Just put each individual form in its own separate <h:form> component, or use the process attribute of the <p:commandButton> to identify the region you'd like to process.
<p:commandButton process="panel_groupEdit" ... />
...
<p:commandButton process="panel_groupCreate" ... />
Having a "God" form is in any way a poor practice.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
When you are using <p:dialog some of the good practices as advised on the PF forum are -
Never put your <p:dialog inside any other component. Place it somewhere so that it falls right under the <h:body.
Give every <p:dialog it's own form. But, don't place the dialog inside the form, place the form inside the dialog. It's not good to update the dialog itself, only it's content. (I think this should solve your issue also.)
e.g.
<p:dialog widgetVar="dlg" ...
<h:form ...
<h:panelGroup id="dlgContent" ...

Resources