how can I validate a composite component on blur? - jsf-2

I have a composite component that contains two inputText components.
The composite component manages a bean containing two Integers.
class valueBean {
private Integer valueA;
private Integer valueB;
//getters, setters.
}
<composite:interface componentType="valueBeanUI">
<composite:attribute name="value">
</composite:interface>
<composite:implementation>
<h:inputText id="inputA"/>
<h:inputText id="inputB"/>
</composite:implementation>
In my valueBeanUI I implement getConvertedValue and encodeBegin.
Everything works as expected - when I click submit the code in getConvertedValue is called and I can throw error messages if the conversion values if the user enters characters in the integer fields.
What I would like to do is be able to require a valid value in both fields, and show one error message if this condition is not met. I have this working when the user clicks submit, but I'd like to fire it on blur of either field (inputA or inputB). I cant figure out how to validate the backing component when either field blurs. Can anyone suggest a way to achieve this? I dont want to submit the whole form - I'd like to do just this component via ajax.

Just add <f:ajax event="blur"> to the inputs.
<h:inputText id="inputA">
<f:ajax event="blur" execute="#this inputB" render="messageForInputA messageForInputB" />
</h:inputText>
<h:inputText id="inputB">
<f:ajax event="blur" execute="#this inputA" render="messageForInputA messageForInputB" />
</h:inputText>
The messageForInputA should point to a <h:message id="messageForInputA">.

Related

Primefaces selectBooleanCheckbox with binding

i am trying to make composite component(multiply use on each view) which allows me to show some inputs by checkbox value. One input is depended on checkbox value. I dont want to bind it to bean cause this value is not saved to database or so. I though that i ll save it in view scope holder.
I ve added in face config holder for bindings
<managed-bean>
<description>Holder of all component bindings.</description>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
composite component:
<p:selectBooleanCheckbox binding="#{components[cc.attrs.bindingId]}">
<p:ajax update="panel"/>
</p:selectBooleanCheckbox>
<h:panelGroup id="panel">
<p:inputText rendered="#{components[cc.attrs.bindingId].value}" value="#{cc.attrs.beanPropertyOnTrue}">
<p:inputText rendered="#{not components[cc.attrs.bindingId].value}" value="#{cc.attrs.beanPropertyOnFalse}">
</h:panelGroup>
It works fine, I can use this component multiply on one view, but the problem is when i am using commandButton to send form to server, checkboxes are changing to unchecked....
<p:commandButton value="show decision dialog"
actionListener="#{testBean.action}"
update="#form"
oncomplete="if (args && !args.validationFailed){ dialog.show() }"/>

Why does required="true" not fail validation when disabled="true" is specified

