Escape a primefaces/jsf page that has required fields - validation

I have a jsf page with
<h:inputText required="true"> attribute.
When I click on my add button, I want to see an error if the field is blank.
I have a <f:message> to display this.
But how can I escape (cancel) the page with that field blank? In my case it continually posts the error message and I have to enter something in the field to go to another page.

If your cancel button is a POST requests e.g. <p:commandButton>,<h:commandButton>, <p:commandLink>, or <h:commandLink>
You can put your cancel button outside the form that has the <h:inputText> so that form is not submitted
<h:form>
<h:inputText value="#{bean.string}" required="true"/>
</h:form>
<h:form>
<p:commandButton value="Cancel" action="anotherpage.xhtml"/>
</h:form>
If you are navigating without any actions or method invocation, then you can use GET requests e.g. <h:button>, <p:button>, <h:link> or <h:outputLink>.
Example:
<h:form>
<h:inputText value="#{bean.string}" required="true"/>
<p:button value="Cancel" outcome="anotherpage.xhtml"/>
</h:form>

You can use immediate="true" in your <p:commandButton>. Then it will skip the validation.
For example:
<p:commandButton action="#{managedBean.action}" value="Cancel" immediate="true" />

Just don't process the form on submit if you want to cancel or navigate away.
I.e. don't do
<h:form>
...
<p:commandButton value="Cancel" action="#{bean.cancel}" />
</h:form>
But just do
<h:form>
...
<p:commandButton value="Cancel" action="#{bean.cancel}" process="#this" />
</h:form>
Or, better if you're only returning a navigation outcome in cancel() method anyway
<h:form>
...
<p:button value="Cancel" outcome="otherpage.xhtml" />
</h:form>

Related

All dialogs update the backing bean

I have 2 dialogs on a xhtml page:
<p:dialog width="400" id="dialog1" header="Download" widgetVar="dialog1">
<h:outputText value="Field1"/>
<h:inputText value="#{backingBean.field1}"/>
<br/>
<h:outputText value="Field2"/>
<h:inputText value="#{backingBean.field2}"/>
<br/>
<p:commandButton value="Download" ajax="false" onsuccess="PF('diaglog1').hide();">
<p:fileDownload value="#{backingBean.file}"/>
</p:commandButton>
</p:dialog>
<p:dialog width="400" id="dialog2" header="Send" widgetVar="dialog2">
<h:outputText value="Field1"/>
<p:inputText value="#{backingBean.field1}"/>
<br/>
<h:outputText value="Field2"/>
<h:inputText value="#{backingBean.field2}">
<p:ajax update="somePanel"/>
</h:inputText>
<br/>
<h:outputText value="Recipient"/>
<h:panelGroup id="somePanel">
<p:selectOneMenu style="width: 100%;" var="recipient">
<f:selectItems value="#{backingBean.someList}"/>
</p:selectOneMenu>
</h:panelGroup>
<br/>
<p:commandButton value="Send" actionListener="#{backingBean.sendSomething}" onsuccess="PF('dialog2').hide();">
<f:attribute name="item" value="#{recipient}"/>
</p:commandButton>
</p:dialog>
They have different functionality but are on the same page and using the same backing bean. Only one dialog can appear at a time. The problem is when I input some value into the first dialog and press 'Download', it will update the field1 and field2 of the backing bean to the value that I want, but after that the second dialog also updates it to its value, which causes the first one to download the wrong file. If I remove the second dialog, the first will behave correctly.
How do I stop the second dialog from updating the values?
I guess you are keeping both dialogs in one single h:form component.
Then obviously submit in one dialog will submit fields in both dialogs coz, they are in same form.
Don't keep p:dialog inside a h:form, instead use h:form inside
dialog.
You can use multiple h:form s in a page there is no harm in
that, but should not use one h:form in another.
Decide how many forms you can use, based on your design and functionality, In your case you can use 2 h:forms each one inside both dialogs.

JSF and AJAX: hiding part of site until first ajax request

