本文介绍了JSF2 + IceFaces 2-从ViewRoot检索UIComponent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难解决以下问题.我的问题很简单:我想用红色突出显示触发验证错误的表单字段.使用context.addMessage(...)行将错误消息正确放置在FacesContext中.

I've got hard time resolving the following. My problem is quite simple : I would like to highlight in red the forms fields that triggered validation errors. The error messages are placed correctly in the FacesContext using a context.addMessage(...) line.

我希望我的系统通用.所有带有消息的表单字段都将自动突出显示.

I'd like my system to be generic. All form fields having a message attached are automatically highlighted.

我在此站点上找到了这篇出色文章的链接: http://www.jroller.com/mert/entry/how_to_find_a_uicomponent

I've found on this site a link to this excellent article :http://www.jroller.com/mert/entry/how_to_find_a_uicomponent

有了它,我确实为RENDER_RESPONSE阶段实现了一个PhaseListener,它执行以下操作:

With it, I did implement a PhaseListener for the RENDER_RESPONSE phase, which do the following :

@Override
  public void beforePhase(PhaseEvent event) {
    // get context
    FacesContext context = event.getFacesContext();

    // iterate on all the clientIds which have messages
    Iterator<String> clientIdsWithMessages = context.getClientIdsWithMessages();
    while (clientIdsWithMessages.hasNext()) {

      // get the clientId for the field component
      String clientIdWithMessage = clientIdsWithMessages.next();
      // split on ":"
      String[] splitted = clientIdWithMessage.split(":");

      UIComponent component = findComponentInRoot(splitted[splitted.length - 1]);
      if (component != null) {
        Map<String, Object> attributes = component.getAttributes();

        if (attributes.containsKey("style")) {
          attributes.remove("style");
        }
        attributes.put("style", "background-color: #FFE1E1;");
      }
    }
  }

这几乎可以满足我的所有使用要求.

This perform perfectly well for almost all my usage.

现在,有些棘手的地方是我的某些表单具有这样的代码:

Now, where it becomes a bit tricky, is that some of my forms have such code :

<ice:dataTable id="revisionDocuments" value="#{agendaBean.agenda.revisionsDocuments}" var="revision">
    <ice:column>
        <ice:inputText value="#{revision.sequenceAdresse}" id="revisionSequenceAdresse" />
    </ice:column>
    ....

生成的表单有几行(对于versionsDocuments列表的每个对象一行),并且每个元素都有一个唯一的标识符(clientId),看起来像:

The generated form has several lines (one for each object of the revisionsDocuments list), and each element has a unique identifier (clientId) which looks like :

contentForm:revisionDocuments:0:revisionSequenceAdresse

对于每次迭代,将0更改为1、2,....因此,提供的用于从ViewRoot搜索UIComponent的代码无法正常工作.所有表单字段均具有相同的"id".更让我惊讶的是:它们在FacesContext中也具有相同的"clientId":

With 0 changed for 1, 2, ... for each iteration.Consequently, the code provided to search the UIComponent from ViewRoot does not work properly. All forms fields have the same "id". What surprise me more is : they have the same "clientId" in FacesContext too :

contentForm:revisionDocuments:revisionSequenceAdresse

在遍历树时,我看不到正确的表单域或其他任何表单域.

I cannot distinguish, while going through the tree, if I do see the right form field or any of the others.

有人暗示要解决这个问题吗?或提出其他建议来实现我所关注的领域?我不得不承认,我不太喜欢我的代码,我认为像我正在做的那样操纵viewRoot很脏,但是我无法找到更好的解决方案来对我的字段进行通用突出显示.

Does anyone have a hint to solve this ? Or another suggestion to implement the highlight of my fields ? I have to admit, I dont really like my code, I consider dirty to manipulate the viewRoot like I'm doing, but I could not figure out a better solution to have a generic highlight of my fields.

我正在JBOss AS 7.0.2.Final上运行带有JSF-Impl 2.1.1-b04的IceFaces 2.0.2.

I'm running IceFaces 2.0.2 with JSF-Impl 2.1.1-b04 on JBOss AS 7.0.2.Final.

预先感谢您的回答.最好的祝福,帕特里克

Thank you in advance for the answers.Best regards,Patrick

推荐答案

您应该在客户端应用它.您已经获得了带有消息的客户端ID的集合.一种方法是将这些信息传递给JavaScript,然后让它完成工作.您可以在本文中找到此类PhaseListener的示例:在JSF中设置焦点并突出显示.

You should apply this in the client side instead. You've got a collection of client IDs with messages. One of the ways is to pass this information to JavaScript and let it do the job. You can find an example of such a PhaseListener in this article: Set focus and highlight in JSF.

但是,从JSF 2.0开始,有另一种方法不需要PhaseListener.有一个新的隐式EL变量#{component},它引用 UIComponent 当前组件的实例.如果是 UIInput 组件,有一个 isValid() 方法.这使您可以执行以下操作:

Since JSF 2.0 there is however another way without the need for a PhaseListener. There's a new implicit EL variable, #{component} which refers to the UIComponent instance of the current component. In case of UIInput components, there's an isValid() method. This allows you to do something like:

<h:inputText styleClass="#{component.valid ? '' : 'error'}" />

在CSS文件中包含此内容

with this in a CSS file:

.error {
    background: #ffe1e1;
}

(是的,您也可以在style属性中执行此操作,但是将样式与标记混合在一起是一种较差的做法)

(yes, you can also do this in a style attribute, but mingling style with markup is a poor practice)

要对此进行抽象(这样您就不必在每个输入中都重复它),只需创建一个复合组件,例如<my:input>.

To abstract this away (so that you don't need to repeat it in every input), you can just create a composite component for this, something like <my:input>.

这篇关于JSF2 + IceFaces 2-从ViewRoot检索UIComponent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 05:49