4

Is there a way to change dynamically the background of the PrimeFaces growl component? I want to be able to show a red background when it's an error and a green background when is a success.

Thanks in advance.

Tiny
  • 27,221
  • 105
  • 339
  • 599
Daniel Rojas
  • 407
  • 2
  • 5
  • 16

6 Answers6

7

The above solution only works if you add only one message at a time to the context. If you add more than one message, all the growl items will be colored by the last message's severity. Please follow the link below for furher details about the issue.

(Turkish content, you may need to translate it)
Change PrimeFaces growl background color dynamically

In order to solve this problem, you should find growl items by icon style (PrimeFaces changes only growl icons for different severity levels) and add a custom stylesheet class to the grand-parent of the growl icon's html element in order to achieve different background colors.

First define the script below (which adds custom css classes to the grand-parents):

<script>
   function init () { 
      $(".ui-growl-image-info").parent().parent().addClass("g-info");
      $(".ui-growl-image-warn").parent().parent().addClass("g-warn");
      $(".ui-growl-image-error").parent().parent().addClass("g-error");
      $(".ui-growl-image-fatal").parent().parent().addClass("g-fatal");
   }
</script>

and add the below style definition to your page:

<style>
    div[id="growlForm:growl_container"] > div[class~="g-fatal"] {
    background-color: black !important;
    }

    div[id="growlForm:growl_container"] > div[class~="g-error"] {
    background-color: red !important;
    }

    div[id="growlForm:growl_container"] > div[class~="g-warn"]{
    background-color: orange !important;
    }

    div[id="growlForm:growl_container"] > div[class~="g-info"]{
    background-color: green !important;
    }

    .ui-growl-image-info ~ .ui-growl-message {
    color:#fff;
    }
    .ui-growl-image-error ~ .ui-growl-message {
    color:#fff;
    }
    .ui-growl-image-warn ~ .ui-growl-message {
    color:#fff;
    }
    .ui-growl-image-fatal ~ .ui-growl-message {
    color:#fff;
    }
 </style>

And finally, attach init() method to the element which adds messages to the context.

<p:commandButton value="Show" actionListener="#{someBean.someMethod}" oncomplete="init();"/>

And the result is :)

Dynamic Growl Background Color in PrimeFaces

Source Code of the Project

Hope this helps anybody.

ngc4151
  • 442
  • 9
  • 21
5
<style>
        div[id="forma:growl-error_container"] > div {
            background-color: red !important;
        }
        div[id="forma:growl-success_container"] > div{
            background-color: green !important;
        }
    </style>
    <h:form id="forma">           
        <p:growl id="growl-error" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 2}"/> 
        <p:growl id="growl-success" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 0}"/> 
        <p:panel header="Growl">  
            <h:panelGrid columns="2" cellpadding="5">  
                <p:outputLabel for="msg" value="Message:"/>   
                <p:inputText id="msg" value="#{growlView.message}" required="true" />  
            </h:panelGrid>  

            <p:commandButton value="Save" actionListener="#{growlView.saveMessage}" update="@form" />  
        </p:panel>     
    </h:form> 

This is group of code which is used to demonstrated.

wittakarn
  • 3,124
  • 1
  • 18
  • 31
  • 1
    Thanks a lot! Works great!!! It would be awesome that this worked native from primefaces, but this solution its great. – Daniel Rojas Sep 26 '14 at 19:59
  • It **is** natively supported by using the severity attribute on the growl. `... ` or multiple ones. Just see the docs – Kukeltje Oct 23 '15 at 10:40
  • If you add more than one message to the context, let's say 2 (first one's severity info, the second one's danger) all growl elements will be the same (colored by the last message's severity -danger for our example). So the above solution is incorrect! Please see my answer... – ngc4151 Oct 18 '16 at 07:37
2

You can do this by using the severity attribute on the growl

