p:commandLink not fires action - jsf

p:commandLinks with ids cl1 and cl2 do not fire actions. There is nothing on Tomcat console, nothing on Firebug console.
Where should i look for the problem in such situations, i think i am totally desperate without any error or exception, in both consoles.
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:o="http://openfaces.org/"
xmlns:p="http://primefaces.org/ui">
<h:form>
<ui:repeat var="sharing" value="#{sharingController.myList}">
<ui:repeat var="sharingComment" value="#{sharing.subCommentList}">
<p:commandLink id="cl1" value="" process="#this" action="#{reportController.reportSharingComment(sharingComment)}" style="float:right;" id="sharingComment_alert" styleClass="icon_alert" title="#{msg['label.report']}" update=":messages" >
</p:commandLink>
<p:commandLink value="" id="cl2" process="#this" action="#{sharingController.deleteComment(sharingComment)}" style="float:right;" id="sharingComment_delete" styleClass="icon_delete" title="#{msg['label.delete']}" update="#form :messages">
</p:commandLink>
</ui:repeat>
</ui:repeat>
</h:form>
</ui:composition>
I tried with a concrete list in the nested ui:repeat in post construct then commandlinks was fired, but I must iterate over field lists like sub commentlists of every sharing in myList. I'm loading both myList and for every sharing I load the subCommentlist in a for in post construct, but I still cannot make the commandLinks fire.

h:commandLink / h:commandButton is not being invoked
The 4. point solved:
Putting the bean in the view scope and/or making sure that you load the data model in (post)constructor of the bean (and thus not in the getter method!) should fix it.

Related

JSF rendered and fragments

I'm facing a a problem with JSF, i have a fragment that is rendered on all pages, and displays the latest entries of a table (~ 10 items). And i want to reuse it on a page that lists all entries.
I put a rendered rule to prevent the all pages version of the element to appear on this page specifically, but still no go, I aways get a "duplicate id found in view" error. The problem seems to lay on the fact that the JSF processor validate the IDs before validating which ones will really be rendered.
Just for information, I'm using the end of the request URI to determine if rendered is True or False.
Ah, and I tried using c:if, but it was useless too.
Edit:
Sample code requested...
i have this xhtml fragment ("tableInclude.xhtml"):
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<ui:fragment>
<p:dataTable var="item" value="#{bean.items}"
emptyMessage="#{msg['table.empty']}"
widgetVar="table" id="listItems" styleClass="tableItems">
<p:column styleClass="span1" style="text-align: center;">
<f:facet name="header">
<i class='fa-icon-picture'/>
</f:facet>
<p:commandLink action="#{bean.itemSelected(item)}" value="#{item.name}"/>
</p:column>
</p:dataTable>
</ui:fragment>
</ui:composition>
Then i run on every page this:
<ui:include src="./tableInclude.xhtml">
i tried to do this:
<ui:fragment rendered="#{request.requestURI != '/context/don't_render_here.xhtml'}">
<ui:include src="./tableInclude.xhtml">
</ui:fragment>
But i still get the duplicated id error even so when i access the "don't_render_here.xhtml" page.
not the best solution, but a quick and dirty: replace ui:fragment with f:subView

JSF redirect via commandButton

I cannot redirect to another page if the code is like this:
<h:commandButton type="button" value="Enter" action="index?faces-redirect=true" >
But the redirect works if the code is:
<h:commandButton type="button" value="Enter" action="index?faces-redirect=true" >
<f:ajax />
</h:commandButton>
Could anyone explain this? Thanks!
-----------------------EDIT------------------------
The entire xhtml code for your reference:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="form">
<h:commandButton id="enterModelButton" type="button" value="Enter" action="index?faces-redirect=true" >
<f:ajax />
</h:commandButton>
</h:form>
</h:body>
</html>
The <h:commandButton type="button"> doesn't generate a submit button. It just generates a "dead" button without any effects, purely intented to be used for custom onclick="..." scripts and like. This is somewhat a leftover of the dark JSF 1.0/1.1 era, when it wasn't nicely possible to just use plain vanilla HTML in JSF for this kind of things.
The <f:ajax> performs the submit by ajax powers through JSF-generated onclick. It doesn't care about the button's type.
Essentially, removing type="button" and relying on its default type="submit" should fix your problem.
<h:commandButton value="Enter" action="index?faces-redirect=true" />
However, all with all, if this is the real code and you don't actually intend to invoke a bean action, then you're going in completely the wrong direction as to implementing the functional requirement of navigating to a different page by a button. You should be using <h:button> instead.
<h:button value="Enter" outcome="index" />
See also:
Difference between h:button and h:commandButton
How to navigate in JSF? How to make URL reflect current page (and not previous one)

