Primefaces设置了bean的焦点

时间:2018-03-05 14:00:52

标签: jsf primefaces

如果我想将焦点设置到无法验证的字段。我可以使用<p:focus context='@form'/>轻松实现这个简单的案例。但我的问题是,并非所有验证都可以在前端执行。例如,我希望用户输入用户名,当用户提交表单时,bean将检查数据库是否已存在用户名,如果存在,则将错误消息设置为该字段并将焦点设置为该字段。在这种情况下,<p:focus />标记不再起作用,因为它实际上已经通过了前端验证。

我找到this回答并尝试实施它,我会说它只能部分工作。为什么?因为如果通过为bean声明变量来手动设置bean的焦点,它将覆盖<p:focus context='@form'/>标记。当此焦点标记失去其功能时,如果有任何前端验证失败,它将不再将焦点带到该特定字段。

我尝试过使用widgetVar来执行焦点。我为我的字段声明了一个widgetVar名称,比如widgetVar='username',在托管bean中,我使用以下代码来关注它:

RequestContext.getCurrentInstance().execute("PF('username').focus()");

不幸的是,它不起作用。不确定execute()是否以这种方式工作或者语句有问题。对不起我的英语不好,任何帮助或建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

PrimeFaces 6.3及以上

正如评论中所提到的,PrimeFaces class

中提供了一种实用工具方法
PrimeFaces.current().focus(String expression)

表达式相对于view root或:

PrimeFaces.current().focus(String expression, UIComponent base)

其中表达式相对于提供的基本组件。

在PrimeFaces 6.3之前

只需检查PrimeFaces在focus renderer中执行的操作:

ResponseWriter writer = context.getResponseWriter();
UIComponent forComponent = SearchExpressionFacade.resolveComponent(
        context, focus, focus.getFor());

String clientId = forComponent.getClientId(context);

writer.write("$(function(){");
writer.write("PrimeFaces.focus('" + clientId + "');");
writer.write("});");

您可以在动作中执行相同的操作:

public void focus(String expression) {
  FacesContext context = FacesContext.getCurrentInstance();
  UIComponent forComponent = SearchExpressionFacade.resolveComponent(
    context,
    UIComponent.getCurrentComponent(context),
    expression
  );
  String clientId = forComponent.getClientId();
  RequestContext.getCurrentInstance().execute("PrimeFaces.focus('" + clientId + "');");
}

请注意,我使用触发操作的命令按钮作为搜索表达式的来源,并且您在这里不需要$(function(){...}

您唯一需要做的是,不要将clientId作为操作方法的参数,而是创建代码以确定应该获得焦点的组件。

使用XHTML进行测试:

<h:form id="main">
  <p:inputText id="text1"/>
  <p:inputText id="text2"/>
  <p:commandButton value="Focus 1" action="#{myBean.focus('text1')}"/>
  <p:commandButton value="Focus 2" action="#{myBean.focus('text2')}"/>
  <p:commandButton value="Form" action="#{myBean.focus('@form')}"/>
</h:form>