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

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

谢谢|阿比

【问题讨论】:

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

标签: java javascript jsf


【解决方案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; 元素中,如下所示:stackoverflow.com/a/18787995/2577705valueChangeListener 不是必需的,除非需要跟踪更改本身。
【解决方案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,但这就是我正在做的,对我不起作用。当我点击图片时没有任何反应!
    猜你喜欢
    • 2011-06-12
    • 2014-05-03
    • 1970-01-01
    • 2014-07-31
    • 2013-05-04
    • 2011-08-31
    • 2014-03-30
    • 1970-01-01
    相关资源
    最近更新 更多