我有一个带输入字段的数据表。在表单提交上,我必须一起验证所有输入。验证没有问题,但是在无效字段上放置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;
}
}
答案 0 :(得分: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);
}
}
} }
在组件上定义验证器
<pe:inputNumber id="inV1" validator="#{myValidator}" value="#{dtSpiErf2.satz1Verloren}"
maxlength="2" decimalPlaces="0"
style="width:20px; text-align:left">
将<prime:message/>
附加到组件并让JSF执行此操作。造型和定位取决于您
<prime:message for="inV1"/>