PrimeFaces growl change color dynamically
Asked Answered
T

6

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.

Together answered 16/9, 2014 at 19:55 Comment(3)
I thought it did that already according to the FacesMessage.SEVERITYPrefix
Severity only changes icon.Together
you're right. I was thinking on p:messages, not p:growlPrefix
E
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.

Esperance answered 18/9, 2014 at 1:42 Comment(3)
Thanks a lot! Works great!!! It would be awesome that this worked native from primefaces, but this solution its great.Together
It is natively supported by using the severity attribute on the growl. <p:growl severity="info">... or multiple ones. Just see the docsAlgonquin
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...Snowber
S
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.

Snowber answered 18/10, 2016 at 7:56 Comment(0)
E
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.

Esperance answered 18/9, 2014 at 1:42 Comment(3)
Thanks a lot! Works great!!! It would be awesome that this worked native from primefaces, but this solution its great.Together
It is natively supported by using the severity attribute on the growl. <p:growl severity="info">... or multiple ones. Just see the docsAlgonquin
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...Snowber
A
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

Algonquin answered 23/10, 2015 at 10:47 Comment(0)
C
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.

Cytogenesis answered 4/8, 2017 at 11:56 Comment(1)
If non of the others worked you must have some additional code that messes things up and you need this to correct it... Very strangeAlgonquin
E
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.

Esperance answered 17/9, 2014 at 9:31 Comment(4)
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?Together
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.Esperance
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.Together
If you specific your component(h:form) id that cover your p:growl the j_idt80 is not generated.Esperance
S
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();");
}
Sangfroid answered 21/4, 2017 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.