如何使用 JSF 显示/隐藏组件?

IT技术 java javascript jsf
2021-02-20 11:56:28

如何使用 JSF 显示/隐藏组件?我目前正在尝试在 javascript 的帮助下做同样的事情,但没有成功。我不能使用任何第三方库。

谢谢| 阿比

6个回答

实际上,您可以在没有JavaScript 的情况下仅使用 JSF 的rendered属性来完成此操作,方法是将要显示/隐藏的元素封装在本身可以重新呈现的组件中,例如 panelGroup,至少在 JSF2 中是这样。例如,以下 JSF 代码根据第三个下拉列表的值显示或隐藏两个下拉列表中的一个或两个。AJAX 事件用于更新显示:

<h:selectOneMenu value="#{workflowProcEditBean.performedBy}">
    <f:selectItem itemValue="O" itemLabel="Originator" />
    <f:selectItem itemValue="R" itemLabel="Role" />
    <f:selectItem itemValue="E" itemLabel="Employee" />
    <f:ajax event="change" execute="@this" render="perfbyselection" />
</h:selectOneMenu>
<h:panelGroup id="perfbyselection">
    <h:selectOneMenu id="performedbyroleid" value="#{workflowProcEditBean.performedByRoleID}"
                     rendered="#{workflowProcEditBean.performedBy eq 'R'}">
        <f:selectItem itemLabel="- Choose One -" itemValue="" />
        <f:selectItems value="#{workflowProcEditBean.roles}" />
    </h:selectOneMenu>
    <h:selectOneMenu id="performedbyempid" value="#{workflowProcEditBean.performedByEmpID}"
                     rendered="#{workflowProcEditBean.performedBy eq 'E'}">
        <f:selectItem itemLabel="- Choose One -" itemValue="" />
        <f:selectItems value="#{workflowProcEditBean.employees}" />
    </h:selectOneMenu>
</h:panelGroup>
应该注意的是,如果您还想提交表单,则只会提交带有 render = true 的输入字段(或这里的 SelectOneMenus)。
2021-04-21 11:56:28
为此,我必须添加onchange="submit()"到外部<h:selectOneMenu>元素,如下所示:stackoverflow.com/a/18787995/2577705valueChangeListener是没有必要的,除非需要跟踪的变化本身。
2021-05-05 11:56:28
应该注意的是,这使用了 ajax,并且会创建额外的服务器请求。虽然有时这可能更可取,但我会选择基于 javascript 的解决方案
2021-05-10 11:56:28

通常,您需要通过其clientId获得控件的句柄此示例使用带有请求范围绑定的 JSF2 Facelets 视图来获取其他控件的句柄:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
  <h:head><title>Show/Hide</title></h:head>
  <h:body>
    <h:form>
      <h:button value="toggle"
               onclick="toggle('#{requestScope.foo.clientId}'); return false;" />
      <h:inputText binding="#{requestScope.foo}" id="x" style="display: block" />
    </h:form>
    <script type="text/javascript">
      function toggle(id) {
        var element = document.getElementById(id);
        if(element.style.display == 'block') {
          element.style.display = 'none';
        } else {
          element.style.display = 'block'
        }
      }
    </script>
  </h:body>
</html>

具体如何执行取决于您使用的 JSF 版本。有关较旧的 JSF 版本,请参阅此博客文章:JSF:使用组件标识符

完全同意@jake-long:您将 JS 与 JSF 混合使用。尽管您可能会造成混乱,这不符合module化开发的最佳实践。
2021-05-10 11:56:28

您应该使用<h:panelGroup ...>带有属性的标签rendered如果设置true为渲染,<h:panelGroup ...>则不会显示的内容你的 XHTML 文件应该是这样的:

<h:panelGroup rendered="#{userBean.showPassword}">
    <h:outputText id="password" value="#{userBean.password}"/>
</h:panelGroup>

用户Bean.java:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class UserBean implements Serializable{
    private boolean showPassword = false;
    private String password = "";

    public boolean isShowPassword(){
        return showPassword;
    }
    public void setPassword(password){
        this.password = password;
    }
    public String getPassword(){
        return this.password;
    }
}
几乎是正确的想法,但是如果您希望能够像 AJAX 事件一样动态显示/隐藏组件,则应在 panelGroup 内部的组件上使用渲染属性,而不是在 panelGroup 本身上。如果在 panelGroup 上使用 render 并且其条件最初为 false,则第一次尝试更新它时会出现错误,因为它在页面上不存在。
2021-05-09 11:56:28

使用在 h 命名空间中的大多数(如果不是全部)标签上可用的“rendered”属性。

<h:outputText value="Hi George" rendered="#{Person.name == 'George'}" />
这是迄今为止最简单和最好的方法。谢谢你的回答。
2021-04-25 11:56:28

一个明显的解决方案是使用 javascript(不是 JSF)。要通过 JSF 实现这一点,您应该使用 AJAX。在这个例子中,我使用一个单选按钮组来显示和隐藏两组组件。在后台 bean 中,我定义了一个布尔开关。

private boolean switchComponents;

public boolean isSwitchComponents() {
    return switchComponents;
}

public void setSwitchComponents(boolean switchComponents) {
    this.switchComponents = switchComponents;
}

当 switch 为 true 时,将显示一组组件,当它为 false 时,将显示另一组组件。

 <h:selectOneRadio value="#{backbean.switchValue}">
   <f:selectItem itemLabel="showComponentSetOne" itemValue='true'/>
   <f:selectItem itemLabel="showComponentSetTwo" itemValue='false'/>
   <f:ajax event="change" execute="@this" render="componentsRoot"/>
 </h:selectOneRadio>


<H:panelGroup id="componentsRoot">
     <h:panelGroup rendered="#{backbean.switchValue}">
       <!--switchValue to be shown on switch value == true-->
     </h:panelGroup>

   <h:panelGroup rendered="#{!backbean.switchValue}">
      <!--switchValue to be shown on switch value == false-->
   </h:panelGroup>
</H:panelGroup>

注意:在 ajax 事件中,我们渲染组件根。因为首先未呈现的组件无法在ajax 事件上重新呈现

另请注意,如果“componentsRoot”和单选按钮位于不同的组件层次结构下。您应该从根(形式根)引用它。