How can we use multiple <h:messages> tags or <h:message> tags in a single JSF page? - jsf

My problem is that I have 2 forms in a single JSF page each having its <h:message> or <h:messages> tag. As we know the message/messages tags print any validation errors, so what happens is, suppose I leave the fields of any of the 2 forms empty it should print "Fields cannot be left blank" or some kind of message. It gives this message, but it gives twice as there are two forms. So I see the same error/validation message at each of the two forms.
So what I need is the <h:messages> or the <h:message> tag should display error/validation message only once for each of their respective forms!!
So any help would greatly be appreciated!!

If you're using JSF 2, then you could just submit and update the form by ajax. This allows for partially updating the view.
<h:form>
<h:messages />
...
<h:commandButton ...>
<f:ajax execute="#form" render="#form" />
</h:commandButton>
</h:form>
<h:form>
<h:messages />
...
<h:commandButton ...>
<f:ajax execute="#form" render="#form" />
</h:commandButton>
</h:form>
Or if you can't/don't want to use ajax for some unobvious reason, or are still using the legacy JSF 1.x, then check in the rendered attribute of <h:messages> if the desired form is been submitted or not.
<h:form binding="#{form1}">
<h:messages rendered="#{form1.submitted}" />
...
<h:commandButton ... />
</h:form>
<h:form binding="#{form2}">
<h:messages rendered="#{form2.submitted}" />
...
<h:commandButton ... />
</h:form>
The <h:message> shouldn't have this problem by the way, in contrary to what you're implying in your question.

Related

h:commandLink renders data table but p:commandLink does not [duplicate]

I'm trying to ajax-update a conditionally rendered component.
<h:form>
...
<h:commandButton value="Login" action="#{login.submit}">
<f:ajax execute="#form" render=":text" />
</h:commandButton>
</h:form>
<h:outputText id="text" value="You're logged in!" rendered="#{not empty user}" />
However, that does not work. I can assure that #{user} is actually available. How is this caused and how can I solve it?
It's not possible to re-render (update) a component by ajax if the component itself is not rendered in first place. The component must be always rendered before ajax can re-render it. Ajax is using JavaScript document.getElementById() to find the component which needs to be updated. But if JSF hasn't rendered the component in first place, then JavaScript can't find anything to update.
The solution is to simply reference a parent component which is always rendered.
<h:form>
...
<h:commandButton ...>
<f:ajax ... render=":text" />
</h:commandButton>
</h:form>
<h:panelGroup id="text">
<h:outputText ... rendered="#{not empty user}" />
</h:panelGroup>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

Unable to update component with rendered="#{initially false}" with Ajax [duplicate]

I'm trying to ajax-update a conditionally rendered component.
<h:form>
...
<h:commandButton value="Login" action="#{login.submit}">
<f:ajax execute="#form" render=":text" />
</h:commandButton>
</h:form>
<h:outputText id="text" value="You're logged in!" rendered="#{not empty user}" />
However, that does not work. I can assure that #{user} is actually available. How is this caused and how can I solve it?
It's not possible to re-render (update) a component by ajax if the component itself is not rendered in first place. The component must be always rendered before ajax can re-render it. Ajax is using JavaScript document.getElementById() to find the component which needs to be updated. But if JSF hasn't rendered the component in first place, then JavaScript can't find anything to update.
The solution is to simply reference a parent component which is always rendered.
<h:form>
...
<h:commandButton ...>
<f:ajax ... render=":text" />
</h:commandButton>
</h:form>
<h:panelGroup id="text">
<h:outputText ... rendered="#{not empty user}" />
</h:panelGroup>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

h:commandButton not working [duplicate]

How to update a div and do partial submission using <h:commandButton>, I have previously used <p:commandButton> to do partial submission by setting the ajax attribute to true and the update attribute to :statusBlock, where the id of the <h:panelGroup> is statusBlock. I am having some designing issues with <p:commandButton> so I cannot use it so I have to use <h:commandButton>.
This is to be done by nesting a <f:ajax> in it.
In effects,
<p:commandButton ... process="#form" update=":statusBlock" />
does exactly the same as
<h:commandButton ...>
<f:ajax execute="#form" render=":statusBlock" />
</h:commandButton>
Note that the subtle difference with the PrimeFaces equivalent is that PrimeFaces defaults to #form in the process/execute, while the <f:ajax> one defaults to #this, so you might need to explicitly specify execute="#form" over all place where you didn't specify the process attribute in the PrimeFaces component.
See also:
Communication in JSF 2.0 - Ajax (asynchronous) POST form
You can just use the standard components alongside f:ajax e.g.
<h:form id="myForm">
<h:commandButton value="Push Me">
<f:ajax execute="myForm" render="statusBlock" />
</h:commandButton>
<h:panelGroup id="statusBlock">
</h:panelGroup>
</h:form>

Why doesn't h:commandButton execute the action method when combined with c:chose?

I've seen a strange problem in my project. It's that <h:commandButton/> does not execute the action method.
<c:choose>
<c:when test="#{empty param.t}">
// HTML
</c:when>
<c:when test="#{param.t eq 'normal'}">
// HTML
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}" />
</h:form>
<c:when>
</c:choose>
When I move <h:form> into first c:when, then the action method is called. Otherwise, it isn't. Why?
I'll ignore the syntax error in your EL (a missing }).
The command button won't be executed when #{param.t eq 'normal'} evaluates to false at the point the form submit request is to be processed. You need to maintain the same parameter for the subsequent request so that the button will be rendered so that JSF can confirm that the enduser is allowed to invoke the action. You can do this by adding a <f:param>:
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}">
<f:param name="t" value="#{param.t}" />
</h:commandButton>
</h:form>
Note that this is supported since JSF 2.0 only. On JSF 1.x you'd need to replace h:commandButton by a h:commandLink if you want f:param support.
Unrelated to the concrete problem, you should try to avoid JSTL as much as possible in your JSF views. If the intent is to render view parts conditionally (not to build view parts conditionally), then you should rather be using the JSF component's rendered attribute instead of a JSTL <c:choose> or <c:if>:
<h:panelGroup rendered="#{empty param.t}">
// HTML
</h:panelGroup>
<h:panelGroup rendered="#{param.t eq 'normal'}">
// HTML
<h:form>
<h:commandButton value="ADD" action="#{addBean.doSomething}" />
</h:form>
</h:panelGroup>

JSF 2.0 - Ajax submit validation on inputs

I have a form that needs to be submitted with ajax. I am trying to get the validation to work but it wont work when I use ajax. When I take the ajax out and submit the form with an empty testinput it properly triggers he validation and does not submit the form. How can I do this with an ajax call. My form is below.
<h:form>
<f:ajax>
<h:panelGrid columns="3">
<h:outputLable for=test" value="testinput:" />
<h:inputText id=test" required="true" label="testinput" />
<h:message for="test" id="testError"/>
</h:panelGrid>
<h:commandButton value="Submit" actionListener="#{testBean.doSomething}" />
</f:ajax>
</h:form>
The <f:ajax> by default doesn't re-render the form, so you won't see anything. Replace <f:ajax> by <f:ajax execute="#form" render="#form" />.
Maybe try something like this:
<h:form id="yourFormId">
<!-- form content -->
<h:commandButton value="Submit">
<f:ajax execute="yourFormId" listener="#{testBean.doSomething}"/>
</h:commandButton>
</h:form>

Resources