Displaying and Rerendering a RichFaces ModalPanel from a commandLink

Let’s say that when a user clicks on something, perhaps selecting something from a DataTable or DataGrid, you want to call some server side code, and then popup a modal panel which needs to show content based on the new state setup by your server side call. In my case I have a DataGrid showing a number of items, and when a user clicks on an item I want to set the current selected item on a Seam component on the server, and then popup a modal panel to display detailed information about the item, and provide the user some actions within the modal panel.

Looking at the solution it seems so simple, but for some reason it took me hours of trying different combinations, orders, tags, JavaScripts, etc… before I could get this to work correctly. I had the panel appearing with the old data, or appearing with the old data and then disappearing completely, only to show the so called new data the next time I clicked on an item, or rendering on the page itself below the footer, or not popping up at all, or popping up with null data, or…. So I’m posting it up here for myself and anyone else who runs into issues.

First, create your modal panel (rich:modalPanel). I do this in a separate .xhtml file, as I will use the same model panel in various pages throughout the site. In your modal-panel.xhtml file (or whatever you choose to name it), start with a <ui:composition> tag, define your RichFaces xml namespace (and any other JSF libs you’ll be using), and then setup your <rich:modalpanel>

You need to give the modalPanel a unique id, in this case we’ll call it “myModalPanel”.

<rich:modalpanel id="myModalPanel" autosized="true" zindex="2000">

Inside your modalPanel tag, you need to define an inner div. This is the div which you will be rerendering after the server action is complete. I use tags, as I’m using Seam. Ensure that any references to backing beans or data that you want refreshed are within these div tags. You must give this div a unique id as well, in this case we’ll call it “myModalDiv”.

<s:div id="myModalDiv">

The one limitation that I’ve run into here, and if you know how to solve this, please let me know, is that the <f:facet> tags for your header text and controls can’t be inside this div, and you can’t put the div around the whole modalPanel (or it makes the panel disappear when you rerender). As such you can’t make anything from the <f:facet>s be updated on rerender. This is preventing me from having the modal panel header displaying the current selected item’s name. Not great, but not the end of the world.

So inside this div you have your dynamic output. I have lots of <h:outputtext value="#{backingBean.selectedItem.property}"> type entries in mine.

On your actual page where you will be displaying the modal panel from you need to include the modal-panel.xhtml file, I use a:

<a:include viewid="/modal-panel.xhtml">

Then, I have my page, which includes a rich:dataGrid, and inside it has an <a:commandLink> which creates the AJAX clickable item. This commandLink has to call the backend action, display the modal panel, and rerender your div.

<a:commandlink id="showItem" action="#{backingBean.setSelectedItem(item)}" oncomplete="Richfaces.showModalPanel('myModalPanel',{width:550, top:200});" rerender="myModalDiv">
Click Here!
</a:commandlink>

This makes the panel display, and then the new content is rendered in the panel. It seems to work just how I wanted it to. With the minor annoyance of having to use a static modalPanel header.

