RichFaces confirmation dialog #3

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:


Let’s looks at changes for /WEB-INF/tags/confirmation.xml:






...

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:


or this:


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:


   http://richfaces.org/richx
   
	confirm
	tags/confirmation.xhtml
   
   
      concat
      function.FaceletsFunctions
      
         java.lang.String concat(java.lang.String,java.lang.String)
      
   

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:



Now it’s possible to place any number of confirmation dialog tags on the same page:




...



...



45 thoughts on “RichFaces confirmation dialog #3

  1. Sorry, the tags have been removed …
    I have removed the “<” and “/>” values, hope it works now:

    Modify the action expression of jsFunction to the following
    a4j:jsFunction name=”submit” action=”${backingBean[action]}”

    Then modify the confirm tag in the page to the following
    richx:confirm confirmId=”confirm1″ label=”Save” backingBean=”#{userBean}” action=”save”

    Now we are able to add something like
    richx:confirm confirmId=”confirm2″ label=”Delete” backingBean=”#{userBean}” action=”delete”

  2. I think we could do better. In your case, the modal panel is always in the html code.
    That’s unuseful. We could add a panelGrid with an id and use a condition on a s:div to hide the modal panel component.

  3. i made a sample, we could use :

    
        <a / rel="nofollow">
    
    
    <a / rel="nofollow">
    
    
    
    
    		un mod panel
    
    
    
    

    With this method, we could spare execution time and data transfert.

  4. Hi Max.

    I’m found a example wich you posted on url: http://www.jsfone.com/blog/max_katz/2008/11/richfaces_confirmation_dialog.html about RichFaces Dialog message, and I’m based on your post and trying run the following code:

    
    
    
    				...
    
    
    
    
    
    
    
    
    
    
    
    					    Confirmation
    
    
    
    						    &lt;!--   --&gt;
    
    
    
    
    
    
    
    
    
    
    
    

    But when the my action: #{usuario.remove} is invoked, the programm remove only the last record of datatable, if I remove the rich:modalPanel functionality it’s work fine.

    Do you have any suggestions?

    thanks

  5. Hi Max.

    I’m found a example wich you posted on url: http://www.jsfone.com/blog/max_katz/2008/11/richfaces_confirmation_dialog.html about RichFaces Dialog message, and I’m based on your post and trying run the following code (I have removed the tags “”):
    ———————–

    rich:dataTable

    rich:column width=”20%”
    f:facet name=”header”
    h:outputText value=”#{lblMsg.operacoes}”/
    /f:facet
    a4j:commandLink value=”#{lblMsg.edit}” action=”#{usuario.editSetup}” /
    h:outputText value=” “/
    a4j:commandLink value=”#{lblMsg.remove}” onclick=”#{rich:component(‘confirmation’)}.show();return false;” /
    a4j:jsFunction name=”submit” action=”#{usuario.remove}”/

    rich:modalPanel id=”confirmation” width=”250″ height=”150″
    f:facet name=”header”Confirmation/f:facet
    h:panelGrid
    h:panelGrid columns=”2″

    !– h:graphicImage value=”image/header_br.jpg” / —
    h:outputText value=”Are you sure?” style=”FONT-SIZE: large;” /
    /h:panelGrid
    h:panelGroup
    h:commandButton value=”OK” onclick=”#{rich:component(‘confirmation’)}.hide();submit();return false;” /
    h:commandButton value=”Cancel” onclick=”#{rich:component(‘confirmation’)}.hide();return false;” /
    /h:panelGroup
    /h:panelGrid
    /rich:modalPanel

    /rich:column
    /rich:dataTable

    ———————–
    But when the my action: #{usuario.remove} is invoked, the programm remove only the last record of datatable, if I remove the rich:modalPanel functionality it’s work fine.

    Do you have any suggestions?

    thanks

  6. The confirmation dialog doesn’t perform any actions, so you have to look into your method and what record it deletes. You might have to pass in the id of the record you want to delete.

  7. Hi Max,
    I am reading your post where you use dynamic backing bean and method:

    How can we modify this example in order to dynamically pass method argumends?
    I want to do something like this:

  8. richx:confirm confirmId=”confirm1″ label=”Save” bean=”#{userBean}”
    action=”save” parameter=”#{userCollection}”/>

  9. Thanks for your reply, I tried to invoke dynamically bean method and to pass an argument but without any success:
    a4j:jsFunction name=”submit” action=”#{bean[action][param]}” />
    or :
    a4j:jsFunction name=”submit” action=”#{bean[action(param)]}” />
    or even :
    a4j:jsFunction name=”submit” action=”#{bean[action[param]]}” />
    Do you have any suggestions?
    Thanks..

  10. That will not work. I meant passing it from the composite component. You might want to look at Seam, it does allow passing parameters to methods.

  11. Hi Max,

    I tried out the tag and everything works fine. But there is one problem which I couldn’t solve so far. After the Ok button has been clicked and the action has been executed it might be necessary to update parts of the “main” page. For example, I want to delete an Object inside a h:dataTable via confirmation. The dataTable will not be refreshed after delettion. I tried some “reRender” but nothing worked.

    Any suggestions?

    Thanks

  12. Hi again,

    thanks for the reply, but I don’t see how that article can help me. Perhaps I should explain a little more in detail:

    I want to update the whole table. I use the confirmation.xhtml tag. I tried to place a reRender attribute inside a4j:jsFunction which points to the rich:panel containing the table. But I think there well be no render response phase when I press the OK button. Only the action is executed and the modal panel hides.

    By the way, why do you use the combination of input tag together with a4j:jsFunction tag instead of a4j:commandButton?

    Thanks

  13. I think I found the reason why it doesn’t work. My bean which delete() action is called is a seam EntityQuery instance, and therefore I must refresh() this instance in order to perform a new query. So everything was ok with your tag and the problem was sitting in front of the computer (this is a German phrase, I hope you understand it :-)).

    Thanks

  14. I have the same case as mic501 commented on.

    I have two buttons on the same page and I am using the confirm dialog for both of them.

    Something like this:

    richx:confirm confirmId=”confirm1″ label=”Save” backingBean=”#{userBean}” action=”save”

    richx:confirm confirmId=”confirm2″ label=”Delete” backingBean=”#{userBean}” action=”delete”

    However, the first action “save” is being executed regardles which dialogs box opens.

    Any suggestions?

    Thank you.

  15. Hello,
    I have tried to execute the code and if i have more than one confirmation tags in the same page the action of the jsFuction always calls to the last method.
    I think that it occurs because the id’s of the different jsFunction are the same.

    In this case always calls delete method.

    Thanks

  16. You can confirm me that is not possible use more than one confirmation dialog in the same page with differents actions.

    So this example is not reusable completly. Do you have any suggestion?

    Thanks in advance

  17. Instead of using a4j:jsFunction, try using a4j:commandButton like this:

    Page:
    richx:confirm confirmId=”confirm1″ label=”Delete” bean=”#{userBean}” method=”delete”

    Custom tag:
    a4j:commandButton action=”#{bean[method]}”

  18. Hello Max,
    I have tried with a4j:commandButton and doesn’t work. I don’t know why but when you click on the button the application doesn’t call to the method.

    Thanks

  19. I had the same problem as Javi, needed to use different methods in different beans.

    Solved as max suggested, having the following line in confirmation.xml

    and on client side:

    Thanks to max for really usefull posts.

  20. There is no need for concat if use rich:componentControl with a4j:commandButton

    a4j:commandButton value=”confirm”
    rich:componentControl for=”confirmationBox#{confirmId}” event=”onclick” operation=”show”/
    /a4j:commandButton

    rich:modalPanel id=”confirmationBox#{confirmId}” autosized=”true”
    a4j:commandButton value=”OK'” action=”#{bean[method]}” type=”submit”
    rich:componentControl for=”confirmationBox#{confirmId}” event=”onclick” operation=”hide” /
    /a4j:commandButton
    a4j:commandButton value=”Cancel”
    rich:componentControl for=”confirmationBox#{confirmId}” event=”onclick” operation=”hide”/
    /a4j:commandButton
    rich:modalPanel

  21. @guy: thanks the posting. I’ll try to do a new post on confirmation dialog incorporating all the input from various comments.

  22. Max,

    Great tutorial; I’ve implemented everything to my specifications and based on your excellent examples.

    However, the problem I’m having is that I want the action that is performed by a4j:jsFunction to the JSF lifecycle in such a way that pages.xml (Seam) is then checked for navigation information.

    While the jsFunction approach works great, my application is not redirecting to its next destination as specified in our navigation rules.

    My options at this point seem to somehow force a manual navigation in the code-behind, or to undo the facelet component approach in favor of a ui:decorate wherein the developer would define their buttons without the need to use a4j:jsFunction.

    I would appreciate any input you have on this issue.

    Thanks.

  23. @Chris: navigation works from a4j:jsFunction, you just need to set redirect on the rule. I tested with standard JSF navigation rules but I’m assuming it should work with Seam as well.

    
    
  24. @Max,

    Max, thanks – I wonder if the problem in my situation is that I’m calling the action to be performed via method invocation; i.e.

    “submitAction” is provided in the form of a String parameter, such as “beanName.myAction”.

    I am not using the EntityHome pattern.

    Do you think that I might have the right idea about this problem?

    Thanks.

  25. Hmm, I’ll have to keep looking.

    Now that I have your attention… 🙂

    I attempted to apply this approach for confirming a data entry form and should have known it would not have been quite so easy.

    The issue I am having is that, without a postback, the default JSF form validation is not triggering.

    Where the commandLink opens the confirmation dialogue, I need to first perform JSF validation or call a method to do so. But, without an ajaxable form, the FacesMessages are being enqueued and are never displayed.

    Ideally, the dialogue would not show unless there were NO errors on the JSF form; however, in order to do so, I need to kick-off a postback – which refreshes the page and therefore means that my dialogue will never show (even if there are no errors).

    What do you think? If you have time, here is some code to ponder over.

    The component call:

    The commandLink (h:commandLink works, but then the dialogue will never show).

  26. You could try using a4j:comamndButton. On click, you would invoke validation and if validation goes through you can open the modal panel via oncomplete attribute. You can send me an email to max at exadel dot com. It’s easier than posting on the blog.

  27. Max, thanks for posting very good posts. I have implemented the above scenario and it worked fine. I have a scenario that I need to invoke spring web flow transition from confirmation.xhtml page. So for testing purpose I passed static value ‘save’ like ‘a4j:jsFunction name=”submit” action=”save”‘ and it invoked ‘save’ transition in weflow. Now I wanted to pass dynamic value for action. I tried passing like this ‘a4j:jsFunction name=”submit” action=”#{action}”‘. it didn’t work. Could you please let us know how do we pass action value dynamically from parent form.

    confirmation.xhtml code —

    main xhtml —

  28. sorry here is the code
    main.xhtml
    richx:confirm confirmId=”confirm1″ label=”Save” action=”save”
    confirmation.xhtml
    a4j:jsFunction name=”submit” action=”#{action}” i know #{action} not true

  29. Hi Max

    I have almost developed my application but look and feel is not good for that i need to use css i dont know how to use css in rich faces please send me steps to use css in our application ; as well as any example and sample css template.

    Waiting for your reply..

    I forgot to tell : “I got lot of help from this site”

    Thanks Max

  30. @max
    Great post! Really helpful for someone like me still learning.

    @guy
    THANK YOU for your code. I was having problems with multiple buttons, methods, and beans inside a rich:dataTable backed by a Seam @DataModel, but your code works great.

  31. After I initially commented I seem to have clicked on the -Notify me when new comments
    are added- checkbox and now each time a comment is added I get four emails with the same comment.
    Perhaps there is a means you can remove me from that service?

    Many thanks!

    1. There is probably a link in the email to unsubscribe from comments? I think it is linked to your own WordPress.com account. I’d check that first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s