Creating master child concent in primefaces - jsf

I'm using Primefaces 3.5 + MOJARA 2.2.
I'm trying to create a Master child kind of environment where we have all applications listed in one Tab with command buttons. Each command button will open up another tab in the same parent window.
To achieve this i'm using dynamic tabs with iframe
<p:tabView value="#{bean.tabs} var="tab">
<p:tab title="#{tab.title}" closable="#{tab.closable}">
<iframe src="#{tab.content}" class="ui-widget" width="100%" height="900px"/>
</p:tab>
</p:tabView>
Here tabs is a List and Tab is a POJO.
class Tab{
private String title;
private String content;//URL
private boolean closable;
//GETTER SETTERS
}
in Backing bean i create a Tab where in show command buttons as below.
public class Bean{
private List<Tab> tabs;
...
public Bean(){
tabs = new ArrayList<Tab>();
Tab tab1 = new Tab("Applicaton","dispApplications.xhtml",false);
tabs.add ( tab1 );
}
}
dispApplications.xhtml
<h:form id="buttonForm">
<h:panelGrid columns="6" border="0">
<c:forEach var="dataItem" items="${bean.applications}">
<h:column>
<p:graphicImage value="/images/#{dataItem.icon}"/>
<p:commandButton binding="#{bean.cmdButton}"/>
</h:column>
</c:forEach>
</h:panelGrid>
</h:form>
Problems:
I'm able to show initial "Applications" Tab. However when i try to invoke each application i had to force reloading of the entire page to get the tabs loaded. This i'm doing cmdButton.setOnClick("parent.location.href = parent.location.href") for each commandButton which is bound to Bean.
I also created an inline processListener for cmdButton which creates an instance of "Tab" and adds it to tabs.
I want to avoid complete page reloading to show tabs.
I want to highlight the new tab that is added/opened recently..
Tabclose is always closing first tab no matter which tab i try closing. Online primefaces showcase shows very clean implementation but i guess this works in 4.0 and hopefully this is a bug in 3.5 version.
This link from Baluc
has provided lot of help, but this is based on tabChange event and also the update is done using requestContext. This is not working when i use iframe.
Any other approach is also welcome.
Thanks in advance

Related

How to use h:commandLink to update and open a p:dialog without reloading other components

I have a <p:datable> to display some products items. One of the item is a <p:graphicImage>. I would like to make this image clickable and display image in bigger in a popup when the image is clicked. Note that the images are stored in a database.
I've tried something like that:
<h:commandLink id="imageBtn"
action="#{imageBean.showImg(_product.id)}">
<p:graphicImage id="product_thumbnail" styleClass="thumbnail"
cache="false"
value="#{imageBean.streamedImageById}">
<f:param name="productId" value="#{_product.id}" />
</p:graphicImage>
</h:commandLink>
...
<p:dialog id="imgDialog" header="Image in Bigger" widgetVar="imgDialog">
<p:graphicImage styleClass="thumbnail_large" cache="false"
value="#{imageBean.getImageById()}">
</p:graphicImage>
</p:dialog>
in my ImageBean:
public void showImg(Long id) {
this.currentProductId = id;
PrimeFaces.current().executeScript("PrimeFaces.widgets['imgDialog'].show();");
}
public StreamedContent getImageById() throws Exception {
if (currentProductId != null) {
..
}
}
The image is clickable and popup correctly displayed, but for some reasons the full data table is refreshed (including all the images) after clicking, which is not user-friendly. Do you have any idea about my problem?
If you are not using Ajax, your entire page will be rerendered if you click a command link. You might want to replace your h:commandLink with a p:commandLink which gives you Ajax out of the box. Then, you want to rerender the dialog when that button is clicked (in order to contain the correct image) and simply show the dialog from the client side using the oncomplete attribute:
<p:commandLink action="#{imageBean.setCurrentProductId(_product.id)}"
update="imgDialog"
oncomplete="PF('imgDialog').show()">
...
</p:commandLink>
Please note that it's important that you choose the right bean scope. Ajax will not work with #RequestScoped beans. You probably want to use #ViewScoped.

h:commandLink inside richfaces dataTable not working properly after pressing browser back button

After I've done some investigation on such issue online, I am still not able to find a proper solution.
The tech stack I have to use here is JSF 1.x, JBoss Seam 2.2.x and richfaces 3.3.x. So the scenario is:
UI
The page contains two main parts, the upper one is providing some criteria for users to search results, and the lower one is to display the results.
Here I am using richfaces.dataTable to populate the results. We also provide the link to load the details of a result item (h:commandLink). The dataTable of course is initially not shown up using rendered attribute of h:panelGroup.
It looks like:
<h:panelGroup rendered="#{results.size gt 0 and not showDetail}">
<rich:dataTable
id="results-table"
value="#{results}"
var="row"
rows="#{rowPerPage}"
styleClass="table"
rendered="#{not empty requests}">
......
<rich:column>
<f:facet name="header">
Action
</f:facet>
<h:commandLink value="DETAILS"
action="#{viewBean.showDetailContext(row)}"
styleClass="link">
</h:commandLink>
</rich:column>
......
</rich:dataTable>
</h:panelGroup>
ViewBean
Code:
#Scope(ScopeType.CONVERSATION)
#Name("result.view")
public class ResultView {
public void showDetailContext(T detailContext) throws Exception {
_detailContext = detailContext;
initListDetails();
setShowDetail(true);
}
protected void initListDetails() throws Exception {
//......
}
}
After doing some search, the UI will be like:
View with Results
So at this moment, users can click the "Details" link and navigate to the detail view like:
Details View
The problem now is when we click the browser back button, we go back to the previous "View with Results" and if users click the Details link of a different item, the Details View will still display the previous detail information as highlighted in the screenshot.
Any advice is highly appreciated.