I'm trying to create a page where some content will be displayed after ajax request. Here is part of my code:
<h:panelGroup>
<h:form>
Retrive object by id: <h:inputText id="myInput" value="#{myManager.id}"/>
<h:commandButton value="ok" action="#{myManager.getById}" >
<f:ajax execute="myInput" render="resultRow" />
</h:commandButton>
<h:panelGroup id="resultRow" >
<br />
You retrived object which id is:
<h:outputText value="#{retrivedObject.id}" />
and its name is:
<h:outputText value="#{retrivedObject.name}" />
</h:panelGroup>
</h:form>
</h:panelGroup>
My problem is taht the "You retrived object which id is: " is rendered even before I retrive any object. I want it to be hidden until I click my command button. Is it possible to do only with jsf + html (this have to be done with ajax)? I could use some javascript if I will have to, but I prefer not.
I tried to solve this by rendered="#{!retrivedObject.id==0}" (my object can't have id 0), but this doesn't work - panel group isn't rendered at all and when I call ajax reqest it is unable to find "resultRow" id.
Thanks for help in advance.
It may not be exactly what you are looking for but you can always wrap the panelGroup in a div and set the div visibility to hidden, then use javascript to change the visibility when you click the command button.
You can use the rendered attribute like this :
<h:panelGroup>
<h:form>
Retrive object by id: <h:inputText id="myInput" value="#{myManager.id}"/>
<h:commandButton value="ok" action="#{myManager.getById}" >
<f:ajax execute="myInput" render="resultRow" />
</h:commandButton>
<h:panelGroup id="resultRow">
<h:panelGroup rendered="#{retrivedObject ne null}">
<br />
You retrived object which id is:
<h:outputText value="#{retrivedObject.id}" />
and its name is:
<h:outputText value="#{retrivedObject.name}" />
</h:panelGroup>
</h:panelGroup>
</h:form>
</h:panelGroup>

Ajax not working with primefaces

In my JSF page I have form when I click submit button in the same page I need to show an static content. But When I click <p:commandbutton> nothing appears in the page. When I put ajax="false" then only action taken place but the Static content display in new page.
In my Backing bean I have used Session scoped. I am using JSF 2.0 and Primefaces 3.2.
My JSF Page.
<h:form>
<h:panelGroup rendered="#{not license.showForm}">
<p:panel header="License Key Request" >
<h:panelGrid columns="2" >
..
<h:outputText value="Bla bla"/>
..
<h:outputText value="Bla Bla" />
</h:panelGrid>
<TABLE>
..
<h:outputLabel for="name" value="Requestor Name : *" />
..
<p:inputText id="name" value="#{license.name}" required="true" requiredMessage="Name is required."/>
..
<h:outputLabel for="company" value="Company : * " />
..
<p:inputText id="company" value="#{license.company}" required="true" requiredMessage="Company is required."/>
..
</table>
<p:commandButton value="Form" id="btnAdd" process="#form"
action="#{license.add}" />
..
</table>
</p:panel>
</h:panelGroup>
<h:panelGroup rendered="#{license.showForm}" >
<h:outputText value="Bla Bla"/>
</h:panelGroup>
</h:form>
Your source code is somewhat confusing (e.g. you have two closing table tags). But I assume that you want to show the panelGroup at the bottom if the button is clicked.
The easiest way would be to add an update ="#form" to your commandButton:
<p:commandButton value="Form" id="btnAdd"
process="#form" update="#form"
action="#{license.add}" />
You don't need to update the whole form but only the specific component. Then you need to give the panelGroup an id attribute and use this attribute instead of #form. However, since it is not clear for me how your naming containers are organized, it could be puzzling to find the correct relative id.

understanding ajax execute behavior with datatable using jsf 2.0

i'm trying to use an search button which brings back the selected items (can be more than one) and it updates the datatable. Then i have a selectBooleanCheckbox next to each colomn, when user selects "n" items then presses the Select the checked Items it insert DB.
The code can be seen below:
<h:panelGrid columns="5">
<h:form>
<h:outputText value="Item Name"/>
<p:inputText value="#{StockController.itemName}"/>
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results"/>
</h:commandButton>
</h:form>
//The code sample below belongs to BalusC see the post here
<h:panelGroup id="results">
<h:form>
<h:dataTable value="#{bean.entities}" var="entity">
<h:column>
<h:selectBooleanCheckbox value="#{bean.checked[entity.id]}" />
</h:column>
...
</h:dataTable>
<h:commandButton value="Select the checked Items" action="#{StockController.insertDao}" >
<f:ajax execute="#form" render=":results"/>
</h:commandButton>
</h:form>
</h:panelGrid>
Now, i have read many blogs and Core javaServer Faces 3, i don't think there is logical error in ajax usage. I tested by removing each ajax then both works fine but whenever i try to use both of cummondButtons with ajax, the second one "Select the checked Items" does not even call the "StockController.insertDao" method.
Any help is appreciated.
Thanks all.
When you want to ajax-render content which in turn contains another form, then you need to include the ID of that form in the render attribute as well, otherwise the other form will lose its view state and nothing will be processed on submit.
<h:form>
...
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results :resultsForm" />
</h:commandButton>
</h:form>
<h:panelGroup id="results">
<h:form id="resultsForm">
...
</h:form>
</h:panelGroup>
If there's however nothing which goes outside <h:form> inside the same <h:panelGroup>, then you can just omit the <h:panelGroup> altogether and re-render the form directly.
<h:form>
...
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results" />
</h:commandButton>
</h:form>
<h:form id="results">
...
</h:form>
This is related to JSF spec issue 790.
See also:
Communication in JSF2 - Ajax rendering of content which contains another form

Inputtext not syncing with backend bean when commandbutton is pushed

When I hit the commandButton it puts in the value that product.amount started as rather than what is currently typed in the input box.
<h:inputText value="#{product.amount}" />
<h:commandButton id="Button"
value="Buy"
tabindex="2" >
<f:ajax listener="#{shopBean.addToCart(product.product, product.amount)}"
execute="#this"
render="#all" />
</h:commandButton>
You need to include the input field in the execute attribute of the <f:ajax> so that it get processed as well, otherwise it will simply be ignored altogether.
<h:inputText id="amount" ... />
<h:commandButton ...>
<f:ajax execute="#this amount" ... />
</h:commandButton>
Or just put the whole in a single form and use execute="#form".
<h:form>
<h:inputText ... />
<h:commandButton ...>
<f:ajax execute="#form" ... />
</h:commandButton>
</h:form>
By the way, the render="#all" defeats one of the main advantages of using ajax. Try to render exactly only the component(s) which actually needs to be updated.

Resources