primefaces update attribute not working on modal dialog opened from modal dialog [duplicate] - jsf

I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.
The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.
Here a simple example:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.
The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.
One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.
The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.
The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.
What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!

Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.
In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.
Just don't use prependId="false", ever.
For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.
For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.
See also:
How to select JSF components using jQuery?
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable ids, which are incompatible with css part of web standards

Related

Missing parameter values in invoked method with composite components using ui:repeat

So after several days of debugging, we were eventually able to reproduce some strange interactions between composite components, ui:repeat, p:remoteCommand and partial state saving in JSF that we do not understand.
Scenario
A composite component iterates over a list of objects using ui:repeat. During each iteration, another composite component is included and arguments are passed.
<ui:composition (...)>
<ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam"/>
In the included composite component, there is an auto-run p:remoteCommand calling a method using parameters defined in the component's interface.
<ui:component (...)>
<p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
autoRun="true"
async="true"
global="false">
However, when setting a breakpoint in someMethod(...), an empty string is passed. This only happens if partial state saving is set to false.
Solutions
We tried several solutions and the following ones appear to work (however we do not understand why and cannot foresee any further problems that could occur):
We can set partial state saving to true.
We can change the composite component pattern to ui:include.
We can remove one or both of the composite components and directly include the content instead.
Question
Why does JSF behave this way? What is this interaction between composite component, ui:repeat and argument passing that changes depending on whether we use ui:include / partial state saving or not?
We're using Primefaces 5.3, Glassfish 4.1, Mojarra 2.2.12, Java 8.
Your code is all fine. It's just that Mojarra's <ui:repeat> is broken. You're not the first one facing a state management related problem with <ui:repeat>.
Checkbox inside ui:repeat not refreshed by Ajax
Dynamically added input field in ui:repeat is not processed during form submit
Components are with the same id inside ui:repeat
<h:form> within <ui:repeat> not entirely working, only the last <h:form> is processed
Composite component with custom backing component breaks strangely when nested inside ui:repeat
ui:repeat in o:tree not working as expected
Root cause of your problem is that #{cc} is nowhere available at the moment the <ui:repeat> needs to visit the tree. Effectively, the <ui:repeat value> is null. A quick work around is to explicitly push the #{cc} in UIRepeat#visitTree() method. Given Mojarra 2.2.12, add below lines right before line 734 with pushComponentToEL(facesContext, null).
UIComponent compositeParent = getCompositeComponentParent(this);
if (compositeParent != null) {
compositeParent.pushComponentToEL(facesContext, null);
}
And add below lines right after line 767 with popComponentFromEL(facesContext).
if (compositeParent != null) {
compositeParent.popComponentFromEL(facesContext);
}
If you don't build Mojarra from source, copy the entire source code of UIRepeat into your project, maintaining its package structure and apply above changes on it. Classes in /WEB-INF/classes have higher classloading precedence than those in /WEB-INF/lib and server's /lib. I have at least created issue 4162 to address this.
An alternative is to replace Mojarra by MyFaces, or to replace the <ui:repeat> by an UIData based component which got state management right such as <h:dataTable> or <p:dataList>.
<p:dataList type="none" var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam" />
</p:dataList>
You might only want to apply some CSS to get rid of widget style (border and such), but that's trivial.
See also:
Should PARTIAL_STATE_SAVING be set to false?

Set ID from backing bean in JSF

Is this legal?
<h:form id="status${a.myID}" >
// ...
</h:form>
where 'a' is an object in a backing bean. It seems to sort of work, but when I look at the rendered HTML, I see the id as: :0:status for example, instead of :status0 as I would expect. My main problem is trying to reference the id from <f:ajax render=.... I'm getting "contains an unknown id..." with pretty much every combination I can think of. Is it possible to set ids using values from a backing bean reliably?
The single-letter variable name ${a} and the symptom of an iteration index like :0 being auto-appended in client ID, suggests that this <h:form> is inside a JSF iterating component such as <h:dataTable> or <ui:repeat> with a var="a" which actually is not a backing bean. It would confirm and explain all symptoms described so far. If ${a} were a real backing bean (and not an iteration variable), then it would have "worked" and you would have seen :0:status0, :1:status0, :2:status0, etc — whose usefulness is questionable though.
First of all, the id attribute of a JSF component is evaluated and set during view build time, the moment when the JSF component tree is to be built based on XHTML source code file. The var attribue of a JSF iterating component is set during view render time, the moment when the HTML output is to be generated based on JSF component tree. Thus, logical consequence is, the object set by var attribute is not available at the moment the id attribute needs to be set and thus evaluates to null/empty-string. The effect is exactly the same as when you would do
<h:form id="status">
JSF iterating components namely already auto-appends the iteration index to the generated client ID. It would not make any sense to manually set the ID of the iterated item in the component ID. There's namely physically only one <h:form> component in the JSF component tree which is in turn reused multiple times during producing the HTML output based on the current iteration round.
This Q&A should also give more food for thought: JSTL in JSF2 Facelets... makes sense?
Coming back to your concrete functional requirement of referencing a component in <f:ajax render>, you definitely need to solve this differently. Unfortunately you didn't clearly describe the context of the source component and the target component, so it's impossible to give/explain the right client ID and so I'm just giving you a link so that you can figure it out on your own: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Unrelated to the concrete problem, the old JSP EL style ${...} has in Facelets exactly the same effect as #{...}. In order to avoid confusion by yourself and your future maintainers it's recommend to completely ban usage of ${...} and stick to #{...} all the time. See also Difference between JSP EL, JSF EL and Unified EL
Actually ${a.myID} this is not rendering any output. As you are getting :0:status as form ID which implies, :0 is parent of :status in HTML tree structure.

