<h:form action="#{bean.method()}"> gets called twice - forms

I am writing a Java EE application for changing password. For taking old and new password inputs I am using a jsf form.
<h:form method="post" action="#{changePass.updatePassword()}" >
<h:inputText id="username" value = "#{changePass.username}" readonly="true" required="true"/>
<h:inputSecret id="oldPassword" value = "#{changePass.oldPassword}" required="true" />
<h:inputSecret id="newPassword" value = "#{changePass.newPassword}" required="true" />
<h:inputSecret id="confirmPassword" value = "#{changePass.confirmPassword}" required="true" />
<button id="update" type="submit"></button>
</h:form>
My intention is to call updatePassword() function in changePass bean class when user clicks on the button. But this fuction gets called twice in this form.
when the form loads
When the user clocks on the button
How can I avoid this calling during the form load?

Your xhtml should look like this:
<h:form>
<h:inputSecret id="newPassword" value = "#{changePass.newPassword}" required="true" />
<h:commandButton value="submit" action="#{changePass.updatePassword}" />
</h:form>
If that still doesn't work then there is smtg wrong with your bean. Also you might want to follow some tutorials. I'm not entirely sure the syntax you used is wrong but it's the first time I've seen it though.

Related

Primefaces Form with 2 buttons dont update

I have a form that has an inputtext where the operator enters the clientid and click on "search", when the search is done the other fields in the form are populated correctly.
Then I have the button "new record" that calls a procedure that creates another object (not a customer) and needs to persist it, when the other object is created in the bean it takes every field from the form except a timestamp.
When the object is persisted only the timestamp is in the DB, all the form values are set to null.
<h:form id="myForm">
<h:outputText value="Customer number" />
<h:inputText id="cIdentidad" value="#{custBean.custID}" />
<p:commandButton process="#all" update="#all" action="#{custBean.populateFields(custBean.custID)}" value="Search" />
<p:growl />
<h:panelGrid id="newCust" columns="2" style="margin-top: 15px">
<h:outputText value="Name" />
<h:inputText id="name" value="#{custBean.name}" disabled="true"/>
<h:outputText value="more fields" />
<h:inputText id="nroAgenda" value="#{custBean.morefields}" disabled="true"/>
</h:panelGrid>
<p:commandButton process="#all" update="#all" action="#{custBean.newRecord()}" value="New record" />
</h:form>
The h:inputText's are disabled, so the value will not be submitted to the server. Maybe you're looking for readonly="true".
Also I would'nt use #all everywhere but rather #form. update="#all" has a special meaning.
Also see this answer.

Reset JSF form fields

I know a lot has been going around this topic, but all the solutions point out to creating a reset button ... is there no way of just clearing the fields and re-populating them ?
Here is what is my code
<p:commandButton id="basic" value="#{c.machine}" action="#{updateEntry.setMachine(c.machine)}" oncomplete="dlg1.show();" styleClass="ui-Machinebutton"/>
This sets the value 'machine' in 'updateEntry' and once completed launches the dialog box 'dlg1'
Dialog Box
<p:dialog id="Update_Entry" header="Update Entry" widgetVar="dlg1" modal="true" height="250" dynamic="True" resizable="False">
<h:form prependId="false" id="Update_Entry_Form" method="post" autocomplete="off">
<h:panelGrid id="update_grid" columns="2" style="margin-bottom:10px">
<f:facet name="header">
<p:messages />
</f:facet>
<h:outputLabel for="machine" value="Machine *" />
<p:inputText id="machine" value="#{updateEntry.machine}" required="true" requiredMessage="Machine is required">
<f:validateLength minimum="5" maximum="5"/>
</p:inputText>
The form loads the value fine for the first time, but it always loads the previous value even if updateEntry.machine is updated. How do i clear this off automatically ? I am using PrimeFaces
You forgot to ajax-update the dialog's content before opening. That's why it's always showing initial content as it was when the page was rendered for the first time or when the dialog was closed for the last time.
Do so accordingly:
<p:commandButton ... update=":Update_Entry">

JSF Buttons in forms sometimes don't perform action

