0

入力フィールドを持つデータテーブルがあります。フォームの送信時に、すべての入力をまとめて検証する必要があります。検証は問題ありませんが、無効なフィールドに ui-state-error を配置すると問題が発生します。UIViewRoot#findComponent(id) でコンポーネントを特定しようとしましたが、このメソッドは常に NULL を返します。firebugから「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。以下は単なるダミー実装です。

      @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. コンポーネントに をアタッチし、<prime:message/>JSF に任せます。スタイリングとポジショニングはあなた次第です

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