change content layout in facelets template by adding url parameter - url

I have the following template file templateBase.xhtml:
<!--Normal SPA Layout-->
<c:if test="#{not MainActionBean.isLayoutTheme(param.theme)}">
<ui:insert name="pageHeader" />
<ui:insert name="content"/>
<ui:insert name="contentFooter"/>
</c:if>
<!--3 panel layout-->
<c:if test="#{MainActionBean.isLayoutTheme(param.theme)}">
<p:outputPanel id="templateBaseLayoutPanel" >
<p:layout widgetVar="panelLayout">
<p:layoutUnit position="west" id="westContentContainer">
<h:outputText value="Document List" />
<ui:include src="/common/Documents.xhtml" />
<br/>
<h:outputText value="Action formulary" />
<ui:insert name="actionSection"/>
</p:layoutUnit>
<p:layoutUnit position="center" id="centerContentContainer">
<ui:insert name="pageHeader" />
<ui:insert name="content"/>
<ui:insert name="contentFooter"/>
</p:layoutUnit>
<p:layoutUnit position="east" id="eastContentContainer">
East Panel Content
</p:layoutUnit>
</p:layout>
</p:outputPanel>
</c:if>
What I want to achieve is to change the current SPA layout to another with 3 columns when a given parameter with a specific value is added to the URL. In the SPA layout the "documents list" and "action formulary" are included into a subview in the "content" section of the template and in the 3 panel layout they should move to the west panel. Currently after adding the param the layout units are being rendered but not the ui:insert and ui:include of the west panel. There are no errors on logs or console and rendition of components is controlled with method "MainActionBean.isLayoutTheme(param.theme)" to prevent ID duplication.
I'd like to know if what I'm trying is even possible or if there is a better approach for this.
P.S: I've tried to summarise and simplify the xhtml structure as much as possible, if needed will post the whole of it.

Related

ui:include parameter passing does not work when remote page is included

I have a basic UI (index.html) that is divided into Header, Footer and Content. The content-page is either on the same (local.xhtml) server like the index.html or on another (remote.xhtml) server.
Including the pages and dynamically reloading them with ajax works pretty good. But parameter passing only works on the local content page. The parameter is retrieved of a Bean called Login which also is on the same server as the index.html.
index.xhtml (excerpt):
<h:panelGroup id="content" layout="block">
<ui:include src="#{contentLoader.page}" >
<ui:param name="userName" value="#{login.userName}" />
</ui:include>
</h:panelGroup>
<h:form>
<f:ajax render=":content">
<ul>
<li><h:commandLink value="include1"
action="#{contentLoader.LocalPage}" /></li>
<li><h:commandLink value="include2"
action="#{contentLoader.remotePage}" /></li>
</ul>
</f:ajax>
</h:form>
local.xhtml
<h:body>
<ui:composition>
<h:form id="form">
<h:outputText value= "Local Page. Parameter is: #{userName}"/>
</h:form>
</ui:composition>
</h:body>
remote.xhtml
<h:body>
<ui:composition>
<h:form id="form">
<h:outputText value= "Remote Page. Parameter is: #{userName}"/>
</h:form>
</ui:composition>
</h:body>
local.xhtml prints out: "Local Page. Parameter is: MyUser"
remote.xhtml only: "Remote Page. Parameter is: "
I am using Glassfish4 as WebServer and JSF2
Thank you. The hints in the comments solved my Problem. For now this works fine for me:
<iframe> was solving my problem. Parameter passing within URL and JSF works brilliant.
Just "including" the remote page with <iframe src="#{myBean.Url}"></iframe> and reading the parameter with JSF Function "#{param['param1']}"
{myBean.Url} return a String in this format: localhost:8680/MyServiceservice/faces/myPage.html?param1=value1 with value1 being the parameter I want to transfer.

How to refer to components located in a different ui:include

On a facelet composed with different ui:include, what would be the best way to refer to a component located in ui:composition 2 from ui:composition 1?
Example:
fileA.xhtml
<ui:composition>
<p:commandButton value="OK" action="#{bean.foo}" update=":componentToUpdate"/>
</ui:composition>
fileB.xhtml
<ui:composition>
<p:panel id="componentToUpdate">
// ...
</p:panel>
</ui:composition>
Here, I'm "hardcoding" the id, "componentToUpdate". I thought of using a parameter:
<ui:include src="fileA.xhtml" >
<ui:param name="myParam" value="myId"/>
</ui:include>
fileB.xhtml
<ui:composition>
<p:panel id="#{myId}">
// ...
</p:panel>
</ui:composition>
Would it be interesting to have a bean that maintains all of these ids?
Hope I'm clear enough, thanks.

