Using CakePHP's Session component we can display a flash message after a redirect(). It provides an elegant way of informing a user what happened after the page refresh. For example, when the user saves a post, you can inform the user that the post has either been saved correctly, or that is has failed to do so. To make the user more aware of this message we show in this tutorial how to add CSS styling to the flash message and to provide a much more elegant way of displaying these flash messages, we show how to let the message fade in and out. We are going to use a combination of CSS and jQuery. We will make use of the animate.css package as provided by Daniel Eden. For some nice icons, we will use the font-awesome library a well.
Curious for the final result? Click here to see a demo.
For this tutorial, we will make use of the following tools:
In your Controller, normally you would only use the first argument of the setFlash function of the Session component. We expand on the default behaviour by adding a second argument which refers to an Element we are going to use to display the Flash message.
$this->Session->setFlash('Item successfully saved', 'flash_success);
Create the Element file /app/View/Element/flash_success.ctp and give it the content as shown below. Note that we have used here for the styling the Bootstrap framework, but you could in principle set your own styling.
<div class="alert alert-success alert-hover" id="flash_success">
<button class="close">x</button>
<i class="fa fa-check"></i> <?php echo $message; ?>
</div>
<script type="text/javascript">
$('#flash_success').addClass('animated fadeInDown');
$( ".close" ).click(function() {
jQuery('#flash_success').removeClass('fadeInDown');
jQuery('#flash_success').addClass('fadeOutUp');
});
</script>
Let's go through the code. The first four lines generate the message. Lines 6-12 is where the magic happens. When the document is loaded, jQuery automatically adds two CSS styles to the div block in line 1. Note that the #flash_success identifier refers to the id attribute of the div. Then, a function is added which triggers when the user clicks on the button with the 'close' class. The function then removes the fadeInDown class and adds the fadeOutUp class.
The only thing left to do is to define then the fadeInDown and fadeOutUp classes and the animated class that goes along with it. These are redefined in animate.css as provided by Daniel Eden, but we will only copy those classes from there which we are actually using. Put the following in app/webroot/css/animate.css:
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
@-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-20px);
-ms-transform: translateY(-20px);
transform: translateY(-20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}
.fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
}
@-webkit-keyframes fadeOutUp {
0% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
}
}
@keyframes fadeOutUp {
0% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-20px);
-ms-transform: translateY(-20px);
transform: translateY(-20px);
}
}
.fadeOutUp {
-webkit-animation-name: fadeOutUp;
animation-name: fadeOutUp;
}
Don't forget to link to font-awesome for the icons and to the jQuery library in your layout file (app/View/Layout/Default.ctp):
echo $this->Html->css('animate.css');
echo $this->Html->css('font-awesome.min');
echo $this->Html->script('jquery.min.js');