Pjax отправка формы.

Обсуждение документации второй версии фреймворка. Переводы Cookbook и авторские рецепты.
Ответить
Vicos
Сообщения: 5
Зарегистрирован: 2017.12.03, 09:53

Pjax отправка формы.

Сообщение Vicos » 2017.12.03, 10:50

Здравствуйте! Возникла проблема с реализацией ajax отправки формы в модалке. Проблема в корректной настройке параметров Pjax.
Ответ приходит всё верно, но замены содержимого контейнера не происходит.
Вывод делаю виджетом в модальном окне.

Код: Выделить всё

<?php
// '//layout/main.php'
Modal::begin([
    'header' => '<h2>Hello world</h2>',
    'toggleButton' => ['label' => 'Обратный звонок', 'class' => 'callback'],
]);
echo WContactForm::widget();
Modal::end();
?>

Код: Выделить всё

// Action
public function actionCallback()
    {
        if (Yii::$app->request->isAjax) {
            $model = new ContactForm();

            if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                Yii::$app->session->setFlash('contactFormSubmitted');
                $send = $model->contact(Settings::getParam(2));
                $status = ['send', $send];
                if (!$status) {
                    Yii::$app->session->setFlash('contactFormFalse');
                }
                return $this->renderAjax('//forms/modal');
            } else {
                $errors = $model->getErrors();
                exit(json_encode($errors));
            }
        } else {
            throw new HttpException('403', 'Not Ajax');
        }
    }

Код: Выделить всё

<?php
// View
// '//forms/modal
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;
use yii\widgets\Pjax;

$title = 'Контакты';
?>
<?php Pjax::begin([
        'id' => 'modalFormPjax',
        'timeout' => false,
        'enablePushState' => true,
        'enableReplaceState' => true,
        'formSelector' => 'contact-form'
    ]) ?>
    <div class="com-xs-12">
        <h1><?= Html::encode($title) ?></h1>
        <?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
            <div class="alert alert-success">
                Спасибо за обращение к нам. Мы постараемся ответить вам как можно скорее.
            </div>
        <?php elseif (Yii::$app->session->hasFlash('contactFormFalse')) : ?>
            <div class="alert alert-warning">
                Произошла ошибка при отправке сообщения!
            </div>
        <?php else: ?>
            <?php $form = ActiveForm::begin([
                'id' => 'contact-form',
                'options' => ['class' => 'form-horizontal', 'data-pjax' => true],
                'validationUrl' => 'site/callback',
                'enableAjaxValidation' => true,
                'enableClientValidation' => true,
                'fieldConfig' => [ /* классы полей формы */
                    'template' => "<div class=\"col-lg-3\">{label}</div>\n<div class=\"col-lg-9\">{input}</div>\n<div class=\"col-lg-12 col-lg-offset-3 \">{error}</div>"
                ],
            ]); ?>
            <div class="">
                <?php
                $form->errorSummary($model);
                ?>
            </div>
            <?= $form->field($model, 'name') ?>
            <?= $form->field($model, 'email') ?>
            <?= $form->field($model, 'subject') ?>

            <?= $form->field($model, 'body')->textArea(['rows' => 6]) ?>
            
            <?= Html::submitButton('Отправить сообщение', ['class' => 'btn btn-default center-block waves-effect btn-color-orange btn-color-orange-long', 'name' => 'contact-button']) ?>
            <?php ActiveForm::end(); ?>
        <?php endif; ?>
    </div>
<?php Pjax::end() ?>
Так же присутствуют следующие проблемы:
Когда форма модель не проходит валидацию и вызвращаем json (для наглядности, сейчас ответ ни как не влияет) скрипт Yii отрабатывют корректно и выставляет ошибки или подсвечивает зелёным.
Когда в action добираемся до render и приходит ответ, то скрипт не отрабатывает.
В поле 'body' происходит blur в action отправляем письмо и получаем ответ.

Код: Выделить всё

//request
<div id="modalFormPjax" data-pjax-container="" data-pjax-push-state data-pjax-replace-state>    <div class="com-xs-12">
        <h1>Контакты</h1>
                    <div class="alert alert-success">
                Спасибо за обращение к нам. Мы постараемся ответить вам как можно скорее.
            </div>
            </div>
</div><script src="/assets/1d2a8dad/jquery.js"></script>
<script src="/assets/fc160f5d/yii.js"></script>
<script src="/assets/d10e8553/jquery.pjax.js"></script>
<script type="text/javascript">jQuery(document).pjax("#modalFormPjax a", {"push":true,"replace":true,"timeout":false,"scrollTo":false,"container":"#modalFormPjax"});
jQuery(document).on("submit", "contact-form", function (event) {jQuery.pjax.submit(event, {"push":true,"replace":true,"timeout":false,"scrollTo":false,"container":"#modalFormPjax"});});</script>

Vicos
Сообщения: 5
Зарегистрирован: 2017.12.03, 09:53