Constructor of a viewScoped class invoked twice

I've been struggling with this for two days with no success and I think it's already time to ask for your help. But first of all, this is what I'm using:
JSF 2 Mojara 2.1.1
Primefaces 3.4.2
Netbeans 7.1.1
Tomcat 7.0.37
And now, the problem: I have a main page which is composed by several other pages using several <ui:include .. /> tags, like this:
<ui:composition template="/resources/templates/template1.xhtml">
<ui:define name="appData">
<p:panelGrid columns="1" id="contenidoAplicacion" styleClass="noborder">
<h:form id="fNewPerson">
<p:panel header="New employee" style="min-height:40em">
<ui:include src="./forms/personal.xhtml" />
<p:accordionPanel styleClass="noborder" activeIndex="3">
<p:tab id="tabSomeData" title="Identidad profesional" >
<ui:include src="./forms/formSomeData.xhtml" />
</p:tab>
....
....
</ui:define>
</ui:composition>
The personal.xhtm file looks like this:
<p:panelGrid>
<p:row>
<p:column >
<h:outputLabel value="Field1"/>
<p:inputText label="Field1" id="field1" value="#{dataBacking.selectedPerson.field1}" tabindex="1"
required="true" size="10" >
<f:convertNumber for="field1" integerOnly="true" groupingUsed="false"/>
</p:inputText>
<p:inputText id="field2" value="#{dataBacking.selectedPerson.field2}" tabindex="2" required="true" size="1" maxlength="1" >
<p:ajax event="keyup" listener="#{dataBacking.check}"
process="field1 field2" partialSubmit="true"
update="field1 field2 photo"/>
</p:inputText>
</p:column>
<p:column rowspan="5" >
<p:graphicImage id="photo" value="#{dataBacking.selectedPerson.photo}" width="90" />
</p:column>
</p:row>
...
</p:panelGrid>
The check() method in the dataBacking class is irrelevant because it only checks if the field1 and the field2 meet some rules and it works properly. The problem comes when the main page is loaded for the first time. In that case, the <p:ajax /> component in personal.xhtml doesn't work. I have to reload the page (simply by pressing the F5 key) and this time it works as it would be expected.
I've been changing some attributes of the component, but nothing seems to work. I really don't know what else to do. Any kind of help will be apreciated.
EDITED. After one more day, I think the problem has nothing to do with Primefaces ajax component, as the title of the question suggested. I've come to this conclusion through these two facts:
The behaviour with the <f:ajax .../> component remains the same.
I've figured out that the view relative to the first time I load the page is not persisted. I'll try to explain myself.
The DataBacking class has defined its scope as view so that the page can "see" all the attributes and methods during the time it's been shown to the user. However, I've noticed that the constructor is called twice: the first time the page is loaded (and then, none of the methods of the class are successfully invoked) and when I refresh the page. In this last case, the behaviour of both the page and the class is the expected one.

JSF 2 Prime Faces Navigation Using Menu and Panels

