You are viewing revision #2 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
In this short how-to I will show how to customize setFlash() to display messages (flashes) styled to be success confirmation, error report or notice information. And how to achieve displaying errors in other way.
What do we have? ¶
Yii (basic application) uses setFlash() to display messages to user. In the controller there could be a code like this:
Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
and in a view like this:
<?php if(Yii::app()->user->hasFlash('contact')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('contact'); ?>
</div>
<?php endif; ?>
But this is mainly used to display success confirmation. However, there is a quite easy way to customize this behaviour, so we can display also errors and notices as well.
Solution 1: Magical # char ¶
We can encode type of flash message inside flash itself. Here I'm doing it by changing class but this is only example, this can be done in any other way.
In the controller:
$message_text = ($overall_result === FALSE) ? 'Seems, we have an error!' : 'Everything went OK...';
$message_class = ($overall_result === FALSE) ? 'flash-error' : 'flash-success';
$flash = $message_class.'#'.$message_text;
usr()->setFlash('flash', $flash);
and in a view:
<?php
if(usr()->hasFlash('config-form-results'))
{
$flash = usr()->getFlash('config-form-results');
$pos = strpos($flash, '#');
$class = ($pos === FALSE) ? 'flash-success' : strstr($flash, '#', TRUE);
$text = ($pos === FALSE) ? $flash : substr($flash, $pos + 1);
echo('<div class="'.$class.'">'.$text.'</div>');
}
?>
Now, according to what is a boolean value of _$overallresult (where of course we can put any checking, we want), user will see either success confirmation or error message.
The above (view) code also takes care of situation if there isn't any # char in the flash. If so, it displays whole flash message with flash-success class, assuming that there is no class definition, if there is no # char.
Solution 2: Own function ¶
We can also define own function, like this:
/**
* Display error summary box.
*/
function errorSummary($content, $htmlOptions = array())
{
if(!isset($htmlOptions['class'])) $htmlOptions['class'] = 'flash-success';
return CHtml::tag('div', $htmlOptions, $content);
}
And user can specify in htmlOptions, which class to use in displaying text (flash-success, flash-error, flash-notice, all found in main.css, used by default Yii application or any other user-defined class).
This solution is easier, but it does not make any use of build in flashing feature. I.e. developer has to take his own care for transferring such message from the controller to a view.
In the controller:
$message_text = ($overall_result === FALSE) ? 'Seems, we have an error!' : 'Everything went OK...';
$message_class = ($overall_result === FALSE) ? 'flash-error' : 'flash-success';
$flash = errorSummary($message_text, array('class'=>$message_class));
$this->render('index', array('flash '=>$flash));
and in a view:
<?php
if(isset($flash)) echo($flash);
?>
That should be all.
Summary ¶
I hope this short how-to will help some Yii developers. If you find any typo or error in this text, please feel free to correct it.
3rd example
I think, that 3rd example is not true flash message, cos is not stored in Session, so it will not survive redirect. Flash messages is IMO mainly intended as post form messages. And as best practice says - always redirect after form processing.
Widget
It seems, that widget will be better solution. And it will be corresponding to DRY =)
@srigi - Redirection
@srigi: I agree with you totally! The second approach was designed to be used in controller for displaying some notifications to user - i.e. results of operation done in that controller. If you would use it for form processing or any other kind of redirection, it would be useless.
@maximus.dv10 - Widget
@maximus.dv10: The code I showed in this example is... just an example. In my real application, I have own class with this and similar functions declared as static and I'm calling them statically from whenever place I want. So, this is some kind of DRY and I personally think that using a widget for exactly this situation is a little bit waste of time - requires more coding to develop and to use it than just simple function declaration and a static call to it. Even if it isn't that professional solution as widget. Of course - this is my personal opinion and you may disagree with it! :)
Important note about a flash message life cycle
Some days ago I was managing flash message.
In the documentation it says for setFlash()
Stores a flash message. A flash message is available only in the current and the next requests.
The messge will be digested when you do a getFlash() or when you do more than 2 redirect ( in my case )
Yii-Flash
I recently submitted a very simple widget for displaying flash message.
You can download it here:
http://www.yiiframework.com/extension/yii-flash.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.