Changes
Title
unchanged
How to work with flash messages
Category
unchanged
Tutorials
Yii version
unchanged
Tags
changed
flash message, understanding
Content
changed
A flash message is used in order to keep a message in session and make sureSummary
------
Set your messages in a controller:
```php
Yii::app()->user->setFlash('success', "Data1 saved!");
Yii::app()->user->setFlash('error', "Data2 failed!");
Yii::app()->user->setFlash('notice', "Data3 ignored.");
```
Display them in your view:
```php
<?php
foreach(Yii::app()->user->getFlashes() as $key => $message) {
echo '<div class="flash-' . $key . '">' . $message . "</div>\n";
}
?>
```
Setting flash messages
--------------------
**A flash message is used in order to keep a message in session through one or several requests of the same user**. By default, it’ is removed from session after it has been displayed to the user. Therefore flash messages are available only in the current and the next requests. Flash messages are usually used in combination with HTTP redirections, because in this case there is no view, so messages can only be displayed in the request that follows redirection.
**A flash message has a name and a content** (AKA key and value). It is an entry of an associative array. The name is a string: often "notice", "success", or "error", but it can be anything. The content is usually a string. You can put HTML tags in your message if you display it raw. You can also set the message value to a number or an array: it will be serialized and kept in session like a string.
Flash messages can be set using the [setFlash()](http://www.yiiframework.com/doc/api/CWebUser#setFlash) Method of [CWebUser]. For example, if you would like to inform the user, that his changes were successfully saved, you could add the following line to your Controller:
```php
<?php
Yii::app()->user->setFlash('success', "Data saved!");
$this->redirect(array('thing/view', 'id' => 1));
```
In this example we used the key 'success'. If you want to define more than one flash messages, you will have to use different keys.
Displaying flash messages
-----------------------
To check for flash messages we use the [hasFlash()](http://www.yiiframework.com/doc/api/CWebUser#hasFlash) Method and to obtain the flash message we use the [getFlash()](http://www.yiiframework.com/doc/api/CWebUser#getFlash) Method. So showing of the flash message in a view is done by
```php
<?php if(Yii::app()->user->hasFlash('success')):?>
<div class="info">
<?php echo Yii::app()->user->getFlash('success'); ?>
</div>
<?php endif; ?>
```
These few lines of code will make a flash message with the key "success" visible to the user within a div of class "info". The message will be displayed until this or another page is (re)loaded in the browser.
If you want the flash message to appear somewhere above the content and then automatically fade out after a few seconds, you will have to add the following lines to your view:
```php
<?php
Yii::app()->clientScript->registerScript(
'myHideEffect',
'$(".info").animate({opacity: 1.0}, 3000).fadeOut("slow");',
CClientScript::POS_READY
);
?>
```
With these lines of code we register a piece of [jQuery](http://jquery.com/) (already included with YII) javascript code, using 'myHideEffect' as ID. It will be inserted in the jQuery's ready function (CClientScript::POS_READY). Due to the chainablity of jQuery the little script will run two effects on the .info DIV sequentially:
```php
.animate({opacity: 1.0}, 3000)
```
Normally this would animate the .info DIV to a full opacity within 3 seconds. But the DIV is already rendered with full opacity upon page load, so calling this effect will just cause a delay for 3 seconds.
```php
.fadeOut("slow")
```
This is the fadeOut effect which will hide the .info DIV at slow speed.
More information about the jQuery effects can be found [here](http://docs.jquery.com/Effects).
### Links
[Chinese version](http://dreamneverfall.cn/node/82)ince Yii v1.1.3, there is also a method [getFlashes()](http://www.yiiframework.com/doc/api/CWebUser#getFlashes) to fetch all the messages.
By default, fetching a message deletes it from the session. This means that a message is meant to be displayed only on the first page served to the user. The fetching methods have a boolean parameter that can change this behavior. See the API links in the previous paragraph.
### Displaying statically
So showing of the flash message defined above in a view is done by
```php
<?php if(Yii::app()->user->hasFlash('success')):?>
<div class="info">
<?php echo Yii::app()->user->getFlash('success'); ?>
</div>
<?php endif; ?>
```
These few lines of code will make a flash message with the key "success" visible to the user within a div of class "info". The message will be displayed until this or another page is (re)loaded in the browser.
If you want to always display all the flash messages, then you should add a block to your layout (by default `protected/views/layout/main.php`). Here is a more elaborate example:
```php
<?php
$flashMessages = Yii::app()->user->getFlashes();
if ($flashMessages) {
echo '<ul class="flashes">';
foreach($flashMessages as $key => $message) {
echo '<li><div class="flash-' . $key . '">' . $message . "</div></li>\n";
}
echo '</ul>';
}
?>
```
The default CSS created by the Yii script `yiic webapp` has directives for three classes of flash messages on a div tag: `flash-error`, `flash-notice`, `flash-success`.
The best way to know if some flash messages are set is to check if `Yii::app()->user->getFlashes()` is empty. Since v1.1.7, Yii keeps an associative array of the flash keys in the form `array("key1" => 0, ...)`, or `null` if not flash message is set. You can fetch this with `Yii::app()->user->getState(CWebUser::FLASH_COUNTERS)` but this is not recommended, as Yii could change this internal process.
### Displaying dynamically (with Javascript)
If you want the flash message to appear somewhere above the content and then automatically fade out after a few seconds, you will have to add the following lines to your view:
```php
<?php
Yii::app()->clientScript->registerScript(
'myHideEffect',
'$(".info").animate({opacity: 1.0}, 3000).fadeOut("slow");',
CClientScript::POS_READY
);
?>
```
With these lines of code we register a piece of [jQuery](http://jquery.com/) (already included with YII) javascript code, using 'myHideEffect' as ID. It will be inserted in the jQuery's ready function (CClientScript::POS_READY). Due to the chainablity of jQuery the little script will run two effects on the .info DIV sequentially:
~~~
[javascript]
.animate({opacity: 1.0}, 3000)
~~~
Normally this would animate the .info DIV to a full opacity within 3 seconds. But the DIV is already rendered with full opacity upon page load, so calling this effect will just cause a delay for 3 seconds.
~~~
[javascript]
.fadeOut("slow")
~~~
This is the fadeOut effect which will hide the .info DIV at slow speed.
#### Further readings (JS):
- More information about the jQuery effects can be found [here](http://docs.jquery.com/Effects).
- [Using CJuiDialog to display flash Messages in Dialogues](http://www.yiiframework.com/wiki/79/using-cjuidialog-to-display-flash-messages-in-dialogues "Using CJuiDialog to display flash Messages in Dialogues")
## Links
- [CWebUser API](http://www.yiiframework.com/doc/api/1.1/CWebUser)
- A more specific use of flash messages: [An easy way to display a success page using flash messages](http://www.yiiframework.com/wiki/172/an-easy-way-to-display-a-success-page-using-flash-messages/)