How to restore current step in Primefaces wizard after page refresh?

I have created a primefaces wizard like this:
<p:wizard id="my-wizard" showNavBar="false" flowListener="#{myBean.onFlowProcess}"
widgetVar="transactionWizard">
<p:tab id="first" titleStyleClass="hidden-wizard-title">
</p:tab>
<p:tab id="second" titleStyleClass="hidden-wizard-title">
</p:tab>
</p:wizard>
Below is onflowProcess() code in my bean class. (My bean class has view access scope)
public String onFlowProcess( FlowEvent event ){
return event.getNewStep();
}
My problem is that, when I am on second tab page and refresh the page, it moves back to first tab page after refreshing. Bit I want page to be stayed at current tab after refresh. How do we do that?

Primefaces Wizard doesn't execute onclick method call

I try to build a form where a user can enter data step by step. After trying a FlowScoped solution I now try to implement the Primefaces wizard.
Description:
My main.xhtml:
<h:form id="antragErfassenForm">
<p:wizard showStepStatus="false" widgetVar="wiz" showNavBar="false" >
<p:tab id="basic_decision_tab" title="Grundsatzentscheidungen">
<ui:include src="/eAkte/basic_decisions.xhtml" />
</p:tab>
<p:tab id="driving_ways_tab" title="Fahrtwegvarianten">
<ui:include src="/eAkte/driving_ways.xhtml" />
</p:tab>
</p:wizard>
</h:form>
Inside the include files I have buttons to navigate between the tabs.
The next button in the first tab 'basic_decisions.xhtml':
<p:commandLink value="Next" onclick="#{eAkteController.callDrivingWays()}; PF('wiz').next();" />
Depending on the result from callDrivingWays() (which evaluates the data of the first tab) the second tab has a different content.
My problem:
The method callDrivingWays() isn't called when clicking the next button on the first tab. Instead it is already called when the first tab is loaded. That's why I always have an empty second page.
I tried switching the method call callDrivingWays() inside an actionListener inside the button or the flowListener of the Wizard. After that the method is called at the correct time, but when clicking on the next button I get an exception, that my component ID has already been used before.
Does anyone has any suggestions?
Try using the flowListener attribute of p:wizard
<p:wizard flowListener="#{yourBB.yourMethod}" nextLabel="Next" backLabel="Back" showNavBar="false" widgetVar="myWizard">
In your backing bean code instead you can implement the actionListener like this:
public String yourMethod(FlowEvent event) {
if(event.getOldStep().equals("driving_ways_tab")){}
if(event.getNewStep().equals("driving_ways_tab")){}
you need getOldStep and getNewStep to perform some changes according to the tab you are entering, exiting.

Change tab on button click without update tabView

I want to change a tab by clicking in commandButton. I'm controlling activeIndex on my bean and doing an update on tabView component. Everything works fine.
My problem is that I want to change the activeIndex without need doing an update on tabView, because update of that component is a bit slow.
Is it possible to change a tab by clicking on button, and do that without update?
Here is my actual code.
TabView component
<p:tabView id="tvFoo" dynamic="true" activeIndex="#{fooBean.activeIndex}">
<p:tab title="Title" id="someTab">
<ui:include src="someTabName.xhtml" />
</p:tab>
<p:tab title="Title2" id="anotherTab">
<ui:include src="anotherTabName.xhtml" />
</p:tab>
</tabView>
inside someTabName.xhtml
<p:commandButton value="go to anotherTab" actionListener="#{fooBean.tabChange('anotherTabName')}" />
fooBean, that controls tabs change
public void tabChange(String tabId) {
switch (tabId) {
case "anotherTabName":
activeIndex = 2;
RequestContext.getCurrentInstance().update("tvFoo"); //here is the line that I don't want to call
break;
}
Can I remove that line, RequestContext.getCurrentInstance().update("tvFoo");? Of course, if simply remove, the tab is not changed.
To resume, basically I want change the opened tab. I think that I can achieve this calling the changeTab event manually, but I don't know how do that.
Why don't you do an update on the tabview component by your command button?
I think you have to do an update somewhere, otherwise, how should the tabview notice the change? Moreover, as far as I know, the update function isn't slow at all.
To get the current index of the tabview you could play with the Faces Context:
TabView tabView = FacesContext.getCurrentInstance().getViewRoot().findComponent(aComponentId);
On tabView you can get and set the active tab individually.
I hope this helps, good luck!
Have you tried using the wizard component? I believe the behaviour you're looking for is similar to this primefaces wizard.
http://www.primefaces.org/showcase/ui/panel/wizard.xhtml

Resources