81 thoughts on “Displaying and Rerendering a RichFaces ModalPanel from a commandLink

  1. can you explain with the example..Iam displaying data through modal panel and cannot pass the data when action is called..telling java.El exception…

  2. Hi Devon,
    I wanted to dynamically load an image to a model panel and display it. I’m not sure how I can pass the url of the image dynamically(i.e if when user clicks on the thumbnail of the image the original image should be displayed). Can you please help me on this?

    Thank You,
    Chamila

    • Chamila,

      you mean you want the full size version of the image to appear in the modal? I’ve done exactly that and it’s pretty straight forward. Just use the example code in this posting, and have your backing bean hold the selected image: backingBean.setSelectedImage(image) and then in the modal reference the image path. How you represent the image location is up to you, you could just path the raw path in, or if you have the images managed by your application you can build a constructed path using data from your image item, or reference a servlet path that will serve back image data from the DB.

      In my usage I’m using application managed images (i.e. uploaded by users or generated from videos) which are handled by a servlet, so I reference the full size image within the modal like this:

      <img src="#{facesContext.externalContext.requestContextPath}/image/#{backingBean.selectedImage.id}.jpg" />

      Where /image/ maps to my servlet.

      If you’re just referencing an image on the file system you can pass the full image path to the backing bean and just include that.

      Make sense?

      Devon

  3. Hi Devon,
    I want to pass a radio button value from my modalPanel page to bean.However I am not able to pass the same.
    My code for the modalPanel page is as follows:

    The backing bean method is getting invoked but the radio button value is not getting passed.

    • It looks like my comment system is eating all your markup. Can you either escape it or just e-mail it to me?

      Also: anyone know how to make WordPress comments NOT eat markup?

  4. HI Devon,

    The ‘problem’ you mentioned in you blog of the static content you can’t control dynamicly can be solved.

    I have a solution where my size ( with and height) is variable, the same for the title and an include.

    If you are interested I will post i’t on my blog ( in English ofcourse).

    Greetz,

    Jan-Martijn Wijnholds

  5. Hi Devon,

    now I have do determing the popup dynamically rather than above static code, which specifies, when the popup should display.
    I want to decide if the popup should be displayed or not on the action saveOrUpdateServiceContract.

  6. I dont want to use oncomplete=”Richfaces.showModalPanel(‘myModalPanel’,{width:550, top:200});” in the xhtml but can i invoke the popup from the controllers action which backingBean.saveOrUpdateServiceContract

  7. Hi ,
    I have s:file upload tag in my jsp.and one sx:autocompleter tag.
    if i change the element in sx:autocompleter the ajax to work.
    But the s:file tag is preventing not to work ajax properly.
    Can you give me some idea.Pls…..
    Im trying this for past one week…..
    Thanks in advance.

  8. Hi Devon,

    I need a help with one situation.
    In my case the bean can open a modal panel or redirect to other bean page.
    The situation of open the modal is ok, but i’m have some problems with the redirection, can you give me some suggestion?

    Thanks and regards.

  9. I seem to be having a problem where I get a js error only on the first load of the page or if I clear the browser cache. ‘ModalPanel.Sizer.INITIAL_MIN’ is null or not an object . At first I thought it was my rerender until I changed to rerender the specific outputText id.

    Add/Change feature validation failure

    Strange part is after initially hitting it, there after it works no problem. I’m not using the div but I imagine it won’t matter since I just have the outputText I’m rerendering prior to popping this. Code that shows it is:

    oncomplete=”if(data != null && data != ”){#{rich:component(‘changeFeatureModalPanel’)}.show()};” />

    This part functions fine after reloading the page. I have many other modals experiencing the same thing. I have an older version of modal done this way in another app, on older version of richfaces that seems to work fine. But this version is inside a jetspeed portlet. I tried upgrading to richfaces 3.3.3.Final, but same issue persists.

    Thanks for looking!

    • Looks like it doesn’t like me posting my code snippet. Let me try again with just the important parts..

      Add/Change feature validation failure

      • Guess it’s the greater/less thans:

        rich:modalPanel id=”changeFeatureModalPanel” width=”300″ height=”100″

        f:facet name=”header”>Add/Change feature validation failure

        h:panelGrid columns=”1″
        h:outputText id=”changeFeatureModalText”
        value=”#{changeFeatureBean.changeFeatureValidationMessage}”

        a4j:commandButton value=”OK” reRender=”tab1,fm1″
        onclick=”#{rich:component(‘changeFeatureModalPanel’)}.hide()”

  10. Hi Devon,

    I have similar architecture as you explained but not sure why modal panel is not getting displayed.. whenever I click on command link page gets adjusted but requested modalPanel is not appearing.. Do I need any specific settings at parent xhtml level?

  11. Hai !

    I want to develop a web page, i have three links like home,about us and contact us so my question is when we click on link one of three but view the linked page in same page by using facelets without forwarding next page. just like tiles framework in struts header and footer could be configured only once but not all web pages. how it is possible///

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>