简体   繁体   中英

jsf1.2 rich:messages duplicating validation of rich:message in the same form

I am preparing a registration page using JSF/Spring webflow&mvc application. I have added two side validation one in client side every input fields has its own rich:message and other one at server side, registration bean response as facescontext.addMessage(). My problem when I try to test validation, rich:message components show errors correct but rich:messages show same errors as well. I want to use messages just for specific errors, something like mail already exist in database.

my rich:messages tag:

<rich:messages id="msg" layout="table" limitRender="true"
            style="font-weight:bold;color:#BDBDBD">
            <f:facet name="errorMarker">
                <h:graphicImage url="/images/messages_error.png" />
            </f:facet>
        </rich:messages>

<h:form ...>
   .....SOME LOGIC.....

<h:inputText id="i_ln" required="true" value="#{regBean.lastName}">
    <f:validateLength minimum="2" maximum="35" />
    <rich:ajaxValidator event="onblur" />
</h:inputText>
<rich:message for="i_ln">
    <f:facet name="errorMarker">
       <h:graphicImage url="/images/messages_error.png" />
    </f:facet>
</rich:message>
       .....
    </h:form>

I have checked similar issues that people advice to use globalOnly="true" and when I use this attribute then duplicate validation stops but I am not able to add severity error. My oytput as below:

Feb 07, 2012 10:08:04 PM com.sun.faces.lifecycle.RenderResponsePhase execute
INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=i_comment[severity=(ERROR 2), summary=(Eingabe wird benötigt.), detail=(Eingabe wird benötigt.)]
sourceId=i_title[severity=(ERROR 2), summary=(Eingabe wird benötigt.), detail=(Eingabe wird benötigt.)]
sourceId=i_salut[severity=(ERROR 2), summary=(Eingabe wird benötigt.), detail=(Eingabe wird benötigt.)]
sourceId=i_mobile[severity=(ERROR 2), summary=(Eingabe wird benötigt.), detail=(Eingabe wird benötigt.)]
sourceId=i_fax[severity=(ERROR 2), summary=(Eingabe wird benötigt.), detail=(Eingabe wird benötigt.)]

Another question is should I keep server side validation?

Ok here is a workaround: First of all its a known issue refer to jboss community :

Hi guys,

We investigated the issue further by debugging the RichFaces JavaScript code.

We noticed that both the <rich:messages globalOnly="true" /> component and the <rich:message for="inputField" /> component bind to an "onMessage" event.

When the event is triggered on tab, the "onMessage" function in "message.js.faces" is triggered for both components.

    As you can see in the attached screenshots the function is called twice: once for both components. Other <rich:message /> components which have a "for" attribute related to other fields are not triggered, just as expected.
    In the JavaScript code, we can see that a check is performed on the availability of the "forComponentId" attribute. If this attribute is available, a validation message is rendered for the specified component id. If this is not available, a global message is rendered.
    But when a global message is rendered, we cannot see any check on the globalOnly attribute. So any message is rendered, regardless of this attribute. The attribute is nowhere to be found in the JavaScript code.

    We were wondering if this is the bug or if there is an other piece of code that is responsible for checking whether only global error messages may be displayed?

So I have played around with code and notice that rich:messages just picking messages when:

  1. if globalOnly="true" and clientId is null or clientId is messages component id.
  2. if for="xxx" attribute assigned and message has client&sourceID="xxx"
  3. if no for="xxx" and no globalOnly="true" attribute assigned then any message also messages with the null client id.

I was able to apply two solution for this:

First solution for pages with just one rich:messages;

My rich:messages tag just have globalOnly="true" and there is no for attribute;

   <rich:messages id="msg" layout="list"
        style="font-weight:bold;color:#BDBDBD" 
        globalOnly="true">
        <f:facet name="errorMarker">
            <h:graphicImage url="/images/messages_error.png" />
        </f:facet>
    </rich:messages>

And my bean send message with id=null;

private void addSeverityError(String message)
    {
        FacesContext context = FacesContext.getCurrentInstance();
        FacesMessage fMessage = new FacesMessage();
        fMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
        fMessage.setSummary(message);
        fMessage.setDetail("Validation error");
        context.addMessage(null, fMessage);
    }

Second solution for pages with more than one rich:messages;

I have added one hidden rich:message to use as a bridge, then my message can have hidden component id and will not be null, after I just pick it up by my rich:messages using this id.

<rich:message id="nonExistClient" rendered="false"/>
<a4j:form id="messagesForm">
    <rich:messages id="msg" layout="list"
        style="font-weight:bold;color:#BDBDBD" 
        for="nonExistClient">
        <f:facet name="errorMarker">
            <h:graphicImage url="/images/messages_error.png" />
        </f:facet>
    </rich:messages>
</a4j:form>

And I have added message as below via FacesContext:

private void addSeverityError(String message)
{
    FacesContext context = FacesContext.getCurrentInstance();
    FacesMessage fMessage = new FacesMessage();
    fMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
    fMessage.setSummary(message);
    fMessage.setDetail("Validation error");
    context.addMessage("nonExistClient", fMessage);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM