2011-03-09 73 views
0

我有一些輸入一種形式,具有ViewScoped * ManagedBean *後面。在窗體的底部我有一個CommandButton來保存數據。有一個數據表的形式可以添加新的項目通過輸入數據到輸入並點擊另一個CommandButton。當用戶填充所有輸入並將任何項目添加到數據表時,他/她可以單擊保存按鈕。但是我在控制添加按鈕和更新數據模型方面遇到了一些問題。當我將按鈕的無形設置爲true時,輸入的值不會更新,並且當我將其設置爲false時,驗證錯誤將發生在窗體上的其餘輸入上!JSF複雜的形式 - 綁定錯誤

如果它可以幫助

代碼:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" 
       template="./templates/master.xhtml" 
       xmlns:h="http://java.sun.com/jsf/html" 
       xmlns:f="http://java.sun.com/jsf/core" 
       xmlns:p="http://primefaces.prime.com.tr/ui" 
       xmlns="http://www.w3.org/1999/xhtml"> 

    <ui:define name="windowTitle"> 
    #{lbls.registerWaggon} 
    </ui:define> 

    <ui:define name="sectionTitle"> 
    <h:panelGroup layout="block" styleClass="sectionTitle"> 
     <h:graphicImage library="img" name="railways.png"/> 
    </h:panelGroup> 
    </ui:define> 

    <ui:define name="right"> 
    <ui:include src="templates/railwaysright.xhtml"/> 
    </ui:define> 

    <ui:define name="extraCSS"> 
    <h:outputStylesheet library="css" name="persiancalendar.css"/> 
    <h:outputStylesheet library="css" name="grid.css"/> 
    </ui:define> 

    <ui:define name="extraJS"> 
    <h:outputScript library="js" name="lib/persiancalendar.js"/> 
    </ui:define> 

    <ui:define name="content"> 
    <h:panelGroup rendered="#{!current.hasLoggedIn()}">  
     <h:panelGroup layout="block" styleClass="warningBox"> 
     <h:outputText value="#{app.youHaveNotLoggedIn}"/> 
     <br/> 
     <h:link value="#{lbls.login}" outcome="login"/> 
     </h:panelGroup>  
    </h:panelGroup> 


    <p:panel rendered="#{current.hasLoggedIn() and requestWaggon.isViewable()}"> 
     <f:facet name="header"> 
     <h:outputText value="#{lbls.registerWaggonLong}" /> 
     </f:facet> 

     <h:form id="frmRequest"> 
     <h:panelGrid columns="3" footerClass="buttons"> 
      <h:outputText value="#{lbls.number}:"/> 
      <h:inputText id="number" label="#{lbls.number}" styleClass="ltr" value="#{requestWaggon.request.number}" readonly="true" /> 
      <h:message for="number" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.requestDate}:"/> 
      <h:inputText styleClass="ltr" id="date" label="#{lbls.requestDate}" value="#{requestWaggon.request.date}" required="true" readonly="true"> 
      <f:converter converterId="ir.khorasancustoms.DateConverter"/> 
      </h:inputText>   
      <h:message for="date" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.nameOfMaterialOwner}:"/> 
      <h:inputText id="ownerName" label="#{lbls.nameOfMaterialOwner}" value="#{requestWaggon.request.fullName}" required="true" readonly="true"/> 
      <h:message for="ownerName" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.companyName}:"/> 
      <h:inputText id="companyName" label="#{lbls.companyName}" value="#{requestWaggon.request.companyName}" required="true" readonly="true"/> 
      <h:message for="companyName" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.nameOfMaterial}:"/> 
      <h:inputText id="nameOfMaterial" label="#{lbls.nameOfMaterial}" value="#{requestWaggon.request.materialName}" required="true" readonly="true"/> 
      <h:message for="nameOfMaterial" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/>       

      <h:outputText value="#{lbls.materialWeight}:"/> 
      <h:panelGroup> 
      <h:inputText id="materialWeight" styleClass="ltr" label="#{lbls.materialWeight}" value="#{requestWaggon.request.materialWeight}" required="true" style="min-width: 0px; width: 60px" readonly="true"/> 
      <h:outputText value=" #{requestWaggon.request.weightUnit}"/>    
      </h:panelGroup> 
      <h:message for="materialWeight" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.senderAddress}:"/> 
      <h:inputText id="senderAddress" label="#{lbls.senderAddress}" value="#{requestWaggon.request.address}" required="true" style="width: 350px;" readonly="true"/> 
      <h:message for="senderAddress" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.receiverAddress} (#{lbls.country}):"/>    
      <h:outputText value="#{requestWaggon.request.country}"/> 
      <h:message for="country" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.station}:"/> 
      <h:inputText id="station" label="#{lbls.station}" value="#{requestWaggon.request.station}" required="true" readonly="true"/> 
      <h:message for="station" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.loadingDate}:"/> 
      <h:panelGroup> 
      <h:inputText styleClass="ltr" id="loadingDate" label="#{lbls.loadingDate}" value="#{requestWaggon.request.loadingDate}" required="true" readonly="true"> 
       <f:converter converterId="ir.khorasancustoms.DateConverter"/> 
      </h:inputText>    
      </h:panelGroup> 
      <h:message for="loadingDate" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.boundryStation}:"/>    
      <h:outputText value="#{requestWaggon.request.bountryStation}"/> 
      <h:message for="boundryStation" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value=""/> 
      <h:outputText value=""/> 
      <h:outputText value=""/> 

      <h:outputText value="#{lbls.confirmDate}:"/> 
      <h:panelGroup> 
      <h:inputText styleClass="date ltr" id="confirmDate" label="#{lbls.confirmDate}" value="#{requestWaggon.request.confirmDate}" required="true"> 
       <f:converter converterId="ir.khorasancustoms.DateConverter"/> 
      </h:inputText> 
      <input type="button" value="..." onclick="displayDatePicker('frmRequest:confirmDate', this);" class="datePicker"/> 
      </h:panelGroup> 
      <h:message for="confirmDate" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.confirm}:" styleClass="b"/> 
      <h:selectOneMenu value="#{requestWaggon.request.confirm}"> 
      <f:selectItem/> 
      <f:selectItems value="#{searchRequest.allConfirms}" var="confirm" itemLabel="#{searchRequest.confirmCaption(confirm)}" itemValue="#{confirm}"/> 
      </h:selectOneMenu> 
      <h:message for="confirm" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.description}:"/> 
      <h:inputText id="description" label="#{lbls.description}" value="#{requestWaggon.request.confirmDescription}" required="false" style="width: 350px;"/> 
      <h:message for="description" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      <h:outputText value="#{lbls.waggonType}:"/>    
      <h:selectOneMenu id="waggonType" label="#{lbls.waggonType}" value="#{requestWaggon.request.waggonType}" required="true"> 
      <f:selectItem/> 
      <f:selectItems value="#{requestWaggon.waggonTypes}"/> 
      <f:converter converterId="ir.khorasancustoms.CatalogValueFixedConverter"/> 
      </h:selectOneMenu>    
      <h:message for="waggonType" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/> 

      **<h:outputText value="#{lbls.specialWaggonNumber}:"/> 
      <h:panelGroup> 
      <h:inputText id="specialWaggonNumber" label="#{lbls.specialWaggonNumber}" binding="#{requestWaggon.waggonNumberComponent}" /> 
      <h:commandButton value="#{lbls.add}" action="#{requestWaggon.addWaggon}" immediate="true"/>   
      </h:panelGroup> 
      <h:message for="specialWaggonNumber" infoClass="info" warnClass="warning" errorClass="error" fatalClass="fatal"/>** 

      <h:outputText value="#{lbls.waggons}:"/> 
      <h:dataTable value="#{requestWaggon.waggonsDataModel}" var="waggon" columnClasses="index,,action" styleClass="grid" headerClass="title" rowClasses="two,three,one"> 
      <h:column> 
       <f:facet name="header">#{lbls.index}</f:facet> 
       <h:outputText value="#{searchRequest.datamodel.rowIndex + 1}"/> 
      </h:column> 
      <h:column> 
       <f:facet name="header">#{lbls.number}</f:facet> 
       <h:outputText value="#{waggon.number}"/> 
      </h:column> 
      <h:column> 
      <f:facet name="header">#{lbls.action}</f:facet>    
       <h:commandLink action="delete"> 
       <h:graphicImage styleClass="nb" alt="#{lbls.delete}" title="#{lbls.delete}" library="img" name="delete.png"/> 
       <f:param name="id" value="#{waggon.id}"/> 
       </h:commandLink> 
      </h:column> 
      </h:dataTable> 

      <f:facet name="footer"> 
      <h:button outcome="searchrequest" value="#{lbls.cancel}" rendered="#{requestWaggon.id ne null}"/> 
      <h:commandButton action="#{requestWaggon.doNew}" value="#{lbls.new}" rendered="#{requestWaggon.request.id ne null}"/> 
      <h:commandButton action="#{requestWaggon.save}" value="#{lbls.ok}"/> 
      </f:facet> 
     </h:panelGrid> 
     <h:outputScript> 
      focusElement('frmRequest:confirmDate');    
     </h:outputScript> 
     </h:form> 

     <f:facet name="footer"> 
     <h:messages styleClass="boxMessages" layout="table" infoClass="infoBox" warnClass="warningBox" errorClass="errorBox" fatalClass="errorBox" globalOnly="true"/> 
     <h:link outcome="searchrequest" value="#{lbls.searchRequestWaggon}"/> 
     </f:facet> 
    </p:panel>  

    <p:panel rendered="#{current.hasLoggedIn() and !requestWaggon.isViewable()}"> 
     <h:panelGroup layout="block" styleClass="warningBox"> 
     <h:outputText value="#{app.accessDenied}" /> 
     </h:panelGroup> 
    </p:panel> 
    </ui:define> 

