As one reader pointed out here, reusing Facelets custom tag confirmation dialog wasn’t possible because the component id was hard coded. Placing more than one tag on a page would give duplicate id error. I will show you how to pass an id to the custom. Once we can do that, it’s possible to place any number of confirmation dialog tags on the same page.
We are going to add confirmId attribute to the custom tag to pass the id:
<richx:confirm confirmId="confirm1" label="Save" action="#{userBean}" />
Let’s looks at changes for /WEB-INF/tags/confirmation.xml:
1 2 3 4 5 6 7 8 | <a4j:commandButton value="#{label}" onclick="#{rich:component(richx:concat(confirmId,'confirmation'))}.show();return false" /> <a4j:jsFunction name="submit" action="#{action.save}" /> <rich:modalPanel id="#{confirmId}confirmation" width="250" height="150"> ... </rich:modalPanel> |
The changes are on line 2 and 6. Looking at line 6 first, that’s where we prepend the id. This allows to give a unique id to the modal panel. Looking at line 2. That’s where the modal panel is opened. Unfortunately the following will not work:
<a4j:commandButton value="#{label}" onclick="#{rich:component(#{confirmId}'confirmation'))}.show();return false" />
or this:
<a4j:commandButton value="#{label}" onclick="#{rich:component(confirmId'confirmation'))}.show();return false" />
To solve this problem, we need to create a Facelets function to concatenate two strings into id string.
To keep things simple, we are going to add the Facelets function to the same tag lib file:
<facelet-taglib> <namespace>http://richfaces.org/richx</namespace> <tag> <tag-name>confirm</tag-name> <source>tags/confirmation.xhtml</source> </tag> <function> <function-name>concat</function-name> <function-class>function.FaceletsFunctions</function-class> <function-signature> java.lang.String concat(java.lang.String,java.lang.String) </function-signature> </function> </facelet-taglib>
FaceletsFunctions class looks like this:
package functions; public class FaceletsFunctions { public static String concat(String a, String b) { return a+b; } }
If you want, you can use something more interesting such StringUtils join function as shown here. That’s basically it. One other thing we need to change is links to close the modal panel to use this function:
<input type="button" value="OK" onclick="#{rich:component(richx:concat(confirmId,'confirmation'))}.hide(); submit(); return false;" /> <input type="button" value="Cancel" onclick="#{rich:component(richx:concat(confirmId,'confirmation'))}.hide();return false" />
Now it’s possible to place any number of confirmation dialog tags on the same page:
<h:outputText value="Text:"/> <h:inputText value="#{userBean.text}" /> <richx:confirm confirmId="confirm1" label="Save" action="#{userBean}" /> ... <h:outputText value="Text:"/> <h:inputText value="#{userBean.text}" /> <richx:confirm confirmId="confirm2" label="Save" action="#{userBean}" /> ... <h:outputText value="Text:"/> <h:inputText value="#{userBean.text}" /> <richx:confirm confirmId="confirm2" label="Save" action="#{userBean}" />