簡體   English   中英

JSF2 h:selectOneMenu在驗證失敗時顯示舊值

[英]JSF2 h:selectOneMenu shows old value when Validation Failed

我有一個包含少量輸入字段和一個選擇菜單的表單。 所有字段都是必需的=“true”,firstName,lastName,emailAddress,密碼,國家/地區。

測試用例#1:1)在所有輸入字段中輸入值,保留firstName字段而不輸入任何值,
選擇一個國家/地區(例如:美國)並提交表單,我們可以看到firstName字段所需的錯誤消息。

2)保持表單不變,保留firstName字段而不輸入任何值,然后選擇country to“select one”,並提交表單。 我們可以看到firstName和country字段的錯誤消息,但是在下拉列表中它沒有顯示“Select One”,它顯示美國(之前的選擇)。

我對輸入字段有同樣的問題,但我用轉換器解決了。 有沒有辦法解決這個問題。 我在stackoverflow中發布了一些帖子,后來才知道這是mojarra中的一個bug。

這是我的代碼......

userRegistration.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" >      
 <h:body>
    <h:form id="registrationForm">     
    <h:messages layout="table" infoClass="infoMsgs" errorClass="errMsgs"/>

    <table>
        <tr>
            <td>First Name:</td>
            <td>
                <h:inputText size="40" maxlength="100" 
                             required="true" 
                             styleClass="#{component.valid ? '' : 'text_error'}"
                             value="#{registrationAction.firstName}" />
            </td>
        </tr>
        <tr>
            <td>Last Name:</td>
            <td>
                <h:inputText size="40" maxlength="100" 
                             required="true" 
                             styleClass="#{component.valid ? '' : 'text_error'}"
                             value="#{registrationAction.lastName}" />
            </td>
        </tr>
        <tr>
            <td>Email Address:</td>
            <td>
                <h:inputText size="40" maxlength="100" 
                             required="true" 
                             styleClass="#{component.valid ? '' : 'text_error'}"
                             value="#{registrationAction.emailAddress}" />
            </td>
        </tr>
        <tr>
            <td>Password:</td>
            <td>
                <h:inputSecret size="20" maxlength="15" 
                             required="true" 
                             styleClass="#{component.valid ? '' : 'text_error'}"
                             value="#{registrationAction.password}" />
            </td>
        </tr>
        <tr>
            <td>Country:</td>
            <td>
                <h:selectOneMenu id="yourCountry" name="yourCountry"    
                                 value="#{shortRegistrationAction.shortRegistrationForm.selectedCountry}"
                                 required="true" 
                                 styleClass="#{component.valid ? '' : 'text_error'}">
                    <f:selectItem itemValue="#{null}" itemLabel="-Select One-" />
                    <f:selectItems value="#{registrationAction.countryList}" />
                </h:selectOneMenu>
            </td>
        </tr>
        <tr>
            <td>&#160;</td>
            <td>
                <h:commandButton name="RegisterButton" id="RegisterButton" 
                                 styleClass="submitbutton"
                                 value="Register"
                                 action="#{registrationAction.registerUser}" />
            </td>
    </table>
    </h:form>
</h:body>
</html>

RegistrationAction.java

package com.ebiz.web.bean;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import com.ebiz.service.ICountryService;
import com.ebiz.service.IUserService;
import com.ebiz.vo.UserVO;
import org.apache.log4j.Logger;

@ManagedBean(name = "registrationAction")
@ViewScoped
public class RegistrationAction implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(RegistrationAction.class);

    @ManagedProperty("#{countryService}")
    private ICountryService countryService;

    @ManagedProperty("#{userService}")
    private IUserService userService;

    private String firstName;
    private String lastName;
    private String emailAddress;
    private String password;
    private String selectedCountry;
    private List<String> countryList;

    @PostConstruct
    public void init(){
        countryList = countryService.getCountryList();
    }

    public void registerUser() {

        UserVO userVO = new UserVO();
        userVO.setFirstName(firstName);
        userVO.setLastName(lastName);
        userVO.setEmailAddress(emailAddress);
        userVO.setPassword(password);
        userVO.setCountry(selectedCountry);

        userService.registerUser(userVO);

    }
}

InputTextTrimmer.java

package com.ebiz.web.converter;

import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(forClass=String.class)
public class InputTextTrimmer implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        //return value != null ? value.trim() : null;
         if (value == null || value.trim().isEmpty()) {
             if (component instanceof EditableValueHolder) {
                 ((EditableValueHolder) component).setSubmittedValue(null);
                 ((EditableValueHolder) component).resetValue();
             }
             return null;
         }
         return value;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (value == null) ? null : value.toString();
    }

}

在ajax更新中查看以下BalusC博客文章重置未處理的輸入組件

您可以將OmniFaces添加到項目中並使用其ResetInputAjaxActionListener

因此,您必須將代碼更新為此(您最好使用f:ajax ):

<h:commandButton name="RegisterButton" id="RegisterButton" 
    styleClass="submitbutton"
    value="Register"
    action="#{registrationAction.registerUser}">
    <f:ajax execute="@form" render="@form" />
    <f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener"/>
</h:commandButton>

另外,看看這個BalusC答案如何在驗證錯誤發生后使用primefaces ajax填充文本字段?

經過長時間的研究,我沒有找到任何方法在JSF中實現它。 所以我使用jQuery來處理它的客戶端,可能這個答案不是最好的解決方案,但至少對需要解決方案的人有用。

此處下拉值將顯示為舊值,但仍顯示下拉列表的驗證錯誤。 在上面的xhtml頁面中,如果你查看下拉菜單部分,

    <h:selectOneMenu id="yourCountry" name="yourCountry"    
                     value="#{shortRegistrationAction.shortRegistrationForm.selectedCountry}"
                     required="true" 
                     styleClass="#{component.valid ? '' : 'text_error'}">
             <f:selectItem itemValue="#{null}" itemLabel="-Select One-" />
             <f:selectItems value="#{registrationAction.countryList}" />
</h:selectOneMenu>

即使它顯示驗證失敗案例的舊值,仍然styleClass變為text_error。 在關閉<h:body>標記后,我在xhtml頁面中添加了以下代碼。 ie( </h:body> )它只適用於這個特定xhtml頁面中的所有下拉菜單,但是我們可以將它放在commonTemplate.xhtml這樣的公共位置,以便在所有頁面上執行它。

 <script>
    //<![CDATA[
        jQuery(document).ready(function() {
            jQuery("select").each(function () {
                var dropDownClass = jQuery(this).attr('class');
                if(dropDownClass == 'text_error'){
                    jQuery(this).val('');
                }
              });
        });
    //]]>
    </script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM