0

我有一个带有输入字段的数据表。在提交表单时,我必须一起验证所有输入。验证没有问题,但是将 ui-state-error 放在无效字段上会带来麻烦。我尝试使用 UIViewRoot#findComponent(id) 确定组件,但此方法始终返回 NULL。我从萤火虫那里得到了“id”,所以我不明白出了什么问题???

我希望任何人都可以帮助我!

我的数据表:

                       <prime:dataTable id="dtSpielberichtErfassen2"
                          value="#{bsvttController.spielDetailListe}" var="dtSpiErf2"
                          selection="#{bsvttController.selectedSpielDetail}" selectionMode="single"
                          rowKey="#{dtSpiErf2.id}">

                          <prime:column style="width:55px">
                             <h:outputText value="#{dtSpiErf2.spielPaarung}" />
                          </prime:column>

                          <prime:column style="width:180px"
                             headerText="#{bsvttController.mannschaftHeim}">
                             <h:panelGrid id="pgSpiErf1"
                                columns="1" cellpadding="0" cellspacing="0"
                                styleClass="#{dtSpiErf2.saetzeGewonnen == 3 ? 'fett' : null}">
                                <h:outputText value="#{dtSpiErf2.posHeim1}" />
                                <h:outputText value="#{dtSpiErf2.posHeim2}" />
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:180px"
                             headerText="#{bsvttController.mannschaftGast}">
                             <h:panelGrid id="pgSpiErf2"
                                columns="1" cellpadding="0" cellspacing="0"
                                styleClass="#{dtSpiErf2.saetzeVerloren == 3 ? 'fett' : null}">
                                <h:outputText value="#{dtSpiErf2.posGast1}" />
                                <h:outputText value="#{dtSpiErf2.posGast2}" />
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:50px"
                             headerText="1. Satz">
                             <h:panelGrid columns="3" cellpadding="0" cellspacing="0">
                                <pe:inputNumber id="inG1" value="#{dtSpiErf2.satz1Gewonnen}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:right">
                                </pe:inputNumber>
                                <h:outputText value=":" />
                                <pe:inputNumber id="inV1" value="#{dtSpiErf2.satz1Verloren}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:left">
                                </pe:inputNumber>
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:50px"
                             headerText="2. Satz">
                             <h:panelGrid columns="3" cellpadding="0" cellspacing="0">
                                <pe:inputNumber id="inG2" value="#{dtSpiErf2.satz2Gewonnen}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:right">
                                </pe:inputNumber>
                                <h:outputText value=":" />
                                <pe:inputNumber id="inV2" value="#{dtSpiErf2.satz2Verloren}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:left">
                                </pe:inputNumber>
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:50px"
                             headerText="3. Satz">
                             <h:panelGrid columns="3" cellpadding="0" cellspacing="0">
                                <pe:inputNumber id="inG3" value="#{dtSpiErf2.satz3Gewonnen}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:right">
                                </pe:inputNumber>
                                <h:outputText value=":" />
                                <pe:inputNumber id="inV3" value="#{dtSpiErf2.satz3Verloren}"
                                   maxlength="2" decimalPlaces="0"
                                   style="width:20px; text-align:left">
                                </pe:inputNumber>
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:50px"
                             headerText="4. Satz">
                             <h:panelGrid columns="3" cellpadding="0" cellspacing="0">
                                <pe:inputNumber id="inG4" value="#{dtSpiErf2.satz4Gewonnen}"
                                   maxlength="2" decimalPlaces="0"
                                   disabled="#{bsvttController.disable2(dtSpiErf2, 4)}"
                                   style="width:20px; text-align:right">
                                </pe:inputNumber>
                                <h:outputText value=":" />
                                <pe:inputNumber id="inV4" value="#{dtSpiErf2.satz4Verloren}"
                                   maxlength="2" decimalPlaces="0"
                                   disabled="#{bsvttController.disable2(dtSpiErf2, 4)}"
                                   style="width:20px; text-align:left">
                                </pe:inputNumber>
                             </h:panelGrid>
                          </prime:column>

                          <prime:column style="width:50px"
                             headerText="5. Satz">
                             <h:panelGrid columns="3" cellpadding="0" cellspacing="0">
                                <pe:inputNumber id="inG5" value="#{dtSpiErf2.satz5Gewonnen}"
                                   maxlength="2" decimalPlaces="0"
                                   disabled="#{bsvttController.disable2(dtSpiErf2, 5)}"
                                   style="width:20px; text-align:right">
                                </pe:inputNumber>
                                <h:outputText value=":" />
                                <pe:inputNumber id="inV5" value="#{dtSpiErf2.satz5Verloren}"
                                   maxlength="2" decimalPlaces="0"
                                   disabled="#{bsvttController.disable2(dtSpiErf2, 5)}"
                                   style="width:20px; text-align:left">
                                </pe:inputNumber>
                             </h:panelGrid>
                          </prime:column>

                       </prime:dataTable>

我的验证方法的代码片段:

        // %1% - index of datatable row
        // %2% - identifying part of componet id
        String id = ":formBsvtt:caseUpdateSpielberichtErfassen:dtSpielberichtErfassen2:%1%:in%2%_input";
        int saetzeGesamtGewonnen = 0;
        int saetzeGesamtVerloren = 0;
        int spieleGesamtGewonnen = 0;
        int spieleGesamtVerloren = 0;
        FacesContext fc;
        FacesMessage fm;
        UIComponent uic;
        UIInput uii;
        //
        // Prüfung 1: Sätze korrekt? -> 11:n oder n:11 oder n+2:n(ab n=10)
        for (int i = 0; i < spielDetailListe.size(); i++)
        {
           SpielDetail sd = spielDetailListe.get(i);
           if (!istSatzende(sd.getSatz1Gewonnen(), sd.getSatz1Verloren()))
           {
              fc = FacesContext.getCurrentInstance();
              fm = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Je Satz sind mindestens 11 Punkte und eine Diffenrenz von 2 Punkten notwendig.", "");
              fc.addMessage("", fm);
              id = id.replace("%1%", String.valueOf(i)).replace("%2%", "G1");
              uic = fc.getViewRoot().findComponent(id);
              if (uic != null)
              {
                 uii = (UIInput) uic;
                 uii.setValid(false);
              }
              return false;
           }
        }
4

1 回答 1

1

如果您实现一个独立的验证器并在数据表中的输入组件上声明该验证器,您的工作将会更加清晰和顺畅。您正在尝试做的事情是不可维护的,并且不必要地将视图绑定到模型。我会建议你

  1. 将您的验证逻辑抽象为适当的Validator. 下面只是一个虚拟的 impl。

      @FacesValidator("myValidator")
      public class MyValidator implements Validator{
    
       public void validate(FacesContext context, UIComponent component,
        Object value) throws ValidatorException {
            for (int i = 0; i < spielDetailListe.size(); i++)
    {
       SpielDetail sd = spielDetailListe.get(i);
       if (!istSatzende(sd.getSatz1Gewonnen(), sd.getSatz1Verloren()))
       {
          fc = FacesContext.getCurrentInstance();
          fm = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                "Je Satz sind mindestens 11 Punkte und eine Diffenrenz von 2 Punkten notwendig.", "");
          fc.addMessage("", fm);
          id = id.replace("%1%", String.valueOf(i)).replace("%2%", "G1");
          uic = component.getClientId();
          if (uic != null)
          {
             uii = (UIInput) uic;
             uii.setValid(false);
          }
    
    }
    

    } }

  2. 在组件上定义验证器

    <pe:inputNumber id="inV1" validator="#{myValidator}" value="#{dtSpiErf2.satz1Verloren}"
                               maxlength="2" decimalPlaces="0"
                               style="width:20px; text-align:left">
    
  3. 将 a 附加<prime:message/>到组件并让 JSF 完成它的工作。造型和定位由你决定

    <prime:message for="inV1"/>
    
于 2013-01-24T17:11:55.153 回答