Hi there Im just learning JSF 2 using Primefaces.
I have a question regarding their Panel example. I would like to use the left panel as a placeholder for my Navigation Menu and the center panel for the contents/pages. Each time I click the menu the whole page gets refreshed, what I would like to accomplish is that when I click the menu only the center panel will load the corresponding page. Is this possible using primefaces or other techniques for jsf 2?
Below is the code I am using. Thanks in advance.
Thanks for your quick reply. I tried your suggestion but got some errors. Sorry Im really new to jsf2 and primefaces. Thanks in advance.
ERROR MESSAGE:
/homepage.xhtml #26,84 Tag Library supports namespace: http://primefaces.prime.com.tr/ui, but no tag was defined for name: menuItem
Below is my code for my view (homepage.xhtml)
<p:layout fullPage="true">
<p:layoutUnit position="top" height="75" header="Top" resizable="true" closable="true" collapsible="true">
<h:outputText value="North unit content." />
</p:layoutUnit>
<p:layoutUnit position="bottom" height="75" header="Bottom" resizable="true" closable="true" collapsible="true">
<h:outputText value="South unit content." />
</p:layoutUnit>
<p:layoutUnit position="left" width="250" header="Left" resizable="true" closable="true" collapsible="true">
<h:outputText value="West unit content." />
<p:menu type="plain">
<p:submenu label="Mail">
<p:menuItem actionListener="#{navBean.setPage('pageName')}" update="centerPanel" />
<p:menuitem value="Gmail" url="http://www.google.com" />
<p:menuitem value="Hotmail" url="http://www.hotmail.com" />
<p:menuitem value="Yahoo Mail" url="http://mail.yahoo.com" />
</p:submenu>
<p:submenu label="Videos">
<p:menuitem value="Youtube" url="http://www.youtube.com" />
<p:menuitem value="Break" url="http://www.break.com" />
<p:menuitem value="Metacafe" url="http://www.metacafe.com" />
</p:submenu>
<p:submenu label="Social Networks">
<p:menuitem value="Facebook" url="http://www.facebook.com" />
<p:menuitem value="MySpace" url="http://www.myspace.com" />
</p:submenu>
</p:menu></p:layoutUnit>
<p:layoutUnit position="center" id="centerPanel">
<h:include src="#{navBean.page}.xhtml" />
This is the center panel
</p:layoutUnit>
</p:layout>
This is my code for my bean NavBean.java
package somePackage;
import javax.faces.bean.*;
#ManagedBean
#SessionScoped
public class NavBean {
private String page = "login";
}
Something like this JSF dynamic include using Ajax request.
In your p:menuItem use action attribute instead of url, to make ajaxcal and in the center panel you can use h:include and change the value of the src attribute in h:include in the method in your backing bean. It can also be actionListener instead of action.
Managed bean -
#ManagedBean
#SessionScoped
public class NavBean {
private String page = "default";
//getter/setter for page
View -
<p:menuItem actionListener="#{navBean.setPage('pageName')}" update="centerPanel" />
//center panel with id="centerPanel"
<h:include src="#{navBean.page}.xhtml" />
You don't wan't to refresh page but make an ajaxcal, change the value page and update the center panel.

Java facelets dynamic loading and composite component attributes

Currently I'm trying to implement webpart technology with JavaServer Faces 2.0 with Facelets view technology for educational purposes. I have created facelet templates, facelet custom components and made a few facelet "template" clients. But in one thing I'm stuck. I can't dynamically load controls and put them cc:attributes.
If I have a page for example with static text or bind it with ManagedBean the property ui:include everything works well.
<ui:define name="right-column">
right-column asd
<h:link outcome="asdf" value="link_get">
<f:param name="aa" value="123" />
<f:param name="a" value="123 dd + 20" />
</h:link>
<h:commandLink action="asdf?faces-redirect=true" value="asdf">
<f:param name="aa" value="123" />
</h:commandLink><br />
<ui:include src="./resources/Controls/CategoryTree.xhtml"/><br />
This works even if I put src with MenageBean property.
<ui:include src="#{browseProducts.incudePath}"/>
</ui:define>
Here is my facelet control (data binding is inside this control within #{TreeBean.root}:
<!-- NO INTERFACE -->
<cc:interface>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<!-- This is a very simply scaffolding for Category Three Control.
-->
<p:tree value="#{TreeBean.root}" var="node"
expandAnim="FADE_IN" collapseAnim="FADE_OUT">
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
</cc:implementation>
But I have problem when ui:include points to a control with cc:attribute. I don't know how to initialize this attribute from backing bean and do "stuff".
For example I have this page:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./resources/layout/Template.xhtml"
xmlns:sc="http://java.sun.com/jsf/composite/Controls">
<ui:define name="right-column">
<sc:dummy ItemCount="10" />
<ui:include src="./resources/Controls/dummy.xhtml" />
</ui:define>
</ui:composition>
Here goes the composite control:
<cc:interface>
<cc:attribute name="ItemCount" required="true"
shortDescription="This attribute is meaningful " />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<!-- How to pass ItemCount to my dummy bean to create so many items in
list as ItemCount value -->
<ui:repeat value="#{dummy.dummyList}" var="dummyItem">
<h:outputText value="#{dummyItem}" />
</ui:repeat>
</cc:implementation>
And backing bean code:
public ArrayList<String> getDummyList() {
//Here I try to get dummy list work.
dummyList = new ArrayList<String>(getDummyCount());
for (int i=0;i< getDummyCount();i++){
dummyList.add(i + "" + i);
}
return dummyList;
}
How can this be done?
I think you have two problems:
calling a method with parameter from a composite component
specifying some parameter to an included page
For 1., since jsf 2, you could call the method directly, specifying the parameter (which should be part of method signature):
<ui:repeat value="#{dummy.getDummyList(cc.attrs.dummyCode)}" var="dummyItem">
<h:outputText value="#{dummyItem}" />
</ui:repeat>
But I suspect you are trying to use a backing for something that it isn't designed for. Maybe you'll be interested in writing backing java code for your composite component, which is different. It's difficult to master if you are a beginner, though. I'd first try to design my pages and bean interactions differently. I don't know which problem you are trying to solve, but at first look, this solution looks too complicated.
For 2., you should have a look at ui:param. A quick google search gives me this: http://www.jsfcentral.com/articles/facelets_3.html

Resources