</ui:composition> 

@ManagedBean(name = "requestWaggon") 
@ViewScoped 
public class RequestWaggonBean { 
    //<editor-fold defaultstate="collapsed" desc="FIELDS"> 

    private Logger logger; 
    @ManagedProperty(value = "#{current}") 
    private CurrentSessionBean current; 
    private RequestWaggon request; 
    private Set<CatalogValue> weightUnits; 
    private Set<CatalogValue> countries; 
    private Set<CatalogValue> boundryStations; 
    private Set<CatalogValue> waggonTypes; 
    private Integer id; 
    @ManagedProperty(value = "#{searchRequest}") 
    private SearchRequestBean searchRequest; 
    private Integer newWaggonNumber; 
    private HtmlInputText waggonNumberComponent; 
    private DataModel<Waggon> waggonsDataModel; 
    //</editor-fold> 

    //<editor-fold defaultstate="collapsed" desc="CONSTRUCTORS"> 
    public RequestWaggonBean() { 
    logger = LogUtil.getLogger(RequestWaggonBean.class); 
    request = new RequestWaggon();  

    ExternalContext exContext = FacesContext.getCurrentInstance().getExternalContext(); 
    HttpServletRequest httpRequest = (HttpServletRequest) exContext.getRequest(); 
    String strId = httpRequest.getParameter("id"); 
    try { 
     id = Integer.parseInt(strId); 
    } catch (Exception ex) { 
     logger.fatal(ex); 
    } 
    } 