I have problem with organizing forms. When I make one form some buttons (or any other components making ajax calls) don't perform action but they do perform update. When I split the form into two new ones the buttons start working.
In this case buttons and autocomplete don't work.
<h:form styleClass="question-#{cc.attrs.question.id}">
...
<p:commandButton value="add answer" update="#form" action="#{questionEditorBean.addAnswer}" />
<p:commandButton value="save" update="#(.question-#{cc.attrs.question.id})" action="#{cc.attrs.onSave}" oncomplete="#{cc.attrs.onCancel}" />
<p:commandButton value="cancel" onclick="#{cc.attrs.onCancel}" />
<p:autoComplete value="#{questionEditorBean.newTag}" id="tagSelect" completeMethod="#{tagBean.completeTag}" dropdown="true"
var="t" itemLabel="#{t.name}" itemValue="#{t}" converter="#{tagConverter}" forceSelection="true">
<p:ajax event="itemSelect" action="#{action}" update="#form"/>
</p:autoComplete>
</h:form>
When I split the form everything works.
<h:form styleClass="question-#{cc.attrs.question.id}">
...
<p:commandButton value="add answer" update="#form" action="#{questionEditorBean.addAnswer}" />
<p:commandButton value="save" update="#(.question-#{cc.attrs.question.id})" action="#{cc.attrs.onSave}" oncomplete="#{cc.attrs.onCancel}" />
<p:commandButton value="cancel" onclick="#{cc.attrs.onCancel}" />
</h:form>
<h:form>
<p:autoComplete value="#{questionEditorBean.newTag}" id="tagSelect" completeMethod="#{tagBean.completeTag}" dropdown="true"
var="t" itemLabel="#{t.name}" itemValue="#{t}" converter="#{tagConverter}" forceSelection="true">
<p:ajax event="itemSelect" action="#{action}" update="#form"/>
</p:autoComplete>
</h:form>
I don't have nested forms. I am running to this problem all the time. I don't understand this behaviour and I don't want to split buttons and components into more forms when they should be conceptually together. Is there a solution?
You could try giving the form an id and set prependId="false", as in this example:
<h:form id="ccForm" prependId="false">
Then you add the form id to all update targets.
<p:ajax event="itemSelect" action="#{action}" update="ccForm:tagSelect" />
This way you make explicit what are the update targets inside your composite component.
Also I noticed that you're trying to use styleClass as an id in your form, and trying to update it. Following this way I suggested, make its update property look like this:
<p:commandButton value="save" update="ccForm:question-#{cc.attrs.question.id}" action="#{cc.attrs.onSave}" oncomplete="#{cc.attrs.onCancel}" />
I hope it helps.

CommandButton's action URL depending on the form content

I'm doing a simple search engine for my web app and I'm facing a problem.
My search.xhtml works by getting a parameter, so that search.xhtml?key=lol will return the results for "lol".
What I need to do is that my search commandButton will redirect do search.xhtml?key=INPUT TEXT CONTENT.
Here's my simple code :
<div id="searchBox">
<pou:panel id="searchPanel">
<h:form>
<h:inputText id="searchInput" value="#{dispensaRicercaBean.query}" size="99" maxlength="99"/> <pou:commandButton icon="ui-icon-search" action="ricerca?faces-redirect=true"/>
<pou:watermark value="Search" for="searchInput"/>
</h:form>
</pou:panel>
</div>
where dispensaRicercaBean is #RequestScoped and my result page loads the data calling executeQuery(#{request.getParameter('key')) (a rough example, actually there are some differences)
How can I do that?
Use a plain HTML <form>
<form action="ricera.xhtml">
<h:inputText id="key" size="99" maxlength="99" />
<pou:watermark value="Search" for="key" />
<pou:button icon="ui-icon-search" onclick="submit(); return;" />
</form>

Why the form id prefix in the h:message output?

