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

Posted

技术标签:

【中文标题】如何使用 JSF 显示/隐藏组件?【英文标题】:How can I show/hide component with JSF? 【发布时间】:2011-04-11 07:15:03 【问题描述】:

我目前正在尝试在 javascript 的帮助下做同样的事情,但没有成功。 我不能使用任何第三方库。

谢谢|阿比

【问题讨论】:

您想在页面生成期间显示/隐藏它,还是对已生成页面上的某些操作作出反应?第一个可以通过JSF标签的“rendered”属性来实现,后者可以通过JavaScript实现。 该组件在页面呈现时应该是不可见的,并且应该在用户单击图像时显示。如果你能告诉我 JS 的方法那就太好了! 如果您可以使用 JSF 2.0,<f:ajax> 标签将允许您轻松更新页面的一部分,而不是触发完整的页面刷新。 【参考方案1】:

您实际上可以在不使用 JavaScript 的情况下完成此 ,至少在 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>

【讨论】:

应该注意这使用 ajax 并且会创建额外的服务器请求。虽然有时这可能更可取,但我会选择基于 javascript 的解决方案 需要注意的是,如果您还想提交表单,则仅提交rendered = true 的输入字段(或此处为SelectOneMenus)。 为此,我必须将onchange="submit()" 添加到外部&lt;h:selectOneMenu&gt; 元素中,如下所示:***.com/a/18787995/2577705。 valueChangeListener 不是必需的,除非需要跟踪更改本身。【参考方案2】:

通常,您需要通过其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: working with component identifiers。

【讨论】:

完全同意@jake-long:您将 JS 与 JSF 混合在一起。尽管您可能会造成混乱,这不符合模块化开发的最佳实践。【参考方案3】:

您应该使用带有rendered 属性的&lt;h:panelGroup ...&gt; 标签。如果将true 设置为渲染,&lt;h:panelGroup ...&gt; 的内容将不会显示。您的 XHTML 文件应该是这样的:

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

UserBean.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;
    

【讨论】:

非常正确的想法,但是如果您希望能够动态显示/隐藏组件,则应该在 panelGroup 内部的组件上使用 render 属性,而不是在 panelGroup 本身上,如带有 AJAX 事件。如果您在 panelGroup 上使用 render 并且它的条件最初为 false,那么您在第一次尝试更新它时会收到错误,因为它在页面上不存在。【参考方案4】:

使用 h-namespace 中大多数(如果不是所有)标签上可用的“rendered”属性。

<h:outputText value="Hi George" rendered="#Person.name == 'George'" />

【讨论】:

这是迄今为止最简单、最好的方法。感谢您的回答。【参考方案5】:

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

private boolean switchComponents;

public boolean isSwitchComponents() 
    return switchComponents;


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

当开关为真时,将显示一组组件,当为假时,将显示另一组。

 <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 事件中,我们渲染组件根。因为一开始没有渲染的组件不能是re-rendered on the ajax event。

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

【讨论】:

【参考方案6】:

检查下面的代码。 这是下拉菜单。在此,如果我们选择其他,则文本框将显示,否则文本框将隐藏。

function show_txt(arg,arg1)

if(document.getElementById(arg).value=='other')

document.getElementById(arg1).style.display="block";
document.getElementById(arg).style.display="none";

else

document.getElementById(arg).style.display="block";
document.getElementById(arg1).style.display="none";


The HTML code here :

<select id="arg" onChange="show_txt('arg','arg1');">
<option>yes</option>
<option>No</option>
<option>Other</option>
</select>
<input type="text" id="arg1" style="display:none;">

或者你可以查看这个链接 click here

【讨论】:

这是 HTML + JS,也适用于我的情况,但我在使用 JSF 时遇到问题。 @abhi 如果你想点击图片然后显示组件然后给图片一个 id 并在 IMG 标签上使用 onClick 事件 谢谢 Ricky,但这就是我正在做的,对我不起作用。当我点击图片时没有任何反应!

以上是关于如何使用 JSF 显示/隐藏组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSF 组件中显示预览文本?

JSF 隐藏和显示

JSF / PrimeFaces - 如何显示自定义验证器的消息,但不显示同一组件上的必需验证

在 JSF 1.2 中显示或隐藏 HTML DIV

如果 jsf 数据表为空,如何显示消息?

如何在 JSF 组件中监控异步/后台线程状态并获取通知