Getting page parameters for a requestscoped bean in a form

I have the following page:
<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Fire - Registration</title>
</h:head>
<h:body>
<f:view>
<f:event type="preRenderView" listener="#{confirmPasswordResetBean.bindSessionKey()}"/>
</f:view>
<p:growl id="growl" showDetail="true" life="5000" />
<h:form>
<p:panel header="Select your new password">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="newPassword" value="Type your new password"/>
<p:password id="newPassword"
value="#{confirmPasswordResetBean.firstPassword}"
feedback="true"/>
<p:outputLabel for="retypedPassword" value="Retype your password"/>
<p:password id="retypedPassword"
value="#{confirmPasswordResetBean.secondPassword}"/>
</h:panelGrid>
<p:commandButton id="confirmButton"
value="reset"
action="#{confirmPasswordResetBean.doResetPassword()}"
update=":growl"/>
</p:panel>
</h:form>
</h:body>
The backing bean used above is RequestScoped, and the page itself takes a single parameter (sessionKey)...what I want to do is to:
1. Bind sessionKey to a variable in the backing bean. This is straightforward enough.
2. Use the bound value of sessionKey when executing dedicated logic in the same bean, when the client presses the commandButton.
The problem is that pressing the button starts a new request, which invalidates both the current bean (with the bound value), as well as the external page context...I thus lose all means to get a hold of sessionKey from either the bean or the page parameters...how can I resolve this? I am relatively new to both web programming and JSF, so pardon me if this has an obvious answer.
Either put the bean in the view scope, so that it lives long as you're interacting with the same view, or pass the request parameter by <f:param> to the subsequent requests.
<p:commandButton ...>
<f:param name="sessionKey" value="#{param.sessionKey}" />
</p:commandButton>
By the way, you'd rather have used <f:viewParam> to bind the request parameter to the bean directly.
<f:metadata>
<f:viewParam name="sessionKey" value="#{bean.sessionKey}" />
</f:metadata>
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?

How to create links relative to the right context?

I have this composition :
<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:panelGroup rendered="#{empty userc.userb.user.id}">
<h:panelGrid columns="2" >
<h:outputLink value="system/register.xhtml">Register</h:outputLink>
<h:outputLink value="system/login.xhtml">Login</h:outputLink>
</h:panelGrid>
</h:panelGroup>
</ui:composition>
If the user click in Login the page is redirect to system/login.xhtml, which is correct, but if the user, click in Login again, it is redirect to system/system/login.xhtml.
I know a solution for this, which BalusC help me out a long time ago:
<base href="#{fn:replace(request.requestURL, fn:substring(request.requestURI, 1, fn:length(request.requestURI)), request.contextPath)}/" />
It solve my problem, but if I have some ManageBean instancied when I click in some link the bean it's invalidate.
How mantain the url path in every link page and keep the session in the Managed beans ?
Use <h:link> instead. JSF will append the right context path and FacesServlet mapping.
<h:link value="Register" outcome="/system/register" />
<h:link value="Login" outcome="/system/login" />
See also:
Communication in JSF 2.0 - Implicit navigation

facelets: passing bean name with ui:param to action attribute

Due to some custom components which expect a bean name (NOT the bean instance) in their attributes I need to pass the actual bean name between pages. As the bean itself is also used by non-custom components, I would like to avoid using additional ui:param (like described here Passing action in <rich:modalPanel>) since it will essentially specify the same bean.
Is it possible to specify component's action using bean name provided with ui:param?
Basically I am trying to achieve the following:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/template.xhtml">
<ui:param name="beanName" value="sessionBean"/>
...
</ui:composition>
and template.xhtml is
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
template="/someothertemplate.xhtml">
</ui:define name="somename">
<h:form>
<a4j:commandButton value="test" action="#{beanName.delete}"/>
</h:form>
</ui:define>
</ui:composition>
Although delete method is properly defined (verified with action="#{sessionBean.delete}") the above code gives me
javax.faces.FacesException: #{beanName.delete}: javax.el.MethodNotFoundException: /template.xhtml #201,89 action="#{beanName.delete}": Method not found: sessionBean.delete()
You should be able to reference the bean via its scope:
<a4j:commandButton value="test"
action="#{sessionScope[beanName].delete}"/>
<a4j:commandButton value="test" action="#{bean[action]}" />
The params to pass
<ui:param name="bean" value="#{sessionBean}" />
<ui:param name="action" value="delete" />
you can use #{bean['delete']} if your action name is fixed.

Resources