开发者

JSF 2.0, messages not displayed inside a dataTable

开发者 https://www.devze.com 2023-04-09 08:11 出处:网络
I have a form with a dataTable which has various columns having links and outputTexts. There is one input field which is evaluated through an ajax request . A custom validator makes sure that only int

I have a form with a dataTable which has various columns having links and outputTexts. There is one input field which is evaluated through an ajax request . A custom validator makes sure that only integers are added to the field. The form is below.

    <form>  
            <h:dataTable var="item" value="#{listItems.mo开发者_JAVA技巧del}" id="adminlistItems"> 
                //other columns having commandLinks and outputTexts
                    <h:column>
                        <f:facet name="header" >
                            <h:outputText value="Quantity"/>
                        </f:facet>                  
                        <f:ajax listener="#{listItems.AddQuantityAction}">
                            <div style="padding:5px;float:left">
                                <h:inputText label="changeQuantity" id="addquantity" value="#{item.additionalQuantity}" maxlength="4" size="3">
                                    <f:validator validatorId="integerValidator"/>
                                </h:inputText>
                                <h:outputText value="&nbsp;"/>
                                <h:commandButton value="AddQuantity"  />
                                <h:message for="addquantity"/>
                            </div>
                        </f:ajax>  
                    </h:column>
            </h:dataTable>
        </h:form>

The code for the bean is :

    @ViewScoped
    @ManagedBean
    public class ListItems implements Serializable {    
    //...
    public String AddQuantityAction(){
              //...
      boolean result = //some action
              FacesContext context=FacesContext.getCurrentInstance();
              UIComponent component=UIComponent.getCurrentComponent(context);
              String clientID=component.getClientId(context);
              if (result) {
                   FacesMessage message = new FacesMessage("Quantity added successfully");
                  FacesContext.getCurrentInstance().addMessage(clientID, message);
              } else {
                  FacesMessage message = new FacesMessage("Quantity not added.Processing error");
                  FacesContext.getCurrentInstance().addMessage(clientID, message);
              }
              return "adminListItems"; 
          }
      }

The custom validator throws a validator exception which is not displayed. And the listener also has code for messages which too are not displayed. I have read several similar questions and this sounds a common question too. But even if i am missing something obvious,i am in need of a third eye to see what i dont.


The execute and render of <f:ajax> defaults to @this. So only the currently active component will be processed and refreshed. When you press the button, this won't send the input value nor refresh the message component.

Fix it accordingly:

<f:ajax execute="addquantity" render="addquantity_message" listener="#{listItems.AddQuantityAction}">
    ...
    <h:message id="addquantity_message" for="addquantity"/>
    ...
</f:ajax>

By the way, why don't you just use the builtin javax.faces.Integer converter instead of that validator?

<h:inputText ... converter="javax.faces.Integer">

Further, the return value of ajax listener methods should be void. It's totally ignored in any way. Also, method names should start with lowercase. See also Java naming conventions.


Update as per the comment, that didn't seem to work out well with regard to validation. The listener is invoked 2 times because essentially 2 ajax requests are been sent, one for the input and one for the command. I suggest to move the listener method to the <h:commandButton action>.

<f:ajax execute="addquantity" render="addquantity_message">
    ...
    <h:commandButton action="#{listItems.AddQuantityAction}" />
    <h:message id="addquantity_message" for="addquantity"/>
</f:ajax>

You'll only fix the obtained client ID to be the input ID, not the button ID.

0

精彩评论

暂无评论...
验证码 换一张
取 消