Re: Pjax отправка формы.

Сообщение Vicos » 2017.12.04, 19:25

Изменил опции ActiveForm на

Код: Выделить всё

<?php $form = ActiveForm::begin([
                'id' => 'contact-form',
                'options' => ['class' => 'form-horizontal', 'data-pjax' => true],
                'validationUrl' => 'site/validate',
                'action' => 'site/callback',
                'ajaxDataType' => 'json',
                'fieldConfig' => [ /* классы полей формы */
                    'template' => "<div class=\"col-lg-3\">{label}</div>\n<div class=\"col-lg-9\">{input}</div>\n<div class=\"col-lg-12 col-lg-offset-3 \">{error}</div>"
                ],
            ]); ?>
Получаем валидацию на стороне клиента без ajax запросов. И Возможность пройти валидацию при отправке.
Осталось разобраться с действием в action.

Vicos
Сообщения: 5
Зарегистрирован: 2017.12.03, 09:53

Re: Pjax отправка формы.

Сообщение Vicos » 2017.12.04, 19:37

По сути validationUrl так же не нужен.
В action

Код: Выделить всё

public function actionCallback()
    {
        $model = new ContactForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {

            Yii::$app->session->setFlash('contactFormSubmitted');
            $send = $model->contact(Settings::getParam(2));
            $status = ['send', $send];
            if (!$status) {
                Yii::$app->session->setFlash('contactFormFalse');
            }
            return $this->renderAjax('//forms/modal');
        } else {
            return $this->renderAjax('//forms/modal');
        }
    }
Имеем обновление страницы с содержимым указанного view.
Почему не отрабатывает Pjax. Остаётся вопросом.

dmg
Сообщения: 571
Зарегистрирован: 2012.10.15, 03:09

Re: Pjax отправка формы.

Сообщение dmg » 2017.12.06, 15:28

formSelector проверьте

Vicos
Сообщения: 5
Зарегистрирован: 2017.12.03, 09:53

Re: Pjax отправка формы.

Сообщение Vicos » 2017.12.07, 19:42

Fixed! Или даже "Потрачено")

Код: Выделить всё

<?php Pjax::begin() ?>
    <div class="com-xs-12">
        <h1><?= Html::encode($title) ?></h1>
        <?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
            <div class="alert alert-success">
                Спасибо за обращение к нам. Мы постараемся ответить вам как можно скорее.
            </div>
        <?php elseif (Yii::$app->session->hasFlash('contactFormFalse')) : ?>
            <div class="alert alert-warning">
                Произошла ошибка при отправке сообщения!
            </div>
        <?php else: ?>
            <?php $form = ActiveForm::begin([
                'id' => 'contact-form',
                'options' => ['class' => 'form-horizontal', 'data-pjax' => true],
                'validationUrl' => '/site/validate',
                'action' => '/site/callback',
                'ajaxDataType' => 'html',
                'fieldConfig' => [ /* классы полей формы */
                    'template' => "<div class=\"col-lg-3\">{label}</div>\n<div class=\"col-lg-9\">{input}</div>\n<div class=\"col-lg-12 col-lg-offset-3 \">{error}</div>"
                ],
            ]); ?>

         // Output Fields Model

            <?= Html::submitButton('Отправить сообщение', ['class' => 'btn btn-default center-block waves-effect btn-color-orange btn-color-orange-long', 'name' => 'contact-button']) ?>
            <?php ActiveForm::end(); ?>
        <?php endif; ?>
    </div>
<?php Pjax::end() ?>
Проблема как оказалось в параметрах что передавал в Pjax:

Код: Выделить всё

[
        'id' => 'modalFormPjax',
        'timeout' => false,
        'enablePushState' => true,
        'enableReplaceState' => true,
        'formSelector' => 'contact-form'
    ]
Возможно как и натолкнул dmg проблема в form-selector. Разберусь позднее.
В контроллере сменил renderAjax на render.
Последний раз редактировалось Vicos 2017.12.07, 19:45, всего редактировалось 1 раз.

Vicos
Сообщения: 5
Зарегистрирован: 2017.12.03, 09:53

Re: Pjax отправка формы.

Сообщение Vicos » 2017.12.07, 19:44

Вытекает ещё один вопрос.
Как правльно использовать 'validationUrl'?

Код: Выделить всё

public function actionValidate()
    {
        if (Yii::$app->request->isAjax) {
            $model = new ContactForm();

            if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                $errors = $model->getErrors();

                $response = Yii::$app->getResponse();
                $response->format = \yii\web\Response::FORMAT_JSON;
                $response->data['errors'] = $errors;
                $response->send();
            } else {
                throw new HttpException('403', 'Access Denied');
            }
        } else {
            throw new HttpException('403', 'Access Denied');
        }
    }
На данный момент оставил пока так.
Ответ его как можно перехватить?
Или он мне просто не нужен?

Ответить