Yii2, форма обратной связи во сплывающем (модальном) окне

Пример будет реализован на Yii2 basic, для внедрения его на Yii2 advanced необходимо сменить локацию файлов соответствующую шаблону advanced и namespace (особых трудностей это вызвать не должно).

Устанавливаем Yii2 basic, Как установить Yii 2 basic, краткая инструкция.

Форма обратной связи во всплывающем окне будет работать на каждой странице сайта, поэтому реализуем виджет который будет инициализировать модель ContactForm, отправлять сообщение в случае правильного заполнения формы и сообщать об отправке пользователю (посетителю сайта).

Создаем класс виджет app/components/FBFWidget.php со следующим содержимым:

  1. <?php
  2.  
  3. namespace app\components;
  4.  
  5. use Yii;
  6. use yii\base\Widget;
  7. use app\models\ContactForm;
  8.  
  9. class FBFWidget extends Widget
  10. {
  11.  
  12. public function run()
  13. {
  14. $model = new ContactForm();
  15. if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
  16. Yii::$app->session->setFlash('contactFormSubmitted');
  17. }
  18. return $this->render('fbfWidget', [
  19. 'model' => $model,
  20. ]);
  21. }
  22.  
  23. }

Содержимое класса виджета FBFWidget - простой виджет с кодом инициализации, проверки и отправки формы обратной связи, код практически идентичен содержанию метода (экшена) actionContact класса (контроллера) SiteController (app/controllers/SiteController.php).

Далее создадим представление (view) для виджета app/components/views/fbfWidget.php:

  1. <?php
  2.  
  3. use yii\helpers\Html;
  4. use yii\bootstrap\ActiveForm;
  5. use yii\captcha\Captcha;
  6.  
  7. ?>
  8.  
  9. <?php if (Yii::$app->session->hasFlash('contactFormSubmitted')) { ?>
  10.  
  11. <?php
  12. $this->registerJs(
  13. "$('#myModalSendOk').modal('show');",
  14. yii\web\View::POS_READY
  15. );
  16. ?>
  17.  
  18. <!-- Modal -->
  19. <div class="modal fade" id="myModalSendOk" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  20. <div class="modal-dialog" role="document">
  21. <div class="modal-content">
  22. <div class="modal-header">
  23. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
  24. <h4 class="modal-title" id="myModalLabel">Feedback form</h4>
  25. </div>
  26. <div class="modal-body">
  27. <p>Thank you for contacting us. We will respond to you as soon as possible.</p>
  28. </div>
  29. <div class="modal-footer">
  30. <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35.  
  36. <?php } ?>
  37.  
  38. <!-- Modal -->
  39. <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  40. <div class="modal-dialog" role="document">
  41. <div class="modal-content">
  42.  
  43. <?php $form = ActiveForm::begin(['id' => 'contact-form']); ?>
  44.  
  45. <div class="modal-header">
  46. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
  47. <h4 class="modal-title" id="myModalLabel">Feedback form</h4>
  48. </div>
  49. <div class="modal-body">
  50.  
  51. <?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?>
  52.  
  53. <?= $form->field($model, 'email') ?>
  54.  
  55. <?= $form->field($model, 'subject') ?>
  56.  
  57. <?= $form->field($model, 'body')->textarea(['rows' => 6]) ?>
  58.  
  59. <?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
  60. 'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
  61. ]) ?>
  62.  
  63. </div>
  64. <div class="modal-footer">
  65. <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
  66. <?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>
  67. </div>
  68.  
  69. <?php ActiveForm::end(); ?>
  70.  
  71. </div>
  72. </div>
  73. </div>

Представление содержит два простых модальных окна bootstrap. Первое содержит сообщение об успешной отправки и автоматически выводится при отправке, второе содержит саму форму обратной связи (код формы идентичен форме из представления contact (app/views/site/contacts.php)).

Далее в основном макете (app/views/layouts/main.php) добавляем инициализацию виджета и ссылку (или кнопку) для вызова всплывающего (модального) окна с формой обратной связи.

Добавляем в use виджет с формой обратной связи:

  1. use app\components\FBFWidget;

Добавляем (меняем) ссылку для вывода всплывающего окна с формой обратной связи в меню (Nav::widget):

  1. ['label' => 'Contact', 'url' => '#', 'options' => ['data-toggle' => 'modal', 'data-target' => '#myModal']],

Вызываем виджет со всплывающим (модальным) окном, которое содержит форму обратной связи:

  1. <?= FBFWidget::widget([]) ?>

В итоге файл app/views/layouts/main.php будет выглядеть следующим образом (изменения в строках: 7, 38, 71):

  1. <?php
  2. use yii\helpers\Html;
  3. use yii\bootstrap\Nav;
  4. use yii\bootstrap\NavBar;
  5. use yii\widgets\Breadcrumbs;
  6. use app\assets\AppAsset;
  7. use app\components\FBFWidget;
  8.  
  9. AppAsset::register($this);
  10. ?>
  11. <?php $this->beginPage() ?>
  12. <!DOCTYPE html>
  13. <html lang="<?= Yii::$app->language ?>">
  14. <head>
  15. <meta charset="<?= Yii::$app->charset ?>">
  16. <meta name="viewport" content="width=device-width, initial-scale=1">
  17. <?= Html::csrfMetaTags() ?>
  18. <title><?= Html::encode($this->title) ?></title>
  19. <?php $this->head() ?>
  20. </head>
  21. <body>
  22. <?php $this->beginBody() ?>
  23.  
  24. <div class="wrap">
  25. <?php
  26. NavBar::begin([
  27. 'brandLabel' => 'My Company',
  28. 'brandUrl' => Yii::$app->homeUrl,
  29. 'options' => [
  30. 'class' => 'navbar-inverse navbar-fixed-top',
  31. ],
  32. ]);
  33. echo Источник: Перейти
Комментарии (0):
Чтобы оставить свой комментарий, необходимо пройти аутентификацию