
Рассмотрим 2 случая: когда форма находится на странице сайта и её нужно отправить асинхронно по Pjax; и второй случай - когда форму нужно вывести в модальном окне и тоже отправить асинхронно.
1. Случай формы ActiveForm по Pjax на странице
Пригодится для лендингов. Форму одеваем в пиджак (Pjax::begin() и Pjax::end()), чтобы обновлялась она асинхронно при ответе с сервера (мне нужно вывести вместо формы на её месте сообщение о результате отправки сообщения администратору сайта). И, второе, не забываем у ActiveForm в опциях добавить 'data-pjax' => true, чтобы форма отправляла данные асинхронно.
<?php yii\widgets\Pjax::begin() ?> <?php if (!empty($success)): ?> <div class="alert alert-success lead"> Спасибо! Ваша заявка отправлена. Мы скоро с вами свяжемся. </div> <?php else: ?> <?php $form = ActiveForm::begin(['options' => ['id' => 'contactForm1', 'data-pjax' => true, 'class'=>'form form-register1 text-left'], 'fieldConfig' => ['template' => "{beginWrapper}\n{hint}\n{error}\n{input}\n{endWrapper}"]]); ?> ... <?php ActiveForm::end(); ?> <?php endif; ?> <?php Yii\widgets\Pjax::end(); ?>
Дальше в контроллере в действии для этого представления добавляем отдельно проверку для случая isPjax. В модели формы BuycourseForm действие contact(), отправляющее сообщение на email.
public function actionIndex()
{
...
$model = new BuycourseForm();
if(Yii::$app->request->isPjax && $model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
$success = true;
return $this->render('landing', [
'success'=>$success,
'model' => $model
]);
}
...
return $this->render('landing', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model
]);
}
2. Случай ActiveForm по Pjax в модальном окне ("Пиджак в окне")
Пишу CRM-ку для студии танцев и возникло желание задействовать мощь Pjax. Тем более, что его поддержка встроена в Yii2.
В модальном окне внесения оплаты сохранение оплаты делается через Pjax ("Пиджак в окне"), потому что в модальном окне под формой внесения оплаты находится грид с данными об оплатах этого ученика и таким образом (по pjax) он обновляется на лету и админ видит, что платеж зафиксирован на сервере. При закрытии же самого модального окна, нужно снова обновить ячейку с оплатой в главном гриде "Ученики".
Итак, когда вызывается модальное окно, там форма добавления платежа и грид уже имеющихся платежей. Контроллер PaymentController
public function actionCreate($date=null, $pupil_id=null) { $model = new Payment(); $model->date = $date; $model->pupil_id = $pupil_id; $model->payment_type = 1; $searchModel = new PaymentSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams, $pupil_id = $pupil_id); if (Yii::$app->request->isAjax) { if ($model->load(Yii::$app->request->post()) && $model->save()) { $model = new Payment(); $model->date = $date; $model->pupil_id = $pupil_id; $model->payment_type = 1; } return $this->renderAjax('create_ajax', [ 'model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, 'group_id'=> 2, ]); } else { if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(Yii::$app->request->referrer); } else { return $this->render('create', [ 'model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]); } } }
В виде, что в модальном окне показывается
<?php use yii\helpers\Html; use yii\grid\GridView; use app\components\NumberColumn; use yii\widgets\Pjax; /* @var $this yii\web\View */ /* @var $model app\models\Payment */ $this->title = 'Добавить платёж'; $this->params['breadcrumbs'][] = ['label' => 'Payments', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> <div class="payment-create"> <?= $this->render('_form_ajax', [ 'model' => $model, 'group_id' => $group_id, ]) ?> </div> <hr> <h3>Последние платежи (<?= $model->pupil->name ?>):</h3> <?php Pjax::begin(['id' => 'payments']) ?> <?= GridView::widget([ 'dataProvider' => $dataProvider, //'filterModel' => $searchModel, 'layout'=>"{items}", 'showFooter' => true, 'tableOptions' => [ 'class' => 'table table-striped table-condensed small' ], 'columns' => [ ['class' => 'yii\grid\SerialColumn'], [ 'attribute' => 'date', 'format' => ['date', 'dd.MM.YYYY'], ], [ 'attribute'=>'payment_type', 'label'=>'Тип платежа', //'filter'=>app\models\PaymentType::find()->select(['id', 'title'])->indexBy('id')->column(), //'format'=>'text',//'raw', 'value'=>'paymentType.title', /*'content'=>function(app\models\User $model){ return $model->profile->getGroupName(); },*/ /*'value' => function($model){ return (isset($model->profile->group_id)) ? Html::encode($model->profile->group_id) : '<span class="not-set">' . Yii::t('user', '(not set)') . '</span>'; },*/ 'footer'=>'Всего: ', ], [ 'class' => NumberColumn::className(), 'attribute' => 'price', ], [ 'class' => 'yii\grid\ActionColumn', 'contentOptions' => ['style' => 'white-space: nowrap; text-align: center; letter-spacing: 0.1em; max-width: 7em;'], ], ], ]); ?> <?php Pjax::end() ?>
Часть _form_ajax для этого вида
<?php use yii\helpers\Html; use yii\bootstrap\ActiveForm; use yii\helpers\ArrayHelper; /* @var $this yii\web\View */ /* @var $model app\models\Payment */ /* @var $form yii\widgets\ActiveForm */ ?> <?php // обновляем грид под формой с оплатой внутри модального окна $this->registerJs( '$("document").ready(function(){ $("#new_payment").on("pjax:end", function() { $.pjax.reload({container:"#payments"}); //Reload GridView }); });' ); ?> <div class="payment-form"> <?php yii\widgets\Pjax::begin(['id' => 'new_payment']) ?> <?php $form = ActiveForm::begin(['options' => ['data-pjax' => true], 'layout' => 'horizontal']); ?> <div class="row clearfix"> <div class="col-md-12"> <?= $form->field($model, 'pupil_id')->hiddenInput(['value'=> $model->pupil->user_id])->label(false); ?> <div class="form-group field-payment-date required"> <label class="control-label col-sm-3" for="payment-pupil_id">От</label> <div class="col-sm-6"> <div class="input-group"> <?= $model->pupil->name ?> </div> </div> </div> <?= $form->field($model, 'date')->widget(\yii\jui\DatePicker::classname(), [ 'dateFormat' => 'dd.MM.yyyy', 'language' => 'ru', 'options'=>['class'=>'form-control'], ]) ?> <?= $form->field($model, 'payment_type')->dropDownList(ArrayHelper::map(app\models\PaymentType::find()->select(['id', 'title'])->all(), 'id', 'title'), ['prompt'=>'- Выберите тип платежа -']) ?> <?= $form->field($model, 'price', ['template' => ' {label} <div class="col-sm-6"> <div class="input-group"> {input} <div class="input-group-addon"> <span class="glyphicon glyphicon-rub"></span> </div> </div> {error}{hint} </div>'])->textInput() ?> </div> </div> <div class="form-group"> <div class="col-sm-offset-3 col-sm-8"> <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> </div> </div> <?php ActiveForm::end(); ?> <?php yii\widgets\Pjax::end(); ?> </div>
Важные моменты
- В действии actionIndex добавили сохранение данных новой Заметки, если они пришли в запросе post
- Обернули виджеты GridView и ActionForm в пиджак
- Добавили небольшой скрипт, обновляющий GridView после добавления новой записи
17 сентября 2016, Программирование, веб-кодинг / Метки: Pjax GridView ActiveRecord Modal
По мотивам – https://nix-tips.ru/yii2-primeryaem-pjax-na-activeform-i-gridview.html