    @PostConstruct 
    public void init() { 
    request.setDate(current.getDate()); 

    SessionFactory factory = new Configuration().configure().buildSessionFactory(); 
    Session session = factory.openSession(); 
    ResourceBundle app = ResourceBundle.getBundle("application"); 
    try { 
     //session.beginTransaction(); 

     if (id != null) { 
     request = (RequestWaggon) session.get(RequestWaggon.class, id); 
     } 

     Query query = session.createQuery("from CatalogGroup as catalogGroup where catalogGroup.englishTitle = :englishTitle"); 
     query.setParameter("englishTitle", "WeightUnit"); 
     CatalogGroup weightUnit = (CatalogGroup) query.uniqueResult(); 
     weightUnits = weightUnit.getValues(); 

     query.setParameter("englishTitle", "Country"); 
     CatalogGroup country = (CatalogGroup) query.uniqueResult(); 
     countries = country.getValues(); 

     query.setParameter("englishTitle", "BoundryStation"); 
     CatalogGroup boundryStation = (CatalogGroup) query.uniqueResult(); 
     boundryStations = boundryStation.getValues(); 

     query.setParameter("englishTitle", "WaggonType"); 
     CatalogGroup waggonType = (CatalogGroup) query.uniqueResult(); 
     waggonTypes = waggonType.getValues(); 

     //session.getTransaction().commit(); 
    } catch (Exception ex) { 
     logger.fatal(ex); 
     Transaction tx = session.getTransaction(); 
     if (tx.isActive()) { 
     tx.rollback(); 
     } 
     String message = app.getString("databaseConnectionFailed"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, message, message)); 
    } finally { 
     session.close(); 
    } 

