tags:

views:

52

answers:

1

I am using JSF Myfaces Impl 1.2 without tomahawk and other libs :

I am using different styles + images to show JSF Error messages, find below a sample.

<h:panelGroup rendered="${adminBean.showErrorIcon==2}">
<table width="375" align="center" class="InfoMsg" border="1"
    cellspacing="0" cellpadding="0">
    <tr>
    <td>
    <table width="375" align="center" class="InfoMsg" border="0">
        <tr>
            <td width="50"><img src="static/images/info_icon.gif"
                width="40" height="40" border="0" /></td>
            <td width="325" align="left"><h:messages layout="table"
                errorClass="InfoMsg" /></td>
        </tr>
    </table>
    </td>
</tr>
</table>

Based on the int variable of the Backing Bean , I am displaying a diff image and the corresponding FacesMessage(s) in the screen - only 2 cases - error or an information.

I am using the below code to set the variable of the Backing Bean

//Checking if there are messages!
    log.debug("Checking if there are messages to be shown ]");
    if(getShowErrorIcon()==99){//Set only if the value is still the default :
        log.debug("getShowErrorIcon was DEFAULT - Changing it ]");
        Iterator<FacesMessage> messages = FacesContext.getCurrentInstance().getMessages();
        if(messages != null && getShowErrorIcon()==99){//Set Error/Info for messages that are not added here :
            while(messages.hasNext()){
                log.debug("There are ***messages***");
                FacesMessage aMessage =(FacesMessage) messages.next();
                if(aMessage.getSeverity().compareTo(FacesMessage.SEVERITY_ERROR)==0){
                    setShowErrorIcon(1);
                    break;//just once is enough
                }
                if(aMessage.getSeverity().compareTo(FacesMessage.SEVERITY_INFO)==0){
                    setShowErrorIcon(2);
                    break;
                }
            }
        }
    }//if it is not default, then something has been set already, why again?

Now the problem I have is , There are FacesMessage(s) that are added by the MyFacesImpl - like the required=true and the custom validator messages which are added during PROCESS_VALIDATION Phase, These are not shown in the screen since my integer variable of the Backing Bean is not set , and since the INVOKE_APPLICATION Phase was not called (and that means the above code was not called!!!)

How do I resolve this? Or Whats the best way / Where's the best place to place the above checking code ?

Appreciate your help.Thanks!

+3  A: 

I'm not sure, but this all look like unnecessarily overcomplicated. To change icons/styles based on the message severity, just make use of the CSS powers. You can specify different CSS classes based on message severity using infoClass and errorClass attributes of the <h:messages> and you can specify the icons as CSS background image.

JSF:

<h:messages id="messages" layout="table" infoClass="info" errorClass="error" />

CSS:

#messages .info td {
    background: url('info.gif') no-repeat left center;
    padding-left: 15px;
}
#messages .error td {
    background: url('error.gif') no-repeat left center;
    padding-left: 15px;
}

The <h:messages layout="table"> itself already renders a HTML <table>. I think the whole table around it is unnecessary as well. Just apply styles accordingly the usual CSS way.

#messages {
    width: 375px;
    margin: 0 auto;
    border: 1px black solid;
    border-collapse: collapse;
}

See also:


Update: as per the comments, you're looking for something like this:

<h:messages layout="table" styleClass="messages info" infoClass="info" errorClass="error" />
<h:messages layout="table" styleClass="messages error" infoClass="info" errorClass="error" />

with CSS:

.messages {
    width: 375px;
    margin: 0 auto;
    border-collapse: collapse;
    border: 1px black solid;
}
.messages.info {
    background: url('info.gif') no-repeat left center;
}
.messages.error {
    background: url('error.gif') no-repeat left center;
}
.messages.info tr.error, .messages.error tr.info {
    display: none;
}
.messages td {
    padding-left: 15px;
}

This shows two separate message tables, one for info and other for error messages, each with a single icon on the left center.

BalusC
Thanks BalusC. But Every FacesMessage is added in a single Row inside a new <tr> and so the icons are shown as many messages are there. Is it even possible to control the table that JSF renders in css ? - like to put a single TD inside the table (for the image) and provide a corresponding colspan based on the number of messages? Are there any alternate thoughts?
gurupriyan.e
Ah yes, I now understand the functional requirement. That's doable with just CSS as well. I'll edit the CSS accordingly.
BalusC
Thanks BalusC. I will try that sometime later. I did a trick, I added the above code in the Original question in the getter of ShowErrorIcon and returned 1 or 2 based on the messages in the Context. This worked like a Charm. I had to find a spot the code wherein will definitely execute before the screen is rendered.I'll update if I face any problems. Btw , Do you see any problem here? doing this way?
gurupriyan.e
Well, controlling the layout in the bean and duplicating the view code is a bit clumsy. I'd prefer CSS for that. You can for instance instead use `<table class="${bean.error ? 'error' : 'info'}">` and stick to one table. [DRY!](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
BalusC
Accepting this answer because what I was doing is not a best-practice or is a true JSF way.
gurupriyan.e