<a4j:outputPanel id="tapalSectionSendToPanel" ajaxsingle="true">
<h:inputText id="sendToId1" value="#{MainBean.SectionBean.sendTo}"
class="createresizedTextbox"
required="true" requiredMessage="#{msg.labl_required}"
disabled="true" />
<h:message for="sendToId1" style="color:red" />
</a4j:outputPanel>
i need to validate textbox for empty validation and should show required when i click button without entering any value in textbox. It works fine without disabled="true". Whats the alternative for my requirement.
First, required and disabled don't go well together, because they are mutually exclusive as per the JSF Spec:
required: Flag indicating that the user is required to provide a submitted value for this input component.
disabled: Flag indicating that this element must never receive focus or be included in a subsequent submit.
Like I said in the comments, you can just display a message when the user tries to submit the form without selecting a node:
<h:inputText id="sendToId1" value="#{MainBean.SectionBean.sendTo}"
styleClass="createresizedTextbox" required="true" readonly="true" />
<h:message for="sendToId1" value="#{msg.labl_required}"
rendered="#{facesContext.postback and facesContext.validationFailed}" />
As an alternative you can just display a text anywhere in your markup:
<h:outputText value="#{msg.labl_required}"
rendered="#{empty MainBean.SectionBean.sendTo}" />
disabled="true" disables the input (so it's skipped when the form is submitted), if you don't want the user to type in it use readonly="readonly"

JSF 2: Cannot choose default entry in dropdown element when dropdown is required and default entry is null

I have the following JSF 2 code:
<p:selectOneMenu id="dropdown" value="#{data.selection}" required="true" converter="selectOneMenuConverter">
<f:selectItem itemLabel="Select one..." itemValue="" noSelectionOption="true" />
<f:selectItems value="#{data.entries}" var="entry" itemLabel="#{entry.name}" itemValue="#{entry}" />
<p:ajax update="display" event="change" />
</p:selectOneMenu>
<h:panelGroup id="display">
<h:outputText value="#{data.selection}" />
</h:panelGroup>
Everything works as expected when I choose a value from the dropdown.
When the user "deselects" an entry by choosing "Select One", JSF complains that this is not possible because the selectonemenu is required.
The problem comes from there that the p:ajax makes a partial submit that triggers validation. Immediate=true does also not work because in case the immediate happens on an input field (like selectonemenu is) a validation is performed.
The validation shall only happen when the user presses the "go on" button on the bottom of the page (not shown in code)
Further the given converter converts the Strings to Objects and for the default value it returns null (that's also the expected value within the domain for "no selection").
So my question is what I must do to fulfill my case.
For my this is a standard case and I cannot imagine that there is no solution for this.
Any ideas?
Best regards,
Florian
The validation shall only happen when the user presses the "go on" button on the bottom of the page (not shown in code)
Then just tell the dropdown's required attribute to do exactly that instead of hardcoding a true.
<h:form id="form">
<p:selectOneMenu ... required="#{not empty param['form:go']}">
...
</p:selectOneMenu>
...
<p:commandButton id="go" ... />
</h:form>
The #{not empty param['form:go']} will only evaluate true when the form submit has actually been taken place by the submit button which has the client ID form:go in the particular example. If you don't like hardcoding client IDs either, then reference it as follows:
<h:form>
<p:selectOneMenu ... required="#{not empty param[go.clientId]}">
...
</p:selectOneMenu>
...
<p:commandButton binding="#{go}" ... />
</h:form>

p:message attached to a h:form

I have two forms in my page, in the first formulary are input fields with validation, and in the other a dataTable. The first formulary has a message area to show validation errors, and the second formulary has a message area to show problems with the retrieval of the data (this message area is updated from myController.search).:
<h:form id="form1">
<p:message id="messageForm1" for=":form1" />
<p:inputText id="text1" value="#{myBean.data}" required="true" />
....
<p:commandButton value="Search" actionListener"#{myController.search}"
update=":form2:dataTable :form2:messageForm2 :form1:messageForm1" process="text1, ..." />
</h:form>
<h:form id="form2">
<p:message id="messageForm2" for="messageForm2" />
<p:dataTable>
...
</p:dataTable>
</h:form>
The problem is that the messages in the form2 are working, but the validation messages in form1 are never shown
The description of the for attribute of the p:message tag says:
Id of the component whose messages to display.
So you can't specify the ID of the form. You have to specify the ID of a single form component. e.g. <p:message id="messageForm1" for="text1" />. But then you have to create one message element for every form component.
An alternative would be to use the p:messages tag. For examples see here: http://www.primefaces.org/showcase-labs/ui/messages.jsf

h:selectOneMenu onchange="submit()" immediate="true" does not skip validation of other inputs

I can't set my h:selectOneMenu to submit immediately without validating other inputs. Here is the code:
<h:selectOneMenu value="#{a.avalue}" onchange="submit()" immediate="true">
<f:selectItems value="#{b.bvalue}" var="k" itemLabel="#{k.asdad}"
itemValue="#{k.asdad}"/>
</h:selectOneMenu>
<h:inputText id="sada" value="#{c.cvalue}" required="true"
requiredMessage="*asdadadadasd"
validatorMessage="*asdsadadadadad">
<f:validateLength maximum="80"/>
</h:inputText>
When I change the menu value, the validators of other inputs still fire. How can I deny that?
The immediate="true" on current input component doesn't stop validators of other input components from firing. It only causes that the current input component will be validated one phase before than usual. Basically, you need to attach a valueChangeListener to the input component and then call FacesContext#renderResponse() in the listener method so that the processing of all other input components will be skipped.
But as you're already using JSF 2.0, much better/easier is to use ajax powers instead of this old fashioned JSF 1.x approach.
E.g.
<h:selectOneMenu value="#{bean.country}">
<f:selectItems value="#{bean.countries}" var="country" itemLabel="#{country.name}" itemValue="#{country.code}"/>
<f:ajax listener="#{bean.changeCountry}" />
</h:selectOneMenu>
with
public void changeCountry() {
System.out.println("Selected country is: " + country);
}
If you'd like to re-render some parts of the form whenever the selection is changed, then use the render attribute. E.g.
<f:ajax listener="#{bean.changeCountry}" render="otherComponentId" />
See also:
When to use valueChangeListener or f:ajax listener?

Resources