The simple solution is to create a model form, controller and view to display your alert and then use AJAX to display the message.
First, we will add a DIV
container with an id of jquery-alert-message-container
to our main layout (line 6
) views/layouts/main.php
. This is so that all pages that use this main layout can use this area to display our alert message.
<div class="container">
<?= Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<div id="jquery-alert-message-container"></div>
<?= Alert::widget() ?>
<?= $content ?>
</div>
In the site controller we will add a new action called alert
. If you are using yii\filters\AccessControl
, set permission so everyone has access to this action.
/**
* Renders Yii Alert notification
* @return string
* @throws ServerErrorHttpException
*/
public function actionAlert()
{
if (Yii::$app->request->isAjax)
{
$model = new JqueryAlertForm();
if ($model->load(Yii::$app->request->post()))
return $this->renderAjax('_alert', ['model' => $model]);
}
throw new ServerErrorHttpException('Illegal http call');
}
This is the model form we are using for the alert. For the purpose of this demo is called frontend\models\JqueryAlertForm.php
<?php
namespace frontend\models;
use Yii;
use yii\base\Model;
/**
* JQuery Alert form
*
* @property string $alert_class
*/
class JqueryAlertForm extends Model
{
const TYPE_DANGER = 'danger';
const TYPE_INFO = 'info';
const TYPE_SUCCESS = 'success';
const TYPE_WARNING = 'warning';
public $message;
public $type;
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'message' => 'Message',
'type' => 'Type',
];
}
public function getAlert_class()
{
if ($this->type == self::TYPE_DANGER)
return 'alert-danger';
if ($this->type == self::TYPE_WARNING)
return 'alert-warning';
if ($this->type == self::TYPE_SUCCESS)
return 'alert-success';
return 'alert-info';
}
public static function getTypeList()
{
return [
self::TYPE_DANGER => 'Danger',
self::TYPE_INFO => 'Info',
self::TYPE_SUCCESS => 'Success',
self::TYPE_WARNING => 'Warning',
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[
[
'message',
'type',
],
'required'
],
[
[
'message',
'type',
],
'string'
],
[
'type',
'in',
'range' => array_keys(self::getTypeList())
]
];
}
}
Finally, we render the alert using this view frontend/views/site/_alert
:
<?php
use yii\bootstrap\Alert;
/* @var $model frontend\models\JqueryAlertForm */
echo Alert::widget([
'options' => [
'class' => $model->alert_class,
],
'body' => $model->message,
]);
Now lets create a view to use our new alert. To do this we just need one line of JavaScript. Line 45
, calls our site/alert
action and passes the message and message type as a POST
and then loads the result into the jquery-alert-message-container
DIV
.
<?php
use frontend\models\JqueryAlertForm;
use rmrevin\yii\fontawesome\FAS;
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model frontend\models\JqueryAlertForm */
$this->title = 'JQuery Alert';
$this->params['breadcrumbs'][] = ['label' => $this->title, 'url' => ['jquery-alert']];
?>
<div class="jquery-alert-form">
<h1><?= Html::encode($this->title) ?></h1>
<p>Enter your message and select the message type:</p>
<div class="panel panel-primary">
<?php
$form = ActiveForm::begin(['id' => $model->formName()]);
?>
<div class="panel-body">
<?php
echo $form->field($model, 'message')->textInput();
echo $form->field($model, 'type')->dropDownList(JqueryAlertForm::getTypeList());
?>
</div>
<div class="panel-footer clearfix">
<div class="form-group">
<?= Html::submitButton('Display Alert '.FAS::icon(FAS::_BELL),
['class' => 'btn btn-primary', 'name' => 'jquery-alert-button']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php
$js = <<<JS
// Handles submit action
$(document).on("beforeSubmit", 'form#JqueryAlertForm', function()
{
$('#jquery-alert-message-container').load('/site/alert', {'JqueryAlertForm[message]': $('#jqueryalertform-message').val(), 'JqueryAlertForm[type]': $('#jqueryalertform-type').val()});
return false;
});
JS;
$this->registerJs($js);
This is the site controller used to render the above view:
/**
* Example of JQuery Alerts
* @return string
*/
public function actionJqueryAlert()
{
$model = new JqueryAlertForm();
return $this->render('jquery-alert', ['model' => $model]);
}