如何使用 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()"
添加到外部<h:selectOneMenu>
元素中,如下所示:***.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
属性的<h:panelGroup ...>
标签。如果将true
设置为渲染,<h:panelGroup ...>
的内容将不会显示。您的 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 显示/隐藏组件?的主要内容,如果未能解决你的问题,请参考以下文章