1

问题

我正在尝试在 jsf 1.2 中使用表单验证。我有一个包含两个输入文本字段行的表单。

我输入两行数据,一个坏单元格,如下所示:

| :) | :/ |
| :) | :) |

验证器每行调用一次,但会检查两个字段。每个UIInput验证失败的都被添加到失败的列表中UIComponent。提交动作的方法终于开始运行了。首先它会恢复所有保存的样式。然后它循环失败UIComponent的s。在循环内部,它保存当前样式,然后将样式设置为“badInput”。

但是当页面加载时,两个端单元格都具有“badInput”样式:

| :) | :/ |
| :) | :/ |

我的代码

这是我的验证器,托管 bean 上处理此页面的方法:

public void validateTime(FacesContext context, UIComponent component, Object value)
{
  UIInput out = (UIInput) component.findComponent("out");

  for (UIComponent uic : Arrays.asList(component, out))
  {
    String time = (String) ((UIInput)uic).getSubmittedValue();

    if (!StringToTime.isValid(time))
    {
      // mark that we found invalid times
      validTimes = false;

      // save the failed component
      // the click method will change the style during the render phase
      failedUics.add(uic);  // List<UIComponent>
      badComps.put(uic.getClientId(context), uic);  // Map<String, UIComponent>
    }
  }
}

这是输入字段表:

<h:dataTable binding="#{entryHandler.tableAttends}" value="#{entryHandler.attends}" var="range">
  <h:column>
    <div>
      <h:outputLabel>
        <h:outputText value="In: " />
        <h:inputText value="#{range.start}" id="in" validator="#{entryHandler.validateTime}" />
      </h:outputLabel>

      <h:outputLabel>
        <h:outputText value="Out: " />
        <h:inputText value="#{range.end}" id="out" />
      </h:outputLabel>

      <h:commandLink action="#{entryHandler.delAttend}" value="X" styleClass="removeTime" />
    </div>
  </h:column>
</h:dataTable>

我尝试通过以下两种方式应用错误的输入样式:

for (UIComponent target : failedUics)
{
  log.debug("target client id: " + target.getClientId(context));

  Map<String, Object> attr = target.getAttributes();

  // save the style before changing it
  String style = (String) attr.get("styleClass");
  originalStyle.put(target.getClientId(context), style);

  // add the badInput css class
  if (style == null) style = "";
  attr.put("styleClass", "badInput " + style);
}
failedUics = new ArrayList<UIComponent>();

第二个:

UIComponent root = context.getViewRoot();
for (String clientId : badComps.keySet())
{
  root.invokeOnComponent(context, clientId, new BadInputCallback(originalStyle));
}
badComps = new HashMap<String, UIComponent>();

这是回调函数:

private static class BadInputCallback implements ContextCallback
{
  private final Map<String, String> originalStyle;

  public BadInputCallback(Map<String, String> originalStyle)
  {
    this.originalStyle = originalStyle;
  }

  @Override
  public void invokeContextCallback(FacesContext context, UIComponent target)
  {
    Map<String, Object> attr = uic.getAttributes();

    // save the style before changing it
    String style = (String) attr.get("styleClass");
    originalStyle.put(target.getClientId(context), style);

    // add the badInput css class
    if (style == null) style = "";
    attr.put("styleClass", "badInput " + style);
  }
}
4

1 回答 1

1
于 2013-08-08T01:01:47.510 回答