I'm running Wildfly 8.2 and I'm using the JSF version bundled with it, 2.2.8-jbossorg-1.
I have the following facelet:
<h:form enctype="multipart/form-data">
<h:commandButton value="Submit">
<f:param name="myparam" value="true"/>
<f:ajax execute="#this" render="#this"/>
</h:commandButton>
</h:form>
When I press the submit button, several parameters are submitted, but not myparam. If I remove enctype="multipart/form-data" from the form, myparam=true is submitted just fine.
With or without enctype="multipart/form-data", if I remove f:ajax, myparam=true is always submitted.
Why is it working without enctype="multipart/form-data", but not with? And how can I get it to work?
This is a bug in Mojarra. I've just reported it as issue 3968.
For now, one work around is to pass them as EL method arguments instead.
<h:form enctype="multipart/form-data">
<h:commandButton value="Submit" action="#{bean.action(true)}">
<f:ajax execute="#this" render="#this"/>
</h:commandButton>
</h:form>
public void action(boolean myparam) {
// ...
}
I have found so many examples but the problem is all of them are using JSP/JSF as view. The problem is they always use j_username as username input id and j_password as password id. What I found is these names are standard names. Primefaces doesn't allow me to give name to p:inputtext component. Do you have any solution?
Here is an example : http://krams915.blogspot.com/2012/01/spring-security-31-implement_13.html
j_username and j_password are only default values in Spring Security. You can customize these names as you expected. To do this, you set values for password-parameter and username-parameter as below:
<security:form-login login-page="/login.html"
default-target-url="/welcome.html"
always-use-default-target="true"
authentication-failure-url="/login.html?error"
password-parameter="your_value"
username-parameter="your_value"/>
I'm using Spring Security 3.1. With another version, the configuration is possibly something like above.
Try to use a normal HTML form pointing to the URL of login controller instead of a Primefaces tags:
<form name='f' action="/j_spring_security_check" method='POST'>
<input type='text' name='j_username' value=''>
<input type='password' name='j_password' />
<input name="submit" type="submit" value="submit" />
</form>
You can post directly to j_spring_security_check, but sometimes it might come handy to do it programmatically to combine both worlds.
<p:commandButton value="Login" action="#{loginController.login}" ajax="false">
<h:inputText id="j_username" required="true" />
<h:inputSecret id="j_password" required="true" />
with h xmlns:h="http://java.sun.com/jsf/html"
in your loginController:
ExternalContext context = FacesContext.getCurrentInstance()
.getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/j_spring_security_check");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
I have two jsf pages. layout.xhtml and page.xhtml. Layout looks like this:
<ui:composition>
<h:panelGroup id="menu" layout="block">
<h:outputText value="#{menuBean}" />
<h:form>
<ui:repeat var="menuItem" value="#{menuBean.menuItems}">
<button:menuItem label="#{msgs[menuItem.label]}" action="#{menuBean.selectItem(menuItem.label)}" update="#{update}" />
</ui:repeat>
</h:form>
</h:panelGroup>
<ui:repeat var="menuItem" value="#{menuBean.menuItems}">
<h:panelGroup layout="block" rendered="#{menuBean.selectedItemLabel eq menuItem.label}">
<ui:include src="#{menuItem.page}" />
</h:panelGroup>
</ui:repeat>
And page like this:
<h:panelGroup binding="#{page}" layout="block">
<ui:decorate template="../template.xhtml">
<ui:param name="menuBean" value="#{pageBean}" />
<ui:param name="update" value=":#{page.clientId}" />
</ui:decorate>
</h:panelGroup>
When I first time render page everything is ok (menuItems are rendered etc). After I click any button I get Target Unreachable, identifier 'menuBean' resolved to null.
Can anyone explain me what is happening why the menuBean isn't assigned again and if there exists another way to achieve this kind of thing (to have some generic layout page, pass some object there and generate page)? My beans are managed by Spring.
UPDATE:
I guess the problem is somehow connected to my composite button which looks like this:
<composite:interface name="menuItem">
<composite:attribute name="action" targets="button" />
<composite:attribute name="styleClass" />
<composite:attribute name="label" />
<composite:attribute name="update" />
<composite:attribute name="rendered" />
<composite:insertChildren />
</composite:interface>
<composite:implementation>
<h:commandButton id="button" value="#{cc.attrs.label}" style="width: 150px;" action="#{cc.attrs.action}"
rendered="#{empty cc.attrs.rendered ? true : cc.attrs.rendered}" styleClass="menu-item #{cc.attrs.styleClass}" type="button">
<f:ajax render="#{cc.attrs.update}" />
</h:commandButton>
</composite:implementation>
If I replace the tag by standard h:commandButton everything works perfectly. I am passing object into template and the template is passing the passed object into composite, but I am definitely missing something.
I think the problem is connected with the scope of the beans. As I understand your pageBean backing bean have request scope. Try to change scope on wider one (it should be view scope #ViewScoped). If you use CDI annotations instead of JSF then you can look at #ConversationalScope (or you can use MyFacesCODI library as Luiggi noted).
The problem I am facing to BalusC already described on his blogspot:
http://balusc.blogspot.cz/2011/09/communication-in-jsf-20.html#ViewScopedFailsInTagHandlers
Simply put at the moment of postback request (ajax refresh of button) bean passed into my composite button does not exist. As BalusC noted, solution can be creating of standard UIComponent instead of using composite shortcut.
this is my 1st question here :)
My code is as follows:
<?xml version="1.0"?>
<f:view 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:p="http://primefaces.org/ui"
>
<h:head />
<h:body>
<h:form id="filterForm">
<h:outputStylesheet library="css" name="main.css" />
<div id="filterPane">
<h:panelGroup rendered="#{not empty filters.categories}">
<div class="filter">
<div class="filterCategories" style="width: 100%;">
<h4>Kategorien</h4>
<p />
<h:selectManyCheckbox layout="pageDirection"
value="#{filters.selectedCategories}"
valueChangeListener="#{filters.categoryValueChanged}">
<f:selectItems value="#{filters.categories}" var="category"
itemLabel="#{category.displayName} (#{category.count})"
itemValue="#{category.name}" />
<f:ajax render="#form" />
</h:selectManyCheckbox>
</div>
</div>
</h:panelGroup>
</div>
</h:form>
</h:body>
</f:view>
I get the same error as some others before me here #stackoverflow - but none of the suggested solutions worked for me.:
<f:ajax> contains an unknown id 'A5539:filterForm:j_idt9' - cannot locate it in the context of the component j_idt9
Before my switch from <p:selectManyCheckbox to <h:selectManyCheckbox the code was working fine.
We need to change to <h:selectedManyCheckbox, because the PrimeFaces variant is not selectable for a non-JavaScript user. I need the form <h:form id="filterForm"> to be re-rendered as a consequence of my AJaX request via the <f:ajax> element.
Beside the initial <f:ajax render="#form" /> I unsuccessfully tried to reference the <h:form id="filterForm"> element with the following variants:
<f:ajax render=":filterForm" />
<f:ajax render=":#{component.parent.parent}" />
I also tried some more stupid ones.
Any hint, anybody!? :)
I have a Facelets subview at /subviews/document-tree.xhtml that renders a tree for each tab on a <rich:tabPanel> client. The page and sub views are based on JSF 2 and RichFaces 4.
<ui:composition ...>
<rich:tree value="#{rootNode}" var="treeNode" id="#{treeId}">
<rich:treeNode ... id="chapternode">
<h:panelGrid columns="2">
<rich:outputText value="#{treeNode.name}" />
<h:commandLink>
<h:graphicImage library="images/icons" name="delete.png" />
<rich:componentControl target="remove-chapter-popup" operation="show" />
</h:commandLink>
<rich:popupPanel modal="true"
onmaskclick="#{rich:component('remove-chapter-popup')}.hide(); return false;"
id="remove-chapter-popup">
<f:facet name="header">
<h:outputText value="Remove chapter?" />
</f:facet>
<f:facet name="controls">
<h:outputText value="X" />
</f:facet>
<p>Remove chapter #{treeNode.name}?</p>
<h:panelGrid columns="2">
<h:commandButton value="Add"
action="#{nodeManager.removeChapterNode(treeNode)}"
onclick="#{rich:component('remove-chapter-popup')}.hide(); return true;">
<!--f:ajax execute="#this" render="#form" /--> <!-- never executed! -->
<a4j:ajax execute="#this" render="#form" /> <!-- this works however! -->
</h:commandButton>
<h:commandButton value="Cancel"
onclick="#{rich:component('remove-chapter-popup')}.hide(); return false;" immediate="true" />
</h:panelGrid>
</rich:popupPanel>
</h:panelGrid>
</rich:treeNode>
...
</rich:tree>
</ui:composition>
This basically shows tree nodes with their name plus an image to the right for deletion.
Each tree sub view is placed into a <rich:tab>, so the tab panel does have the required enclosing <h:form>. There are no other nested forms (forbidden anyway).
The #{nodeManager.removeChapterNode(treeNode)} bean was correctly marked as #ViewScoped.
Now what happens is kinda strange:
When using <f:ajax execute="#this" ... /> the button never executes, whereas using <a4j:ajax execute="#this" ... /> always works.
Why? What's wrong here?
It doesn't make much sense, given the fact that RichFaces <a4j:ajax> is based 100% on JSF 2 <f:ajax> according to their own words.
Could it be a bug in JSF 2.1.7, which I'm using? (the implementation that came with JBoss AS 7.1.1.Final)
Spaces are illegal in IDs. See also UIComponent#setId() javadoc.
setId
public abstract void setId(java.lang.String id)
Set the component identifier of this UIComponent (if any). Component identifiers must obey the following syntax restrictions:
Must not be a zero-length String.
First character must be a letter or an underscore ('_').
Subsequent characters must be a letter, a digit, an underscore ('_'), or a dash ('-').
Component identifiers must also obey the following semantic restrictions (note that this restriction is NOT enforced by the setId() implementation):
The specified identifier must be unique among all the components (including facets) that are descendents of the nearest ancestor UIComponent that is a NamingContainer, or within the scope of the entire component tree if there is no such ancestor that is a NamingContainer.
Parameters:
id - The new component identifier, or null to indicate that this UIComponent does not have a component identifier
Throws:
IllegalArgumentException - if id is not syntactically valid
Seems like that RichFaces is never validating it according the rules for the tree. I would in turn account it as a bug in RichFaces. Report it to the RichFaces guys.
Here's the reduced diff:
<form id="tree-form" name="tree-form" method="post" action="/pqgenerator2/debug.jsf" enctype="application/x-www-form-urlencoded">
...
<table style="margin: 0 auto;">
<tbody>
<tr>
- <td><input id="tree-form:sorting-tree-one:real root:j_idt34" type="submit" name="tree-form:sorting-tree-one:real root:j_idt34" value="Fortfahren" onclick="jsf.util.chain(this,event,'RichFaces.$(\'tree-form:sorting-tree-one:real root:add-root-chapter-popup\').hide(); return true;','mojarra.ab(this,event,\'action\',\'#this tree-form:sorting-tree-one:real root:new-root-chapter-name-input\',\'#form\')');return false" /></td>
+ <td><input id="tree-form:sorting-tree-one:real root:j_idt34" type="submit" name="tree-form:sorting-tree-one:real root:j_idt34" value="Fortfahren" onclick="jsf.util.chain(this,event,'RichFaces.$(\'tree-form:sorting-tree-one:real root:add-root-chapter-popup\').hide(); return true;','RichFaces.ajax(this,event,{"parameters":{"javax.faces.behavior.event":"action","org.richfaces.ajax.component":"tree\\u002Dform:sorting\\u002Dtree\\u002Done:real root:j_idt34"} ,"sourceId":this} )');return false" /></td>
</tr>
</tbody>
</table>
...
- </div></span></span></div></div><input type="hidden" name="tree-form:sorting-tree-one__SELECTION_STATE" id="tree-form:sorting-tree-one__SELECTION_STATE" class="rf-tr-sel-inp" value="" /><script type="text/javascript">new RichFaces.ui.Tree("tree\u002Dform:sorting\u002Dtree\u002Done",{"toggleType":"client"} );</script></div></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="998210192617713914:-9142017502724223608" autocomplete="off" />
+ </div></span></span></div></div><input type="hidden" name="tree-form:sorting-tree-one__SELECTION_STATE" id="tree-form:sorting-tree-one__SELECTION_STATE" class="rf-tr-sel-inp" value="" /><script type="text/javascript">new RichFaces.ui.Tree("tree\u002Dform:sorting\u002Dtree\u002Done",{"toggleType":"client"} );</script></div></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-5805340602741883884:1908800949269113937" autocomplete="off" />
</form>
The problem here is that I create a dummy root node for the RichFaces root to be displayed and I add the real root via RichFaces TreeNodeImpl's addChild("real root", ...), which contains a space in the key.
The <a4j:ajax> code can obviously handle this but not JSF 2's <f:ajax> (note the first diff part).