    Waggon[] arrayWaggons = new Waggon[request.getWaggons().size()]; 
    arrayWaggons = request.getWaggons().toArray(arrayWaggons); 
    waggonsDataModel = new ArrayDataModel<Waggon>(arrayWaggons); 
    } 
    //</editor-fold> 

    //<editor-fold defaultstate="collapsed" desc="METHODS"> 
    public void save() { 
    boolean canSave = false; 
    String cantSaveMessage = ""; 

    SessionFactory factory = new Configuration().configure().buildSessionFactory(); 
    Session session = factory.openSession(); 
    ResourceBundle app = ResourceBundle.getBundle("application"); 
    try { 
     session.beginTransaction(); 

     int number = 0; 
     if (request.getNumber() == null) { 
     number = RequestWaggon.nextNumber(); 
     } 

     if (request.getNumber() != null || number > 0) { 
     if (request.getNumber() == null) { 
      request.setNumber(number); 
      canSave = isInsertable(); 
      cantSaveMessage = app.getString("insertDenied"); 
     } else { 
      canSave = isEditable(); 
      cantSaveMessage = app.getString("editDenied"); 
     } 

     if (canSave) { 
      session.saveOrUpdate(request); 

      RequestWaggonHistory history = new RequestWaggonHistory(request, current.getUser(), number > 0 ? 'I' : 'U', current.getIP()); 
      session.save(history); 

      session.getTransaction().commit(); 

      String message = app.getString("savedSuccessfully"); 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message)); 
     } else { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, cantSaveMessage, cantSaveMessage)); 
     } 
     } else { 
     logger.fatal("Getting next number failed!"); 
     String message = app.getString("databaseConnectionFailed"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, message, message)); 
     } 
    } catch (Exception ex) { 
     logger.fatal(ex); 
     Transaction tx = session.getTransaction(); 
     if (tx.isActive()) { 
     tx.rollback(); 
     } 
     String message = app.getString("databaseConnectionFailed"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, message, message)); 
    } finally { 
     session.close(); 
    } 
    } 

    public void addWaggon(ValueChangeEvent event) {  
    ResourceBundle app = ResourceBundle.getBundle("application"); 
    String strNewWaggonNumber = event.getNewValue().toString(); 
    Integer newWaggonNumber = Integer.parseInt(strNewWaggonNumber); 
    if (newWaggonNumber == null || newWaggonNumber <= 0) { 
     String message = app.getString("EnterWaggonNumber"); 
     FacesContext.getCurrentInstance().addMessage("frmRequest:specialWaggonNumber", new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message)); 
    } else { 
     Waggon newWaggon = new Waggon(); 
     newWaggon.setNumber(newWaggonNumber); 
     request.getWaggons().add(newWaggon); 

     Waggon[] arrayWaggons = new Waggon[request.getWaggons().size()]; 
     arrayWaggons = request.getWaggons().toArray(arrayWaggons); 
     waggonsDataModel = new ArrayDataModel<Waggon>(arrayWaggons); 
    } 
    } 

    public boolean isViewable() { 
    return current.isViewable(); 
    } 

    public boolean isDeletable() { 
    return current.isDeletable() && request.getWaggons().isEmpty(); 
    } 

    public boolean isInsertable() { 
    return current.isInsertable(); 
    } 

    public boolean isEditable() { 
    return current.isEditable() && request.getConfirm() == null; 
    } 

    public void doNew() { 
    request = new RequestWaggon(); 
    request.setDate(current.getDate()); 
    } 

    public String delete() { 
    SessionFactory factory = new Configuration().configure().buildSessionFactory(); 
    Session session = factory.openSession(); 
    ResourceBundle app = ResourceBundle.getBundle("application"); 
    try { 
     session.beginTransaction(); 

     session.delete(request); 

     RequestWaggonHistory history = new RequestWaggonHistory(request, current.getUser(), 'D', current.getIP()); 
     session.save(history); 

     session.getTransaction().commit(); 

     searchRequest.search(); 
     String message = app.getString("deletedSuccessfully"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message)); 
    } catch (ConstraintViolationException ex) { 
     String message = app.getString("constraintViolation"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, message, message)); 
    } catch (Exception ex) { 
     logger.fatal(ex); 
     Transaction tx = session.getTransaction(); 
     if (tx.isActive()) { 
     tx.rollback(); 
     } 
     String message = app.getString("databaseConnectionFailed"); 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, message, message)); 
    } finally { 
     session.close(); 
    } 

    return "searchrequest"; 
    } 
    //</editor-fold> 

    //<editor-fold defaultstate="collapsed" desc="PROPERTIES"> 
    public RequestWaggon getRequest() { 
    return request; 
    } 

    public void setRequest(RequestWaggon requestWaggon) { 
    this.request = requestWaggon; 
    } 

    public CurrentSessionBean getCurrent() { 
    return current; 
    } 

    public void setCurrent(CurrentSessionBean current) { 
    this.current = current; 
    } 

    public Set<CatalogValue> getWeightUnits() { 
    return weightUnits; 
    } 

    public void setWeightUnits(Set<CatalogValue> weightUnits) { 
    this.weightUnits = weightUnits; 
    } 

    public Logger getLogger() { 
    return logger; 
    } 

    public void setLogger(Logger logger) { 
    this.logger = logger; 
    } 

    public Set<CatalogValue> getCountries() { 
    return countries; 
    } 

    public void setCountries(Set<CatalogValue> countries) { 
    this.countries = countries; 
    } 

    public Set<CatalogValue> getBoundryStations() { 
    return boundryStations; 
    } 

    public void setBoundryStations(Set<CatalogValue> boundryStations) { 
    this.boundryStations = boundryStations; 
    } 

    public Integer getId() { 
    return id; 
    } 

    public void setId(Integer id) { 
    this.id = id; 
    } 

    public SearchRequestBean getSearchRequest() { 
    return searchRequest; 
    } 

    public void setSearchRequest(SearchRequestBean searchRequest) { 
    this.searchRequest = searchRequest; 
    } 

    public Set<CatalogValue> getWaggonTypes() { 
    return waggonTypes; 
    } 

    public void setWaggonTypes(Set<CatalogValue> waggonTypes) { 
    this.waggonTypes = waggonTypes; 
    } 

    public Integer getNewWaggonNumber() { 
    return newWaggonNumber; 
    } 

    public void setNewWaggonNumber(Integer newWaggonNumber) { 
    this.newWaggonNumber = newWaggonNumber; 
    } 

    public DataModel<Waggon> getWaggonsDataModel() { 
    return waggonsDataModel; 
    } 

    public void setWaggonsDataModel(DataModel<Waggon> waggonsDataModel) { 
    this.waggonsDataModel = waggonsDataModel; 
    }  

    public HtmlInputText getWaggonNumberComponent() { 
    return waggonNumberComponent; 
    } 

    public void setWaggonNumberComponent(HtmlInputText waggonNumberComponent) { 
    this.waggonNumberComponent = waggonNumberComponent; 
    } 
    //</editor-fold> 
} 

回答

2

h:commandButton提交整個窗體和所有的元素將被驗證。您可以使用ajax進行部分提交。請嘗試以下操作:

爲您的數據表提供一個id值。所以,你可以從你的commandButton引用它:

<h:panelGroup id="tableWrapper"> 
<h:datatable id="mytable" value="#{requestWaggon.waggonsDataModel}" ..> 
     ... 
</h:datatable> 
</h:panelGroup> 

然後把一個< f:ajax>您的commandButton內。 renderexecute屬性必須包含您的數據表的標識;不需要immediate=true

<h:commandButton value="#{lbls.add}" action="#{requestWaggon.addWaggon}"> 
    <f:ajax render="tableWrapper" execute="mytable"/> 
</h:commandButton> 
+0

這是一個很好的解決方案,但在JSF中也有一些經典的(不是Ajax)解決方案。 – ehsun7b 2011-03-12 07:16:34