如何在 JSF 2.0 (Sun Mojarra) 中获取选项卡式窗格组件
我现在正在学习/使用 JSF 2.0 (Sun Mojarra),我希望在我的 web 应用中有一个选项卡式窗格(单个选项卡可以命名为 General、Detail1、Detail2...).
我如何实现这一目标?到目前为止,我还没有找到任何文档:(
解决方案其他人已经暗示过:Mojarra 是一个基本 JSF 实现.它提供了最少的强制性组件集,以涵盖大多数现有的 HTML 元素(表单、输入字段和表格).由于 HTML 没有在单个元素中提供选项卡式面板,因此基本的 JSF 实现也不会这样做.
选项卡式面板基本上是一堆链接(或按钮)和面板,它们可以切换为隐藏/可见.为了表示链接,您通常使用 HTML <a>
元素.为了表示面板,您通常使用 HTML <div>
元素.要切换显示/隐藏,基本上有两种方法:
打印每个面板以响应,但使用 CSS
display: none
隐藏所有其他面板,并使用 JavaScript 通过将新面板设置为display: block
和旧面板到display: none
.或者,有条件地将请求的面板打印到响应中.可以通过链接(或按钮)中的请求参数来确定请求了哪个面板.
这是方式 1 的 basic copy'n'paste'n'runnable 示例:
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"><h:头><title>SO 问题 3491969</title><script src="http://code.jquery.com/jquery-latest.min.js"></script><脚本>$(文档).ready(函数() {$('#tabs a').click(function() {$('#panels').children().hide();$($(this).attr('href')).show();});});</脚本><风格>#tabs li { 列表样式类型:无;显示:内联;边框:1px纯黑色;}#panels { 宽度:600px;高度:400px;边框:1px纯黑色;}.hide { 显示:无;}</风格></h:head><h:body><ul id="标签"><li><a href="#panel1">panel1</a></li><li><a href="#panel2">panel2</a></li><li><a href="#panel3">panel3</a></li></ul><div id="面板"><div id="panel1">panel1 内容</div><div id="panel2" class="hide">panel2 内容</div><div id="panel3" class="hide">panel3 内容</div></div></h:身体></html>
您当然可以将 <a>
替换为 <h:outputLink>
和 <div>
替换为 <h:panelGroup layout="block">
等等,但只要您不需要将它与支持 bean 和/或 JSF 组件树绑定,那么纯 HTML 就完美了也有效并且开销更少.
您只需输入 <ui:repeat>
即可根据某些列表动态"重复选项卡和面板.也不要忘记加入一个好的 CSS 镜头,让它看起来很美味.这基本上是大部分工作的所在.
毕竟这基本上也是那些 3rd 方组件库,如 PrimeFaces、RichFaces 和 IceFaces 正在做.它们都在一个组件中提供了所需的功能,该组件完成了所有重复和美观的工作.例如 PrimeFaces 有一个 <p:tabView>
,RichFaces 有一个 <rich:tabPanel>
、IceFaces 和 <ice:panelTabSet>
等等.p>
I am learning/using JSF 2.0 (Sun Mojarra) now and I want to have a tabbed pane in my webapp (single tabs could named be General, Detail1,Detail2,...).
How do I achieve this? I haven't found any documetation for this so far :(
解决方案Others have already hinted it: Mojarra is a basic JSF implementation. It offers the minimum set of mandatory components to cover the most of existing HTML elements (forms, input fields and tables). Since HTML does not offer a tabbed panel in a single element, the basic JSF implementation won't do that as well.
A tabbed panel is basically a bunch of links (or buttons) and panels which are to be toggled hidden/visible. To represent links, you usually use the HTML <a>
element. To represent panels, you usually use the HTML <div>
element. To toggle show/hide either there are basically 2 ways:
Print every panel to response, but hide all other panels using CSS
display: none
and use JavaScript to toggle the visiblity by setting the new panel todisplay: block
and the old panel todisplay: none
.Or, print the requested panel to the response conditionally. Which panel has been requested can be be determined by request parameters in the links (or buttons).
Here's a basic copy'n'paste'n'runnable example of way 1:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>SO question 3491969</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('#tabs a').click(function() {
$('#panels').children().hide();
$($(this).attr('href')).show();
});
});
</script>
<style>
#tabs li { list-style-type: none; display: inline; border: 1px solid black; }
#panels { width: 600px; height: 400px; border: 1px solid black; }
.hide { display: none; }
</style>
</h:head>
<h:body>
<ul id="tabs">
<li><a href="#panel1">panel1</a></li>
<li><a href="#panel2">panel2</a></li>
<li><a href="#panel3">panel3</a></li>
</ul>
<div id="panels">
<div id="panel1">panel1 content</div>
<div id="panel2" class="hide">panel2 content</div>
<div id="panel3" class="hide">panel3 content</div>
</div>
</h:body>
</html>
You can of course replace <a>
by <h:outputLink>
and <div>
by <h:panelGroup layout="block">
and so on, but as long as you don't need to bind it in the with the backing bean and/or JSF component tree, then just plain HTML is perfectly valid as well and has less overhead.
You just have to bring <ui:repeat>
in to repeat the tabs and the panels "dynamically" based on some list. Also don't forget to throw in a good shot of CSS to make it all look like tasty. This is basically where the most of the work goes in.
This is after all basically also what those 3rd party component libraries like PrimeFaces, RichFaces and IceFaces are doing. They all provide the desired functionality in a single component which does all the repeating and eye-candiness job. PrimeFaces for example has a <p:tabView>
, RichFaces a <rich:tabPanel>
, IceFaces an <ice:panelTabSet>
and so on.
相关文章