【问题标题】:How to create tabs - Jquery or JSF如何创建选项卡 - Jquery 或 JSF
【发布时间】:2012-04-23 17:28:00
【问题描述】:

我想创建带有标签的 JSF 页面。像this 这样的东西。但我想知道如果我选择使用 Jquery 来执行此操作,我可以实现延迟加载 - 当我单击 JSF 页面上的选项卡时,会在打开选项卡时生成内容。是否可以在纯 JSF 中实现选项卡的延迟加载?而且我想在这两种情况下我都可以轻松实现 AJAX。

最好的祝福

【问题讨论】:

    标签: java jquery jsf jsf-2


    【解决方案1】:

    Primefaces Tabview 组件支持延迟加载。

    来自展示的引述:

    选项卡内容也可以使用 ajax 延迟加载,当动态时 属性设置为“true”只有活动选项卡的内容将是 呈现并单击惰性选项卡将获取选项卡内容 阿贾克斯。这种行为对于节省带宽和减小页面大小很方便 在处理具有大量内容的选项卡时。​​p>

    展示中的快速示例:

    <h:form id="form">  
        <p:tabView id="tabView" dynamic="true" cache="true"> 
          // tabs
        </p:tabView>
    </h:form>
    

    cache 属性用于防止在选项卡之间切换时 ajax 重新加载选项卡内容。

    【讨论】:

    • 是的,这是一个可能的解决方案。但是用纯 JSF 能达到同样的效果吗?
    • 没有。你至少需要一些额外的 javascript 和 css。
    • 好的,我可以将 JQuery 与 JSF 和延迟加载一起使用吗?这两种解决方案中的哪一种将需要更少的资源。例如,我将有 8 个选项卡的 JSF 页面。每个选项卡都会有带有分页等的 JSF 数据表。两者中哪一个更适合多行代码的 JSF 页面?
    • 我不知道。我(还)对 jQuery 不是很有经验。
    【解决方案2】:

    用 jQuery UI 实现一个 ajax 选项卡根本不是问题。

    查看jQuery Tabs with ajax here的文档并点击“查看源代码”找到你需要的代码。

    【讨论】:

      【解决方案3】:

      您可以查看 Core Java Server Faces third edition 第 339 页一书,了解如何使用 h:panelGrid 实现简单的选项卡。

      输出是这样的:

      这是书中的代码示例:

      ...
      <h:form>
      <h:panelGrid styleClass="tabbedPane" columnClasses="displayPanel">
      <!-- Tabs -->
      <f:facet name="header">
      <h:panelGrid columns="4" styleClass="tabbedPaneHeader">
      <h:commandLink tabindex="1"
      title="#{msgs.jeffersonTooltip}"
      styleClass="#{tp.jeffersonStyle}"
      actionListener="#{tp.jeffersonAction}">
      #{msgs.jeffersonTab}
      </h:commandLink>
      ...
      </h:panelGrid>
      </f:facet>
      <!-- Tabbed pane content -->
      <ui:include src="washington.xhtml" />
      <ui:include src="roosevelt.xhtml" />
      <ui:include src="lincoln.xhtml" />
      <ui:include src="jefferson.xhtml" />
      </h:panelGrid>
      </h:form>
      ...
      

      这是描述:

      The tabbed pane is implemented with h:panelGrid. Because we do not specify
      the columns attribute, the panel has one column. The panel’s header—defined
      with an f:facet tag—contains the tabs, which are implemented with another
      h:panelGrid that contains h:commandLink tags for each tab. The only row in the panel
      contains the content associated with the selected tab.
      When a user selects a tab, the associated action listener for the command link is
      invoked and modifies the data stored in the backing bean. Because we use a
      different CSS style for the selected tab, the styleClass attribute of each h:commandLink
      tag is pulled from the backing bean with a value reference expression.
      As you can see from the top picture in Figure 8–11, we have used the title
      attribute to associate a tooltip with each tab. Another accessibility feature is the
      ability to move from one tab to another with the keyboard instead of the
      mouse. We implemented that feature by specifying the tabindex attribute for
      each h:commandLink.
      The content associated with each tab is statically included with the JSP include
      directive. For our application, that content is a picture and some text, but
      you could modify the included JSF pages to contain any set of appropriate
      components. Notice that even though all the JSF pages representing content are
      included, only the content associated with the current tab is rendered. That is
      achieved with the rendered attribute—for example, jefferson.xhtml looks like this:
      Putting It All Together
      <h:panelGrid columns="2" columnClasses="presidentDiscussionColumn"
      rendered="#{tp.jeffersonCurrent}">
      <h:graphicImage value="/images/jefferson.jpg"/>
      <span class="tabbedPaneContent">"#{msgs.jeffersonDiscussion}"</span>
      </h:panelGrid>
      Figure 8–12 shows the directory structure for the tabbed pane application and
      Listings 8–14 through 8–17 show the most important files.
      

      不幸的是,我不知道如何在这段代码中添加延迟加载和 AJAX 支持。

      【讨论】:

        【解决方案4】:

        注意:如果您希望标签 bean 成为会话范围,请阅读答案底部的说明...

        由于您不想使用任何第三方库,这里是一个 PureJSF + jQuery 示例

        JSF + Jquery + Ajax 延迟加载 + 查看 Scope Bean 示例...

        B.T.W 这是它最终的样子:

        当您单击每个选项卡时,您可以查看 Web 服务器控制台以查看 @PostConstruct@PreDestroy 的打印输出...

        选项卡的内容 - xhtml 页面及其 bean 将在选项卡单击时加载(延迟加载),并在单击其他选项卡时销毁,

        我建议你创建一个新项目并慢慢将所有文件放入其中并开始播放并查看它...它 100% 工作,但我放置了一些打印输出只是为了看看它真的工作...... .

        这个例子非常简单直接......

        首先转到jQueryUI and download it(1.8.18)

        并将jquery-1.7.1_.min.jsjquery-ui-1.8.18.custom.min.js 放入WebContent\resources\jsjquery-ui-1.8.18.custom.cssWebContent\resources\css

        现在到其他文件...

        myTabs.xhtml

        <!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:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:c="http://java.sun.com/jsp/jstl/core">
        <h:head>
         <h:outputScript library="js" name="jquery-1.7.1_.min.js" target="head" />
         <h:outputScript library="js" name="jquery-ui-1.8.18.custom.min.js" target="head" />
         <h:outputStylesheet library="css" name="jquery-ui-1.8.18.custom.css" target="head"     />
         <h:outputScript library="js" name="mytabs.js" target="head" />
        </h:head>
        <h:body>
        
        <f:view>
            <h:form prependId="false">
                <h:panelGroup id="tabs" layout="block">
                    <ul>
                        <c:forEach items="#{myTabs.tabs}" var="tab">
                            <li><a href="##{tab.tabid}" onclick="$('#button_#{tab.tabid}').click()">#{tab.tabid}</a></li>
                            <h:commandButton id="button_#{tab.tabid}" value="TabClick" action="#{myTabs.switchPages(tab.tabid)}" style="display:none">
                                <f:ajax render="tabs"></f:ajax>
                            </h:commandButton>  
                        </c:forEach>
                    </ul>
        
                    <c:forEach items="#{myTabs.tabs}" var="tab">
                        <h:panelGroup id="#{tab.tabid}" layout="block" rendered="#{tab.tabid eq myTabs.selectedTab}">
                            <ui:include src="#{tab.tabfilename}"></ui:include>
                        </h:panelGroup>
                    </c:forEach>
                </h:panelGroup>
            </h:form>
        </f:view>
        </h:body>
        </html>
        

        MyTabs.java

        package pack;
        
        import java.util.ArrayList;
        import java.util.List;
        
        import javax.annotation.PostConstruct;
        import javax.faces.bean.ManagedBean;
        import javax.faces.bean.SessionScoped;
        
        @ManagedBean
        @SessionScoped
        public class MyTabs{
        
        @PostConstruct
        public void init(){
            tabs = new ArrayList<MyTabObject>();
            tabs.add(new MyTabObject("tab1.xhtml", "tab1"));
            tabs.add(new MyTabObject("tab2.xhtml", "tab2"));
            tabs.add(new MyTabObject("tab3.xhtml", "tab3"));
        
        }
        String selectedTab="tab1";
        
        public String getSelectedTab() {
            return selectedTab;
        }
        
        public void setSelectedTab(String selectedTab) {
            this.selectedTab = selectedTab;
        }
        
        public String switchPages(String selTab) {
            selectedTab = selTab;
            return "myTabs.xhtml";
        }
        
        
        List<MyTabObject> tabs;
        
        
        public List<MyTabObject> getTabs() {
            return tabs;
        }
        
        public void setTabs(List<MyTabObject> tabs) {
            this.tabs = tabs;
        }
        
        
        }
        

        MyTabObject

        package pack;
        
        
        
        public class MyTabObject{
        
        
        String tabfilename;
        String tabid;
        public String getTabfilename() {
            return tabfilename;
        }
        public void setTabfilename(String tabfilename) {
            this.tabfilename = tabfilename;
        }
        public String getTabid() {
            return tabid;
        }
        public void setTabid(String tabid) {
            this.tabid = tabid;
        }
        public MyTabObject(String tabfilename, String tabid) {
            super();
            this.tabfilename = tabfilename;
            this.tabid = tabid;
        }
        
        }
        

        Tab1Page,(Tab2Page和Tab3Page完全一样,只是把所有地方的数字都改了)

        package pack;
        
        import java.io.Serializable;
        import java.text.Format;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        
        import javax.annotation.PostConstruct;
        import javax.annotation.PreDestroy;
        import javax.faces.bean.ManagedBean;
        import javax.faces.bean.ViewScoped;
        
        @ManagedBean
        @ViewScoped
        public class Tab1Page implements Serializable{
        
        /**
         * 
         */
        private static final long serialVersionUID = 254415216070877770L;
        // Constants
        public final static String hashKey = "tab1PageTab";
        public String actionString = "";
        
        @PostConstruct
        public void post(){
          Format formatter;
          Date date = new Date();
        
          // Time formate 01:12:53 AM
          formatter = new SimpleDateFormat("hh:mm:ss a");
          tabName = formatter.format(date);
            System.out.println("Tab1Page\t"+tabName+"\t@PostConstruct...");
        }
        
        @PreDestroy
        public void destroy(){
          Format formatter;
          Date date = new Date();
        
          // Time formate 01:12:53 AM
          formatter = new SimpleDateFormat("hh:mm:ss a");
          tabName = formatter.format(date);
            System.out.println("Tab1Page\t"+tabName+"\t@PreDestroy...");
        }
        
        
        String tabName;
        
        public String getTabName() {
            return this.getClass().getName().substring(this.getClass().getName().lastIndexOf("."))+"\t"+tabName;
        }
        public void setTabName(String tabName) {
            this.tabName = tabName;
        }
        
        public String getActionString() {
            return actionString;
        }
        
        public void setActionString(String actionString) {
            this.actionString = actionString;
        }
        
        }
        

        tab1.xhtml(tab2.xhtml 和 tab3.xhtml 完全一样 - 只是替换数字)

        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <ui:composition xmlns="http://www.w3.org/1999/xhtml" 
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html" 
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:c="http://java.sun.com/jsp/jstl/core">
        
        <h:panelGroup>
            <h:form>
                <h:outputText value="#{tab1Page.tabName}" />
            </h:form>
        </h:panelGroup>
        </ui:composition>
        

        到最后一个文件

        mytabs.js(将其放在 WebContent\resources\js 中)

        $(document).ready(function () { 
            $("#tabs").tabs();
        });
        
        $(window).load(function() {
            jsf.ajax.addOnEvent(function (data) {
                if (data.status === "success") {
                        $("#tabs").tabs();
                }
            });
        });
        

        为了使用 Session Scope Beans:

        MyTabs.java 中的方法switchPages 应该是void 并且不返回任何东西,像这样

            public void switchPages(String selTab) {
            selectedTab = selTab;
        }
        

        【讨论】:

        • 很好的例子。谢谢你的好答案。查看“Core Java Server faces”一书,我看到可以在纯 JSF 中创建选项卡。但是是否可以使用延迟加载和 AJAX 创建 JSF 选项卡?
        • @PeterPenzov 没试过......这就是你使用纯 JSF & Jquery & Ajax 延迟加载的方法
        • @PeterPenzov 我的解决方案不是完全符合您的要求吗?
        • 我想问你一件事。这是“Core Java Server Faces”一书中的代码,它展示了如何创建选项卡。 2shared.com/file/YUSB70Ro/tabbedpane.html 能不能看看能不能加个Ajax支持和延迟加载?
        • @PeterPenzov 明天将对其进行调查...不知道该示例与延迟加载的差距有多大...(如果有的话),您尝试过我的示例吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多