views:

350

answers:

3

I'd like to be able to make an Ajax call using JSF/Seam/RichFaces and have the page update with the relevant h:messages component. That works with no problem. I'm able to perform the appropriate reRender. However, I'd also like to be able to make use of rich:effect to make it a bit prettier. Ideally, I'd like to be able to have the messages fade in and then disappear when the user clicks on them. However, I've been unable to get this working thus far.

Has anyone gotten such a scenario working? Does anyone who knows JSF/Seam a bit better than me have any good advice? Thanks in advance!

+3  A: 

I do exactly that although I don't bother with rich:effect.

I use jQuery. It's personal preference but I find it much easier and direct than using rich:effect (which is based on Scriptaculous). It's worth having a quick look at the jQuery Effects documentation.

An example:

Add jquery to your page (ships with richfaces):

<a:loadScript src="resource://jquery.js"/>

Assign jQuery to $j for convenience (add this to your javascript):

$j = jQuery.noConflict();

Messages Div:

<a:outputPanel id="messagetextPanel" ajaxRendered="true" layout="block" style="z-index:100; display:none;">
    <s:div styleClass="messagetext" rendered="#{not empty facesContext.maximumSeverity}">
        <h:messages infoClass="infomessage" errorClass="errormessage" warnClass="warningmessage" layout="list" />
        <s:div styleClass="messageClose">
            <a onclick="hideMessages();">#{messages['messages.close']}</a>
        </s:div>
    </s:div>
</a:outputPanel>

Some javascript to hide and show the div:

function hideMessages() {
  $j("div#messagetextPanel").fadeOut("slow");
}
function showMessages() {
  $j("div#messagetextPanel").fadeIn("fast");
}

Now you just have to figure out the best way to call the showMessages() when completing a call (eg. use oncomplete on your a4j:commandButton etc).

Personally I prefer to not have an effect on the showing of the div so that I can use ajaxRendered to handle everything. You can do this by replacing the first line with:

<a:outputPanel id="messagetextPanel" ajaxRendered="true" layout="block" style="z-index:100; display: #{empty facesContext.maximumSeverity ? 'none' : 'block'};">

This way I don't have to have any code on my button/link/support and the FacesMessages will always be displayed when my Back-end code decides to create one.

Damo
A: 

Thanks for your suggestion, Damo. I tried it and it worked with no problem. Additionally, I was able to solve it using rich:effect. Here's what I came up with:

            <a:outputPanel id="message-panel"
            onclick="hideMessages({delay:0.5,duration:0.9});">
                <h:messages id="messages" globalOnly="true" styleClass="message"
                    errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
                    rendered="#{showGlobalMessages != 'false'}" />
            </a:outputPanel>
                <rich:effect name="hideMessages" for="message-panel" type="Fade" />

...

            <h:form>
                <a:commandLink action="#{myAction.runTest()}" value="Run Test"
                    reRender="message-panel" />
            </h:form>

Once I did this, everything worked as expected.

Shadowman