I created a facelet template called loginRegisterTemplate.xhtml. When I use it in a template client and I place a in it, the method in the managed bean is not invoked. Without the template the button is working fine. Why is this happening?
<ui:composition template="resources/css/faceletsTemplates/loginRegisterTemplate.xhtml">
<ui:define name="top">
Login Page
</ui:define>
<ui:define name="content">
<div align="center">
<h:panelGrid columns="3" columnClasses="rightalign,leftalign,leftalign">
<h:outputLabel value="Username:" for="userName"/>
<h:inputText id="userName" label="Username" required="true" value="#{loginBean.userName}" />
<h:message for="userName" />
<h:outputLabel value="Password:" for="password"/>
<h:inputText id="password" label="Password" required="true" value="#{loginBean.password}" />
<h:message for="password" />
</h:panelGrid><br/>
<h:button value="Back to Home" outcome="home"/>
<h:commandButton id="login" value="Login" action="#{loginBean.doLogin}"/>
</div>
</ui:define>
</ui:composition>
</h:body>
The simple <h:button> next to it, on the other side, is working fine.
Here is the body of my template file:
<h:body>
<div id="top">
<ui:insert name="top">Top</ui:insert>
</div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
</h:body>
I have looked here: h:commandLink / h:commandButton is not being invoked but I couldn't find which problem causes that.
Thanks!
Why is the h:commandButton not working?
Your problem is number 1 in the answer you have checked.
UICommand and UIInput components must be placed inside an UIForm
component, e.g. <h:form>.
Why is the h:button working then ?
from the h:button docs:
Render an HTML "input" element of type "button". The value of the
component is rendered as the button text and the outcome of the
component is used to determine the target URL which is activated by
onclick.
So ...
JSF will put your h:button outcome value in a javascript function that will be executed at an onclick event. But it will execute the action of the h:commandButton on the form submit with the POST method, so there should be a form to submit.
Related
I am loading stuff via AJAX into my JSF page from the server. However, not all of the content is displayed immediately, two divs arent displayed until the page is refreshed.
Here's the form for loading the content:
<h:form>
<h:dataTable value="#{consoleController.list}" var="item">
<h:column>
<h:commandLink class="list-group-item"
action="#{consoleController.defineLink()}">#{item}
<f:setPropertyActionListener target="#{consoleController.content}"
value="#{item}" />
<f:ajax event="action" render="menuDiv contenDiv facetDiv"></f:ajax>
</h:commandLink>
</h:column>
</h:dataTable>
</h:form>
These are the elements I want to load the code into.
<div class="col-sm-12">
<div class="col-sm-4">
<h:panelGroup id="menuDiv">
<ui:include src="#{consoleController.loadMenu()}" />
</h:panelGroup>
</div>
<div class="col-sm-8">
<h:panelGroup id="contentDiv">
<ui:include src="#{consoleController.loadPage()}" />
</h:panelGroup>
</div>
</div>
<div class="col-sm-12">
<h:form>
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</h:form>
</div>
menuDiv is displayed fine, the other two aren't displayed until I refresh the page.
What's the problem here?
I read that you cannot upload elements that don't exist in the JSF tree, but that's not the case here.
Well, turns out it was as easy as removing the h:form tag around the last panel tag:
<div class="col-sm-12">
<h:form>
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</h:form>
</div>
becomes:
<div class="col-sm-12">
<h:panelGroup id="facetDiv">
<ui:include src="#{consoleController.loadFacet()}" />
</h:panelGroup>
</div>
and now it works.
I have simple page, I want to retrieve j_username to save it in session as a logged in user, i can't fetch it from the form. here Server it self perform authentication in this code
<h:form id="login" onsubmit="document.getElementById('login').action='j_security_check';" prependId="false">
<h:panelGrid columns="2">
<p:outputLabel for="j_username" value="Username" />
<p:inputText id="j_username" name="j_username"/>
<p:outputLabel for="j_password" value="Password" />
<p:password id="j_password" name="j_password" value=""/>
<p:commandButton style="font-size:15px" type="submit" value="Login" ajax="false"/>
<p:commandButton style="font-size:15px" type="clear" value="Clear" ajax="false"/>
</h:panelGrid>
</h:form>
It's available by HttpServletRequest#getRemoteUser() which is in JSF context delegated by ExternalContext#getRemoteUser().
So, this should do either in the view:
<ui:fragment rendered="#{empty request.remoteUser}">
<p>This is only rendered when someone's NOT logged in.</p>
</ui:fragment>
<ui:fragment rendered="#{not empty request.remoteUser}">
<p>This is only rendered when someone's been logged in.</p>
<p>Welcome, you're logged in as #{request.remoteUser}!</p>
</ui:fragment>
or in the managed bean:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String username = ec.getRemoteUser();
// ...
Unrelated to the concrete problem: it's better to get rid of that onsubmit nonsense and just use plain <form> instead of <h:form>.
<form id="login" action="j_security_check">
This way it'll also work on JS-disabled clients.
See also:
Performing user authentication in Java EE / JSF using j_security_check
I'm passing one request parameter to a facelet page which is processed in the corresponding preRenderView event/listener :
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{essayDetails.id}" />
<f:event type="preRenderView" listener="#{essayDetails.init}"/>
</f:metadata>
</ui:define>
Init method is properly accessed and the page is rendered normally. I have a commandLink (RichFaces component) that show a modal panel via an ajax request:
<a4j:commandLink rendered="#{essayDetails.comment}" render="create_comment_group" oncomplete="#{rich:component('create_comment_panel')}.show()">
<h:graphicImage library="images/icons" name="comment.png" />
</a4j:commandLink>
The modal panel snippet:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:utils="http://java.sun.com/jsf/composite/components/utils">
<rich:popupPanel id="create_comment_panel" autosized="true">
<f:facet name="header">
<utils:labeledIcon label="#{msg.action_comment}" image="icons/comment.png" />
</f:facet>
<h:form>
<h:panelGroup id="create_comment_group">
<h:inputTextarea cols="80" rows="8" value="#{essayDetails.userComment}" style="resize: none;" />
<table style="width: 100%">
<tr>
<td style="width: 50%;text-align: right;">
<a4j:commandButton value="#{msg.button_create}" action="#{essayDetails.saveComment}" execute="create_comment_panel_essay" render="essay_comments" oncomplete="#{rich:component('create_comment_panel')}.hide()" />
</td>
<td style="width: 50%;text-align: left;">
<a4j:commandButton value="#{msg.button_cancel}" execute="#none" oncomplete="#{rich:component('create_comment_panel')}.hide()" />
</td>
</tr>
</table>
</h:panelGroup>
</h:form>
</rich:popupPanel>
In this panel a comment is inserted in a h:inputTextArea field, but when the corresponding Accept button is pressed instead of calling #{essayDetails.saveComment} method the post-back request fails in validating f:viewParam id parameter saying that this fields needs a value.
If we make no changes to original code but adds an extra f:viewParam:
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{essayDetails.id}" required="true" />
<f:viewParam name="v" value="#{essayDetails.v}" required="true" />
<f:event type="preRenderView" listener="#{essayDetails.init}"/>
</f:metadata>
</ui:define>
There is no validation error and the behaviour is as expected. What am I doing wrong in using f:viewParam and/or preRenderView event?
Thanks in advance!
try this:
<f:viewParam name="id" value="#{essayDetails.id}" required="#{not facesContext.postback}" />
Try checking in your init() method whether it is a postback:
if (!FacesContext.getCurrentInstance().isPostback()) {
//do your initilialization
}
I am trying to use inputTextArea but i am getting error
javax.servlet.ServletException: org.primefaces.util.ComponentUtils.getValueToRender(Ljavax/faces/context/FacesContext;Ljavax/faces/component/UIComponent;)Ljava/lang/String;. Here is my code
<ui:composition template="./WEB-INF/templates/layout.xhtml">
<ui:define name="title">Add News</ui:define>
<ui:define name="content">
<h:form id="news_advertisement_form" prependId="false" >
<div id="outerboxmid">
<div id="outboxmidborder">
<div id="outboxmidpg">
<div id="formaddupdategrey">
<div class="MainHeader">
<h:outputLabel value="Add News"/>
</div>
<p:panelGrid columns="2">
<h:outputLabel for="firstname" value="Firstname: *" />
<p:inputText id="firstname" value="Basit" label="Firstname" />
</p:panelGrid>
</div>
</div>
</div>
</div>
</h:form>
</ui:define>
</ui:composition>
</h:body>
why i am getting this error?
Thanks
The problem is with the value of your p:inputText.
value="Basit"
The error:
javax.servlet.ServletException: org.primefaces.util.ComponentUtils.getValueToRender(Ljavax/faces/context/FacesContext;Ljavax/faces/component/UIComponent;)Ljava/lang/String;
The Primefaces ComponentUtils class is trying to get the component value during the Render phase and it is probably expecting an EL expression that references a property or object from a managed bean.
My code snippet:
<ui:repeat var="o">
<h:panelGroup id="someid">
<ui:repeat>
// HTML
</ui:repeat>
</h:panelGroup>
<div>
<h:form>
<h:commandButton action="#{o.doSomething}">
<f:ajax event="action" render=":someid" />
</h:commandButton>
<h:form>
</div>
</ui:repeat>
Why didn't <f:ajax> find someid?
That's not possible. The <ui:repeat> prepends the client ID with its own ID and an index. All those panelgroups get IDs like j_id1:0:someid, j_id1:1:someid, j_id1:2:someid, etc. The following is supposed to work in your particular construct:
<f:ajax render=":#{component.parent.parent.clientId}:someid" />
This will prepend the <ui:repeat>'s current client ID dynamically. It however only works when you're using with MyFaces instead of Mojarra. The <ui:repeat> is broken in many ways in Mojarra. They have scheduled many fixes for 2.2.
An alternative is to group them in a common NamingContainer component like <h:form>, so that you can use a relative ID.
<ui:repeat var="o">
<h:form>
<h:panelGroup id="someid">
<ui:repeat>
// HTML
</ui:repeat>
</h:panelGroup>
<div>
<h:commandButton action="#{o.doSomething}">
<f:ajax event="action" render="someid" />
</h:commandButton>
</div>
<h:form>
</ui:repeat>