在我的xhtml中使用Template(jsf)之后,commandLink和CommandButton标记不会调用任何操作

时间:2014-04-10 08:25:50

标签: java html jsf templates jsf-2

我以下列方式使用了JSF模板:

TemplateHeader.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:f="http://xmlns.jcp.org/jsf/core"
   xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>TODO supply a title</title>
    <meta name="viewport" content="width=device-width"/>
</h:head>
     <h:body>

            <ui:composition>
                    <div></div>   
             </ui:composition>

      </h:body>
</html>

TemplateMenu.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:f="http://xmlns.jcp.org/jsf/core"
   xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>TODO supply a title</title>
    <meta name="viewport" content="width=device-width"/>
</h:head>
        <h:body>
            <ui:composition>
                <div></div>
            </ui:composition>
        </h:body>
</html>

TemplateContent.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:f="http://xmlns.jcp.org/jsf/core"
   xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    <title>TODO supply a title</title>
    <meta name="viewport" content="width=device-width"/>
</h:head>
<h:body>
    <ui:composition>
          <div></div>
    </ui:composition>
</h:body>
</html>    

TemplateFooter.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:f="http://xmlns.jcp.org/jsf/core"
   xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>TODO supply a title</title>
    <meta name="viewport" content="width=device-width"/>
</h:head>
<h:body>
    <ui:composition>
        <div></div>  
    </ui:composition> 
</h:body>
</html>

然后我将所有这些包含在一个完整的模板文件中:

CompleteTemplate.xhtml

 <html> // with all the necessary tags as above
  <h:head>
    <title>State Transport Department- Work Schedule</title>
    <meta name="viewport" content="width=device-width"/>
    <link  rel="stylesheet" type="text/css" href="../CSS/templateCSS.css"/>
 </h:head>

 <h:body style="with the reqd styles">

 <div style="css styles">

  <div style="">
 <ui:insert name="header">
                <ui:include src="/webpages/templates/TemplateHeader.xhtml"/>
            </ui:insert>

</div>

<div>
 <ui:insert name="menu">
                <ui:include src="/webpages/templates/TemplateMenu.xhtml"/>
            </ui:insert> 
</div>

<div>
  <ui:insert name="content">
                <ui:include src="/webpages/templates/TemplateContent.xhtml"/>
            </ui:insert>
</div>

<div>
 <ui:insert name="footer">
                <ui:include src="/webpages/templates/TemplateFooter.xhtml"/>
            </ui:insert> 
</div>

 </div>

 </h:body>
 </html>

然后我将此页面包含在我的主页中,例如:

Test.xhtml

 <html>
 <h:body>
    <h:form>
<ui:composition template="/webpages/templates/CompleteTemplate.xhtml">

            <ui:define name="menu">
      //override the previos wid menues etc
            </ui:define>

             <ui:define name="content"> 
 <h:commandLink id="allocateButton" value="Test Submit"
 action="#{myTaskBean.viewMyTask}"/> 

 <h:commandButton id="allocateButton" value="Test Submit"
 action="#{empDutySchedBean.testMethod}"/>
              </ui:define>

 </ui:composition>
         </h:form>
      </h:body>
   </html>

所有commandLinks和commandButttons都无法正常工作。用于菜单的普通html锚点。

对于CommandLink,我收到错误:

  

此链接已禁用,因为它未嵌套在JSF表单中。

对于CommandButton的

:源代码中的按钮名称不会呈现为内置的jsf,如 j_something ,并且它不会调用java方法。

有些人说我的模板方式存在问题。不过我觉得很好。

2 个答案:

答案 0 :(得分:2)

您以错误的方式进行模板操作,不需要在所有页面中设置<h:body><h:head>

您的完整结构应如下所示:

mainTemplate.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">
<f:view>
     <h:head>
         <ui:insert name="header">
                 <!-- so that each implementing page can set its own title -->
             <title></title>
         </ui:insert>
    </h:head>

    <h:body>
         <!-- if your menu is shared through all site, otherwise set it as ui:insert -->
         <ui:include src="menu.xhtml" />
         <ui:insert name="body"></ui:insert>
         <ui:insert name="footer"></ui:insert>
    </h:body>
</f:view>

现在您的表单页面将是:

test.xhtml

<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"
                template="mainTemplate.xhtml">
    <ui:define name="header">
        <title>Test Page</title>
    </ui:define>

    <ui:define name="body">
        <h:form id="myForm">
            <!-- your jsf inputs, commandbutton, etc... -->
        </h:form>
    </ui:define>

    <ui:define name="footer">
        <!-- include can come anywhere inside ui:define -->
        <ui:include src="testPageCustomFooter.xhtml" />
    </ui:define>

</ui:composition>

您当然可以拥有多个模板,但您的<ui:composition>可以通过template属性一次实施一个模板。 实施模板并不会强迫您ui:define所有ui:insert,这取决于您在每个特定网页中的需求。 另请注意test.xhtml您不能重写<html><h:head><h:body>,您可以直接在<ui:composition>内开始实施,以及任何内容外部<ui:define>无法在您的网页中展示。 希望这可以解决问题。

答案 1 :(得分:1)

JSF忽略ui:composition之外的所有内容。如果使用模板,则组件树是基于模板的内容构建的(在那里我看不到h:form)。 JSF仅使用模板从页面中使用ui:define内的部分。

因此,您的h:form未添加到组件树中。您必须将其添加到模板或ui:define内。