I'm currently trying simple validation using required="true"
<h:form>
<h:messages globalOnly="true"/>
<h:panelGrid>
<h:panelGrid columns="3">
<f:facet name="header">
Login Application Sample
</f:facet>
<h:outputLabel for="UserId" value="User Id" />
<h:inputText id="UserId" value="#{userBean.userId}" required="true" />
<h:message for="UserId"/>
<h:outputLabel for="Password" value="Password" />
<h:inputSecret id="Password" value="#{userBean.password}" required="true" />
<h:message for="Password" />
<f:facet name="footer">
<h:commandButton value="Login" action="#{userBean.login}"/>
<h:commandButton type="reset" value="Reset"/>
</f:facet>
</h:panelGrid>
</h:panelGrid>
</h:form>
Leaving the fields blank, and then clickin on the login button, these error messages will display on the right side of each field :
j_idt7:UserId: Validation Error: Value is required.
j_idt7:Password: Validation Error: Value is required.
This is what I expected, but I don't want to display the form id prefix of 'j_idt7:'. I read book examples, they don't output the form id prefix. What I want is :
UserId: Validation Error: Value is required.
Password: Validation Error: Value is required.
What should I do to skip displaying the form id prefix in the component specific messages ?
I'm currently testing JSF 2 in glassfish v3.
The message label defaults to component's client ID, exactly the one as you can see in generated HTML output via rightclick, View Source. That j_id7 is in this particular case the client ID of the parent <form> element. If you give the JSF component a fixed ID like <h:form id="login"> then the labels will become login:UserId and login:Password respectively.
You can however use the input component's label attribute to override it altogether so that the message label will be shown exactly as you intented.
<h:inputText ... label="User ID" />
<h:inputSecret ... label="Password" />
If the input component's label attribute is present, then it will be used instead of the client ID. Using prependId="false" as suggested by other answers has disadvantages. Don't do that.
A completely different alternative is to use requiredMessage (or converterMessage or validatorMessage) attribute for this, but this doesn't allow parameterizing messages and thus you'd have to hardcode the labels and such.
<h:inputText ... label="User ID is required." />
<h:inputSecret ... label="Password is required." />
See also:
Change the default message "Validation Error: Value is required" to just "Value is required"
Getting the component id on the error validation message
How to parameterize requiredMessage attribute in composite component?
Noted should be that it's indeed awkward to have labels duplicated like this:
<h:outputLabel for="userId" value="User ID" ... />
<h:inputText id="userId" ... label="User ID" />
<h:outputLabel for="password" value="Password" ... />
<h:inputSecret id="password" ... label="Password" />
If you happen to use JSF utility library OmniFaces, then you can use <o:outputLabel> to let JSF transparently set the label attribute of the associated component:
<o:outputLabel for="userId" value="User ID" ... />
<h:inputText id="userId" ... />
<o:outputLabel for="password" value="Password" ... />
<h:inputSecret id="password" ... />
If you use MyFaces and the bean validation framework (JSR303) try to define a MessageBundle with a key javax.faces.validator.BeanValidator.MESSAGE
faces-config.xml
<application>
<message-bundle>ApplicationMessages</message-bundle>
</application>
ApplicationMessages.properties
#javax.faces.validator.BeanValidator.MESSAGE={1}: {0}
javax.faces.validator.BeanValidator.MESSAGE={0}
Details
You need to override these messages from JSF.
You can have a messages.properties file in your classpath
Messages.properties
javax.faces.component.UIInput.REQUIRED=Field must be entered.
Faces-config.xml
<application>
<message-bundle>Messages</message-bundle>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
</application>
Have a look at this Article
If you care to see the HTML source from your browser, you will find out that the id of your input field is <form-id>+":"+<input-field-id>, in your case, j_idt7:UserId:. Try to give your <h:form> some meaningful id in order to make some sense out of it. You can read about JSF IDs here. In case you don't like it, you can turn it off by modifying your form tag to something like this,
<h:form prependId = false> // its true by default.
But that might turn out to be problematic, as pointed out by BalusC here.
Furthermore, it seems like you have never configured any validation messages yourself. Which in turn ends up with this message. Hence, a message.properties file is needed to have a control over message and show something more appropriate. Even then the field name should not be the part of the message, to make those validation message generic to avoid repetition. See BalusC's answer regarding the use of label attribute inside the <h:inputText>.
Where you are writing required = true, there you can define requiredMessage = "My Message" for any input type.
e.g.
<h:inputText autocomplete="false" id = "CellNumber" label="Cell Number" required="true" requiredMessage="Cell Number Required" maxlength="10" value="#{userManagedBean.cellNumber}" >