Maybe it's a dumb question, but in Primefaces's <p:dialog> there's property which called appendTo which described in manual as:
Appends the dialog to the element defined by the given search
expression.
I can't realize what it useful for?
From the PrimeFaces User Guide (currently p. 185):
Do not place dialog inside tables, containers likes divs with relative positioning or with nonvisible
overflow defined, in cases like these functionality might be broken. This is not a limitation
but a result of DOM model. For example dialog inside a layout unit, tabview, accordion are a
couple of examples. Same applies to confirmDialog as well.
You can overcome this by using appendTo="#(body)" and your dialog will be attached as a child of the <body> node.
One of the main dialog option is modal and you could quickly end up with your dialog behind the overlay if you are not using appendTo as shown below:
See also http://forum.primefaces.org/viewtopic.php?f=3&t=16504
Notes:
Before PrimeFaces 5.0, the attribute to set was appendToBody="true". This was changed for 5.0.
If your dialog contains some buttons don't forget to surround them by <h:form> (see Proper Construct for Primefaces Dialog)
The PrimeFaces docs are a bit sparse on this point. appendToBody / appendTo (before 5.0) solves (or tries to solve) a problem where a PrimeFaces component does not get the right z-Index, meaning it does not appear before or behind other elements the way it should. However, this feature is problematic because it can cause other problems like p:commandbutton action doesn't work inside p:dialog
tl;dr:
Do not use appendTo / appendToBody. Instead, Dialogs (along with ConfirmDialog and OverlayPanel) should always be at the root of the component hierarchy, as a direct descendant of <h:body>. This will make them work reliably. In that case using appendTo / appendToBody is unnecessary.
One good way to accomplish this is to have one (or multiple) separate XHTML files for these components ("dialogs.xhtml"), which then gets included in your main XHTML file or template (for example using <ui:include>). Another solution is to use a <ui:define> in combination with a <ui:insert> if you want the dialogs to remain in the XHTML file where they are used.
Read on for details :-)
The problem
Some PrimeFaces components (such as dialogs) should be be displayed on top of other elements.
For example:
If you use <p:dialog ...modal="true">, and make the dialog visible, you get a dialog in the foreground, appearing above the rest of the page, with the rest of the page covered by a transparent layer.
You can see this for example in the PF Showcase for dialogs (button "Modal").
Behind the scenes, i.e. in the page's DOM, two things happen:
a new <div> (the "modal overlay") is created at the end of the <body>. This div gets the CSS styles: z-index: 1000; position: absolute; opacity: .30;. This makes it transparent and covering the whole page, to get the "modal" effect.
the (existing, but invisible) div of the dialog itself is made visible, and gets the styling z-index: 1001; position:fixed;. Note the z-index is one larger than the modal overlay, thus the dialog appears above the overlay.
However, this does not always work. The reason for this is an aspect of CSS called the stacking context. The details are a bit complex, but basically it says that the z-index of a page element is only compared to other elements inside the same parent element. In particular, an element may appear behind another element even though it has a higher z-index, if the element with the high z-index is contained in an element with a lower z-index.
The short (safe) version is: To be certain that z-index works as expected, all concerned elements should be siblings in the DOM.
Now, in this particular situation, the modal overlay must be right at the top of the DOM hierarchy (i.e. inside <body>), otherwise it cannot reliably appear above the rest of the page. However, the div of the dialog itself is somewhere deeper in the DOM (corresponding to the position of the <p:dialog> tag in the source XHTML). Now we have a problem.
In practice, this means that the overlay may appear above the dialog, thus obscuring and blocking it. Similarly, if the dialog is not modal, it may appear behind other elements in the page.
The insidious thing about this problem is that it depends on the structure of the rest of the page (specifically, whether the rest of the page uses CSS that creates a new stacking context). So <p:dialog> may appear to work initially, then suddenly shows incorrectly after a change elsewhere.
How 'appendTo' helps
As explained above, the problem occurs because the HTML rendered for the PrimeFaces component is somewhere deep down in the DOM, while it would need to be a direct child of <body> for the z-index to work correctly.
When appendToBody / appendTo is used, PrimeFaces will include Javascript in the rendered page which simply moves the DOM node of the PrimeFaces component to the end of <body> (using JQuery's appendTo function). That way the component is in the right place in the DOM, and z-index works.
The problem with using 'appendTo'
While the DOM reorganization performed by appendTo solves the problem with CSS and z-index, it introduces another (potential) problem:
The client-side DOM no longer corresponds to the server-side page state maintained by JSF (called the view).
Now, one of the central features of JSF is that it expects the client-side HTML/DOM structure to correspond to the the server-side view - after all, JSF constructed the HTML from that view. If that rule is violated (usually by manipulating the DOM client-side), you get all kinds of weird problems, such as JSF ignoring form fields or values in a submit, or overwriting part of your modifications on AJAX updates.
In this case, the problems caused by moving the DOM node of the PrimeFaces component include:
If the PrimeFaces component is part of a <h:form>, it will not work properly (because it will not be inside the <form> tag client-side because of the moving).
This is actually mentioned in the PrimeFaces docs, along with the workaround: Instead of putting the component into a form, put a form inside the component - then the form will move with the component.
If the area where JSF originally rendered the PrimeFaces component is updated using JSF's AJAX feature, JSF will remove area to update from the DOM, then render the component again, as it does not know it was moved elsewhere.
In old versions of PrimeFaces, this caused the component to appear in the DOM twice (with the same id), which caused problems with later submits. This was fixed for PrimeFaces 4.0 ( Issue 5636: Dialog appendToBody & dynamic doesn't remove the old dom element ), but re-occurred in 5.0 (issue #367).
This shows that this kind of DOM manipulation "behind JSF's back" is rather risky and should be avoided - thus my advice to not use appendTo / appendToBody.
I am working on something like this:
A JSF template has a side-navigation bar which contains links(either anchor or h:outputLink), and there are cases where two options lead to the same link(page), but with a different value in view parameter, and thus rendering different data being displayed on the page.
Is there a way to do this? Using commandLink or commandButton does not seem like an option to me since it will mess up the styling.
Thanks in advance.
An output link is just a normal HTML link, so a conventional way to do this is with a query parameter, e.g. /contentarea.xhtml?myparam=value.
I don't think you should bind a method to the output link. That would involve a Javascript onclick handler (commandLink), and I don't think that's necessary here. That said, I'm surprised you say commandLink messes with the styling, as it renders a normal HTML link.
See also
http://incepttechnologies.blogspot.ca/p/view-parameters-in-jsf-20.html (see the first technique using f:viewParam)
http://www.mkyong.com/jsf2/jsf-2-link-commandlink-and-outputlink-example/
I need to cache #{request.contextPath} into a variable so that it could used multiple times within a page. Previously while I was working with Mojarra 2.1.3, I could use ui:param for this purpose & that would cache the expression value for entire page & across all the included pages in the current page. But it doesn't work with Myfaces(see issue) reason being <ui:param> should be direct child of <ui:include> or <ui:define> to work.
I have been suggested to use c:set but I want to avoid working with JSTL tags as far as possible. What is recommended for my use case ?
Just use <c:set>. It doesn't harm anything in this particular case.
but I want to avoid working with JSTL tags as far as possible.
It look like that you don't understand why and when JSTL tags should (not) be used and thus overgeneralizes the usage of all JSTL tags in JSF as "bad" for ever. You shouldn't think that. Carefully read this answer to get enlightened: JSTL in JSF2 Facelets... makes sense?
I am trying to get the reusable group of jsf 1.2 components inside a panelgrid using Facelet tag file. #Balusc's previous answer at How to make a grid of JSF composite component? was a fabulous resource. I have a couple of followup questions:
In my c:when how do I test for the tagName itself instead of checking for the attributes. Instead of
<c:when test="#{type != 'submit'}">
I want to check tagName itself to decide how to format it. If 'input' do xxx.
2 Is this approach is still valid with jsf 1.2 other than f:ajax? If yes, can I replace with a4j:support...?
In my c:when how do I test for the tagName itself instead of checking for the attributes.
I'm not sure how this question makes sense. It sounds like that you're approaching something not entirely right. Do you maybe have copypasted exactly the same piece of code over multiple tag files? You should not do that. Make it a reuseable <ui:composition> or maybe <ui:decoration> instead which you compose/decorate in every tag file along with a fixed and unique <ui:param> value depending on the taglib file.
Is this approach is still valid with jsf 1.2 other than f:ajax? If yes, can I replace with a4j:support...?
Being able to create tag files is not necessarily specific to JSF, but to the view technology used, which is in this case Facelets. You can even do similar stuff in its predecesor JSP, see also this answer for an example: JSF 1.2 custom component from jsp:include It should work just fine in every JSF version supporting the view technology in question.
As to ajax support, it doesn't matter to the tag file what you're all doing inside the tag file. If you want and can use <a4j:support> then just do it.
I have links and pictures related to these links on my page. I want to change the pictures everytime when onmouseover event occurred in the links. I want to do this in JSF.
A lot of Thanks to everyone.
You are looking specifically for JSF to do it, or you are open to other Javascript frameworks that provide a slick and easy solution on this? For example Jquery and Dojo etc may be easy to incorporate in your application and will give Rich UI effects.
On the other hand if you are looking at JSF specifically for these UI effects than probably I can try to think of some ways and let you know.
JSF isn't designed directly to do this; It's designed to give you the tools to do this yourself. In order to do this you would need to create a custom JSF component to do this and you would use Java script to do it.
You could possibly find a JSF framework that does this already (a4j, IceFaces, etc.) but this is such a simple and well documented JavaScript thing that just tossing a little Java script among your JSF is perfectly acceptable. However, if you don't want to reinvent the wheel, take a look at those other options.
Javascript solution:
Define onmouseover event on the commandLink tag calling some kind of javascript you may give link address from like onmouseover="doSomething('addressOfImage')" then in doSomething javascript method, first find the image, then set src attribute of a default image to given address.
JSF Solution:
You might want to use a4j for this.
Add a4j:support to link for onmouseover event then just rerender graphicImage component ofcourse you need to give value of graphicImage dynamically. There is an example of using a4j support below. You can add this a4j:support between your link tags for mouseonover event. Then manage everything on backing bean to handle which image to be displayed.
example
<h:graphicImage id="imageToBeRendered" value="#{myBean.imageAddress}"/>
Just google a4j if you have no idea.