Render a jsf element on mouseover

I have a <h:panelGrid> and a h:commandLink(link is basically a image).Now I want that on mouseover event , Then link should be render(render='true') and on mouseout event, it gets removed render='false'.But I am unable to create the logic that How can I do this with these events as the approach I am using is To set the values of bean true and false on this event.
Here is my code
<h:form>
<h:panelGrid mouseover='** we cannot call a bean method here which changes the bean value **'>
This is the Div On which I want to apply mouseover event
</h:panelGrid>
<h:commandLink id="btn" render={renderBean.renderLink}>
<h:graphicImage url="image.jpg"/>
</h:commandLink>
</h:form>
The default value of renderLink attribute of renderBean is false. Now I want to know the way that How can I change its value to true on mouseover event? Is it possible? OR Anyother solution in JSF w.r.t this requirement
You have to remember in JSF that the page will first be processed server-side by the JSF engine in the web server. At that time all JSF tags will be converted into their HTML equivalent. The render attribute tells the server-side engine whether or not to output an HTML a (anchor) link in the place of the <h:commandLink> element.
The behavior you're looking for, namely responding to mouse events, is client-side functionality. It happens in the browser, not at the web server, so no JSF is involved. The solution is to handle the mouse events in JavaScript, not JSF. You will typically set (or remove) the CSS attribute display:none on the id called btn (unfortunately it's slightly more complex as JSF will mangle the element id a bit). There are lots of posts here on StackOverflow that deal with how to handle client-side events in JavaScript. Using jQuery for example is a really common approach.
I recommend to get started you take a look at the blog of one of our best JSF resources and long-time StackOverflow user BalusC: http://balusc.blogspot.com.
There's a lot to learn and you'll get a good start by going there first (and searching for his posts on SO).
Good luck.

JSF render phase (why is my code being executed?)

I'm currently investigating the performance of a JSF application. I have noticed that code is being executed even though rendered is set to false. For example, take this piece of code:
<h:panelGroup rendered="#{bean.render}">
<my composite component here/>
</h:panelGroup>
Even though #{bean.render} returns false, I can clearly see from debug logs, that the code for my composite component is being executed during the render phase. It also looks like the code is being executed before #{bean.render} is even called. It isn't rendered in the HTML returned to the client, but it still appears that the server is executing the code.
Can anyone explain this?
Thanks.
Composite components are built during render response phase. JSF needs to populate the component tree first and then generate HTML based on the component tree. You're inside the composite component apparently referencing some bean properties which are mandatory to be evaluated during view build time.
If you'd like to conditionally control the building of the composite component instead of the rendering, then you need to use a conditional view build time tag instead of the rendered attribute. JSTL offers the <c:if> and <c:choose> for that.
<c:if test="#{bean.build}">
<my:composite />
</c:if>
See also:
JSTL in JSF2 Facelets... makes sense?
Jsf have to know if your components are rendered or disabled or whatever. Let say you say disabled="false" it is shown on clint side and client may change value and submit the form, even though javascript is disabled by the client, jsf checks it's disabled false or true on server side. if it was true it is not acceptable and never comes to your bean because of process validation phase of jsf, same as rendered="false"

Why prependId="false" in a jsf form?

I know what prependId="false" does. It set the flag so that the id of the form does not prepend the id of the form child, but why? any particular reason why you do or dont want to prepend id?
In my experience, I never use this attribute. However, in some cases it can be useful.
When you use Facelets, you can create templates or include pages inside another page. So you can imagine that a page could be included in several different pages. Take the example where the parent pages contain a form, with different id:
Page 1:
<h:form id="form1">
<ui:include src="pages/my-page.xhtml"/>
...
</h:form>
Page 2:
<h:form id="form2">
<ui:include src="pages/my-page.xhtml"/>
...
</h:form>
Now, in the my-page.xhtml, you have a <h:inputText id="foo"/>. In the first case, the real ID of the input will be form1:foo, while in the second case, it will be form2:foo. This could create complex situations if you need a direct access to this component in Javascript or in Java (using findComponent("...") method).
If you use prependId="false" (or on some components forceId="true"), the real ID will be simply foo, and then your code will be simpler as you will not have to care about the container of the input field.
However, you will have to use this attribute carefully, as you may get a duplicate ID error if you use this prepend attribute too often...
In modern jsf versions it might also break ajax, see UIForm with prependId="false" breaks <f:ajax render>
A situation where prependId=false is useful is in the login form, if you are using Spring Security, because the ids of the inputtexts have to be exactly "j_username" and "j_password". So you shouldn't put the form id before them, and using prependId=false is a good choice to acheive this.
I prefer to add prependId occasionally to make styling elements via their ID classes easier. For example, a form:
<h:form id="myform" ... >
<h:inputText id="mytext" ... />
</h:form>
Would give you an ID of myform:mytext. As the colon is reserved in CSS, you have to escape the CSS to read something like #myform\:mytext { ... } which I prefer not to do. With prependId="false" I get to use just #mytext { ... } which is much simpler & nicer to read. It also plays nicer with CSS preprocessors like LESS or Sass.
One scenario where we have to set this flag is in case of Autocomplete control of primefaces library.
I had to set this flag to false when I was trying AutoComplete control of primefaces library. I was not able to get autocomplete working but after setting this flag it worked fine. You can see this link to my question regarding this problem
WARN [Parameters] Parameters: Invalid chunk ignored. warning coming in primefaces application
In addition to making for CSS selectors easier, using prependId=false makes it easier to use JavaScript and jQuery to access specific elements.
Otherwise, without using RichFaces, to get at an elmement by id using jQuery you'll have to use an ugly escape sequence like:
jQuery("form-id\\:element-id")

Resources