<p:growl id="myInfo" severity="info"/>
<p:growl id="myError" severity="error"/>

#myinfo {
    background-color: blue;
}
#myerror {
    background-color: red;
}

But adding a styleClass based on

But if you just want to style the text in it, you can use one growl and use css sibbling selectors

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
1

For those who still have the problem, and need a quick easy fix, the way I solved it was by changing the background color using the following code (I used angular and TS... ):

this.msgs.push({severity:'success', summary:'success', detail:'it worked'});
setTimeout(()=> { document.getElementById('*the ID*').children[0].children[0].setAttribute('style', 'background-color:green');
}, 10);

It is not the best solution, but none of the above ones worked, and it is good enough for me.

  • If non of the others worked you must have some additional code that messes things up and you need this to correct it... Very strange – Kukeltje Aug 04 '17 at 13:14
0

You should try to add CSS that you want.

<style>
        div[id="forma:growl-error_container"] > div {
            background-color: red !important;
        }
        div[id="forma:growl-success_container"] > div{
            background-color: green !important;
        }
</style>

After that, using EL for swapping between success and error.

<p:growl id="growl-error" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 2}"/> 
<p:growl id="growl-success" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 0}"/>

Hope this help.

wittakarn
  • 3,124
  • 1
  • 18
  • 31
  • Thanks a lot for your answer. The only part I don't understand is: div[id="forma:growl-success_container"] What exactly is forma? what do i have to write instead of that? – Daniel Rojas Sep 17 '14 at 17:18
  • The forma is a form that contain p:growl inside of its. Thus, The forma:growl-success_container is an id of growl component, you can use view page source that can get correct id. – wittakarn Sep 18 '14 at 01:51
  • Thanks a lot for your help. I think my growl id is being generated dinamically. I think it is this. j_idt80:messages_container. But I am afraid the j_idt80 is dinamically generated. – Daniel Rojas Sep 23 '14 at 20:04
  • If you specific your component(h:form) id that cover your p:growl the j_idt80 is not generated. – wittakarn Sep 24 '14 at 01:07
0

I spent three hours today with a colleague trying to figure out why the other answers here were not working. Turns out our system needed the HTML file to include CSS and JS from an external file. Not with tags! So this is what worked for us. For our project we have a folder named "css" and a folder named "js" in the main directory.

Below is the relevant code for the HTML body:

<h:outputStylesheet name="css/styles.css" />
<h:outputScript library="js" name="growlColour.js" />

<p:growl id="growlC" autoUpdate="true" showDetail="true" sticky="true" />

<p:commandButton id="buttonC" action="#{bean.methodC}" oncomplete="growlColour();" />

methodC on the backing java bean instantiates a growl message:

public void methodC() {
    String x = "message goes here";
    FacesContext context = FacesContext.getCurrentInstance();
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", x));
}

Obviously you can change the severity which will change the colour given the following code. The growl message is modified by the JS applying a CSS class to the correct growl message object.

styles.css:

.g-info {
    background-color: green;
}
.g-warn {
    background-color: red;
}
.g-error {
    background-color: red;
}
.g-fatal {
    background-color: black;
}

growlColour.js:

function growlColour() {
    $(".ui-growl-image-info").parent().parent().addClass("g-info");
    $(".ui-growl-image-warn").parent().parent().addClass("g-warn");
    $(".ui-growl-image-error").parent().parent().addClass("g-error");
    $(".ui-growl-image-fatal").parent().parent().addClass("g-fatal");
}

That's the simplest and most robust way of doing it, I think.

EDIT: Sometimes oncomplete doesn't work, for example if ajax is set to false. What seems to be the best solution for all cases is NOT to call JS via JSF. Instead, add this line of code right after you create the message in the backing bean:

public void methodC() {
    String x = "message goes here";
    FacesContext context = FacesContext.getCurrentInstance();
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", x));
    RequestContext.getCurrentInstance().execute("growlColour();");
}