I have a page with a p:Menuitem using OnClick function.
My problem is that when i refresh the page, the event onclick is still running, how can i stop it?
Client-side code:
<p:submenu label="Ordres de Fabrication" styleClass="submenustyle" >
<p:submenu label="Ordre non Réalisé">
<p:menuitem value="Afficher" outcome="/admin/gestionduplanning/ofnonrealiseAfficher.xhtml" onclick="#{ofrealiser.getofnonrealiser()}" />
<p:menuitem value="Ajouter" outcome="/admin/gestionduplanning/ofnorealiseAjouter.xhtml" />
</p:submenu> ...
UPDATE 1 :
<p:menuitem value="Afficher" outcome="/admin/gestionduplanning/ofnonrealiseAfficher.xhtml" onclick="#{ofrealiser.getofnonrealiser()}" actionListener="#{exporterPlanningGlobal.refreshfromjsfdateplanning()}" />
the managed bean methode :
public void refreshfromjsfdateplanning()
{
System.out.println("Test actionlistener");
}
but the methode isnt called because in my IDE glassfish it didnt print anything .
how to get the actionlistner working ??
UPDATE 2 :
i found that when i remove the outcome from the menu the action listner is working .. but when i use outcome or url to go to a page didnt work how to solve that ?
Both onclick and oncomplete should only be used to call a javascript event handler.
If you want to call something on server when clicking a menu item then use actionListener.
As a side line, of course the code inside the onclick will trigger when refreshing the page because the jsf expressions are evaluated on the page rendering phase.
You can find a working example on the Primefaces Demo
I found the solution for my problem : do a treatment before navigating with p:menuitem :
<p:menuitem value="Exporter tous les plannings" styleClass="submenustyle" action="#{exporterPlanningGlobal.refreshfromjsfdateplanning}" update="#form"/>
and managed bean methode :
public String refreshfromjsfdateplanning()
{
System.out.println("treatment done");
return "/espaceZP01/gestionduplanning/exporterTousPlanning.xhtml?faces-redirect=true";
}
Related
Working with JSF, I have a <ux:confirm> tag, which has a confirm button. When clicked it triggers a actionListenerEvent. The page and the objects in the faces context are updated, however I have a bootstrap accordion which is not updated. A solution would be refreshing the page, which is my question.
<ux:confirm
ok="#{message.get('Label.Sim')}"
ajax="true"
render="form-consulta"
cancel="#{message.get('Label.Nao')}"
title="#{message.get('Label.Excluir')}"
message="#{message.get('Msg.DesejaExcluirRegistro')}"
>
<f:actionListener
for="onOkClick"
binding="#{bean.excluir()}"
/>
</ux:confirm>
Ok, solved by just adding a JavaScript function on the ajax event and also calling somewhat a template method using javascript.
<f:ajax
render="#{cc.attrs.render}"
disabled="#{not cc.attrs.ajax}"
onevent="onEventConfirm"
/>
function onEventConfirm(data) {
App.ajax.onEvent(App.view.block, null, null, App.view.unblock);
var status = data.status;
switch (status) {
case "complete":
if(shouldRefreshAfterConfirmation)
this.location.reload();
break;
}
}
I'm using p:button with onclick action. (I can't move to p:commandButton, because of legacy outcome navigation in faces-config.xml and custom navigation history in db):
<p:remoteCommand name="unlock_tt" actionListener="#{ttEntityMBean.unlock()}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" onclick="unlock_tt()"/>
Generated by primefaces javascript looks like
onclick="unlock_tt(); window.open(....)"
And after clicking button, unlock_tt() in browser initiated, but immediatly broken by page redirecting, so backed java method didn't execute.
Should I make unlock_tt() or java call async to be sure it will be executed before browser leaves page?
Upd: I'm thinking to use p:commandButton, if it is possible to get to-view-id programically, like in this question:
Programmatically get navigation case <to-view-id> from faces-config.xml by outcome
<p:commandButton action="#{ttEntityBean.unlock()}"/>
public String unlock() {
//some business logic
return OutcomeResolverHelper.getRuleFor(navigationMenuItemToRedirect.navigationRule)
}
This should reduce number of requests
I'm not sure this will work but can you try this :
Instead of :
<p:remoteCommand name="unlock_tt" actionListener="#{ttEntityMBean.unlock()}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" onclick="unlock_tt()"/>
do:
<h:panelGroup>
<f:ajax event="click" listener="#{ttEntityMBean.unlock}"/>
<p:button value="#{msgs['button.ok']}" outcome="#{ttEntityMBean.navigationMenuItemToRedirect.navigationRule}" />
<h:panelGroup>
Don't forget to remove onclick and your remotecommand.
This should wrap a panelGroup around your button. PanelGroup implements ClientBehaviorHolder so it can get f:ajax tag in its children. Thus when you click on it it should trigger the listener.
The easiest way was migration from p:button to p:commandButton, which allows to execute some java-code in action method before redirect. The core is programmical translation of navigation rule, defined in faces-config.xml to base url, usable in explisit jsf-2.0 style:
//receive base url from <to-view-id> tag
public static String resolveOutcomeRule(String ruleName) {
FacesContext context = FacesContext.getCurrentInstance();
ConfigurableNavigationHandler configNavHandler = (ConfigurableNavigationHandler)context.getApplication().getNavigationHandler();
NavigationCase navCase = configNavHandler.getNavigationCase(context, null, ruleName);
return navCase.getToViewId(context);
}
//decorate it with faces-redirect=true and our custom navigation
public static String resolveOutcome(NavigationMenuItem item) {
return resolveOutcomeRule(item.getNavigationRule()) + "?faces-redirect=true&menu=" + item.getId();
}
//controller-method
public String cancelEditTT() {
super.unlock();
return FacesUtil.resolveOutcome(getNavigationMenuItemToRedirect());
}
//new jsf button:
<p:commandButton value="#{msgs['button.ok']}" action="#{ttEntityMBean.cancelEditTT}"/>
This solution provided 1-step redirect instead of 2-step old one.
I am relatively new in jsf.
I have a jsf page someDetails.xhtml, in which I have an output link
<h:outputLink value="#{someTaskController.completeTask(taskId)}?taskId=#{taskId}">Assign Ticket</h:outputLink>
On clicking on this link, the method completeTask should be called and do something.
The problem is, when the jsf page someDetails.xhtml is opened(in browser), the method completeTask is getting called and does all the task, which should only happen on clicking the link.
What should I do ? Please help
You're using the wrong tag for your purpose, use command link instead:
<h:commandLink value="Assign Ticket" action="#{someTaskController.completeTask()}">
<f:param name="taskId" value="#{taskId}" />
</h:commandLink>
You can access taskId inside method completeTask() like this:
public void completeTask() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String taskId= params.get("taskId");
// do your business action...
}
I have a p:commnandButton as follows
<p:commandButton id="previouscat"
value="Go to #{categoryBean.getPreviousCategory().name}"
style="margin:0px;" icon="ui-icon-back" update="#all"
action="#{categoryBean.selectPreviousCat}"/>
which is inside a form. Now my problem is that when clicking on the button, the action doesn't execute cause then it should change the value of the button. I've tryed with setting the action function like categoryBean.selectPreviousCat & categoryBean.selectPreviousCat() with no success.
public void selectPreviousCat(){
this.selectedCategory = this.getPreviousCategory();
}
Let say that I want to create a variable set of <rich:tab> elements within a <rich:tabPanel> component. So I tried to do that way:
<rich:tabPanel switchType="client" ...>
<ui:repeat value="#{myBean.myTabs}" var="tab">
<rich:tab name="#{tab.name}" label="#{tab.label}"/>
</ui:repeat>
</rich:tabPanel>
But it didn't work, as no tab is rendered. I also got the following message in the logs:
j_id174: tab panel has no enabled or rendered tabs!
This problem seems to be encountered by others people, for example here.
So as suggested by the previous thread, I replaced my <ui:repeat> by a <c:forEach> but the problem still occurs.
I have a way to solve this problem using the binding attribute of my <rich:tabPanel> component:
<rich:tabPanel switchType="client" binding="#{tabNavigationBean.tabPanel}"
</rich:tabPanel>
and then in my Java bean:
private HtmlTabPanel tabPanel; // + getter and setter
public void setTabPanel(HtmlTabPanel tabPanel) {
this.tabPanel = tabPanel;
if (tabPanel != null) {
createTabs();
}
}
private void createTabs() {
Application application = FacesContext.getCurrentInstance().getApplication();
HtmlTab newTab = null;
for (DedicatedPageTab dpt : getDedicatedPageTabs()) {
newTab = (HtmlTab) application.createComponent(HtmlTab.COMPONENT_TYPE);
newTab.setLabel(dpt.getLabel());
newTab.setName(dpt.getName());
tabPanel.getChildren().add(newTab);
}
}
This code is working.
However, my question is to know if I can solve my problem without using the binding attribute (i.e. a 100% pure XHTML solution)?
<a4j:outputPanel id="out">
<rich:tabPanel>
<c:forEach items="list" var="var">
<rich:tab label="#{var.name}" switchType="client">
content
</rich:tab>
</c:forEach>
</rich:tabPanel>
</a4j:outputPanel>
Yes, it is possible, but difficult. Here are some notes I have:
Use c:forEach to create tab tags inside tabPanel inside outputPanel. reRender outputPanel on tab removal, add, or name change
http://relation.to/11633.lace
http://devharbor.blogspot.com/2009/08/add-jsf-controls-dynamically-with.html
We also made use of templating, though I still have an outstanding issue for it: How to force the build phase in a JSF 1.2 page using JSTL?
http://facelets.java.net/nonav/docs/dev/docbook.html#template
Docs on templating
http://www.jsfcentral.com/articles/facelets_3.html
Templating tutorial