Смена статуса в editable kartik с подтверждением.

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Закрыто
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Смена статуса в editable kartik с подтверждением.

Сообщение Fixpix »

Всем привет.

В GridView имеется редактируемый (editable kartik) столбец со статусами (статусы обработки товара). Хочу сделать чтобы при смене статуса, появлялось модальное окно в котором я буду показывать список с радиобоксами в зависимости от самого статуса... То есть если статус "отменен", то из списка модального окна надо выбрать "почему" он был отменен, и также со статусом "приостановлен", только уже другие причины показывать надо в самом модальном окне. После валидации подтверждения и валидации модального окна, сохраняется сам статус.

В GridView

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

'editableOptions' => function($model, $key, $index) {
    /** @var $model Orders */
    return [
        'formOptions' => [
            'id'=>'states',
            'action' => ['orders/states', 'id' => $model->id],
            'method'=>'post',
        ],
        'asPopover' => true,
        'header'=>'Status',
        'inputType'=>Editable::INPUT_DROPDOWN_LIST,
        'data' => Orders::getStates($model->Status),
        'options' => ['class'=>'form-control', 'prompt'=>'Выберите статус...'],
        'submitOnEnter' => false,
    ];
}
Модальное окно:

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

<?php $form = ActiveForm::begin([
    'id' => 'formCauses',
    'method' => 'POST',
    'validationUrl' => \yii\helpers\Url::toRoute('orders/validation'),
    'type' => ActiveForm::TYPE_VERTICAL,
    'formConfig' => [
        'showErrors' => true,
        'deviceSize' => ActiveForm::SIZE_LARGE,
    ],
]);
?>
<?php
    switch ($newState) {
        case 'Отменен' :
        echo $form->field($model, 'cause',[
                'hintType'=>\kartik\form\ActiveField::HINT_SPECIAL,
            ])->radioList(Orders::getListCausesCancelled())->label('');
        break;
        case 'Остановлен' :
            echo $form->field($model, 'cause')->Orders::getListСausesPause())->label('');
        break;
        default :
            echo '';
        break;
    }
?>
<?php ActiveForm::end(); ?>
Конроллер:

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

public function actionMessage($id, $newState = 'Новый')
{
    $model = $this->findModel($id);

    if ($model ->load(Yii::$app->request->post())) {
        if ($model ->save()) {
            $this->redirect('index');
        } else {
            $errors = $model ->errors;
        }
    }

    return $this->renderAjax('message', [
        'model'=>$model,
        'newState' => $newState,
    ]);
}

public function actionStates($id)
{
    if (isset($_POST['hasEditable']))
    {
        \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $stateId = YII::$app->request->post('editableKey');
        $model = $this->findModel($stateId);

        $post = [];
        $posted = current($_POST['Orders']);
        $post['Orders'] = $posted;

        $out = Json::encode(['output'=>'', 'message'=>'']);

        if ($model->load($post))
        {
            $newState = $posted['Status'];

            // Как вывести модальное окно?
            
            $message = $this->actionMessage($id, $newState);
            $this->actionMessage($id, $newState);
            
            // Здесь нужна проверка на валидацию модального окна, если все верно, тогда сохраняю...
            if($model->save())
            {
                if (isset($newState))
                {
                    $output = $model -> Status;
                }
                $out = Json::encode(['output'=>$output, 'message'=>'']);
            }
        }
        echo $out;
        return;
    }
}
Если смотреть в дебагере, то переменная $message возвращает мне все правильно, выводит данные в зависимости от статуса, но окно не рендериться... я знаю что туплю, но разобраться не могу...
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Смена статуса в editable kartik с подтверждением.

Сообщение Dominus »

Если я правильно понял, то модальное окно вам нужно вызывать программно.
View:

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

<?php
//...
$script = "   
    function showMyModal() {
        $('#my-modal').modal('show'); // Открываем окно       
    }
    
    // До кучи, функция закрытия)
    function hideMyModal() {        
        $('#my-modal').modal('hide'); // Закрываем окно
    }
";
$this->registerJs($script);
?>

<?php \yii\bootstrap\Modal::begin([
    'header' => '<h4>Заголовок</h4>',
    'id' => 'my-modal',
]); ?>

<p>Контент...</p>

<?php \yii\bootstrap\Modal::end(); ?>
После ответа, вызывать js функцию showMyModal();

http://demos.krajee.com/editable
Там есть события, при наступлении нужного события, запускать showMyModal();

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

    pluginEvents = [
        "editableChange"=>"function(event, val) { log('Changed Value ' + val); }",
        "editableSubmit"=>"function(event, val, form) { log('Submitted Value ' + val); }",
        "editableBeforeSubmit"=>"function(event, jqXHR) { log('Before submit triggered'); }",
        "editableSubmit"=>"function(event, val, form, jqXHR) { log('Submitted Value ' + val); }",
        "editableReset"=>"function(event) { log('Reset editable form'); }",
        "editableSuccess"=>"function(event, val, form, data) { log('Successful submission of value ' + val); }",
        "editableError"=>"function(event, val, form, data) { log('Error while submission of value ' + val); }",
        "editableAjaxError"=>"function(event, jqXHR, status, message) { log(message); }",
    ];
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: Смена статуса в editable kartik с подтверждением.

Сообщение Fixpix »

Привет! Спасибо за ответ!

Последовал вашему совету и сделал вывод модального окна через "editableSuccess", сейчас модальное окно показывает правильные данные.

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

public function actionMessage($id)
{
    $stateId = YII::$app->request->post('editableKey');

    $model = $this->findModel($stateId);

    $post = [];
    $posted = current($_POST['Orders']);
    $post['Orders'] = $posted;

    $newState = $posted['Status'];

    $data = $this->renderAjax('message', [
        'model'=>$model,
        'newState'=>$newState,
    ]);
    return Json::encode(["data" => $data]);
}
как теперь привязать второй экшн чтобы после валидации формы, сохранить статус, в ином случае статус остается без изменения?
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Смена статуса в editable kartik с подтверждением.

Сообщение Dominus »

Наверное отправить данные формы ajax`ом на экшен, там проверяем, если всё ок то сохраняем, если нет то какие то действия, возвращаем ответ, и в зависимости от ответа можно так же программно закрыть окно.

Вот посмотрите этот виджет, как там формы организованы и ajax валидация. Возможно найдете для себя что то полезное)
https://github.com/Dominus77/LoginFormWidget
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Аватара пользователя
Dominus
Сообщения: 892
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: Смена статуса в editable kartik с подтверждением.

Сообщение Dominus »

Что то вроде этого.
Выдернул из виджета ajax подписки
View:

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

<?php
//...
$buttonId = 'submit-button';
$container = 'my-cintainer';
$script = "
            $('#subscribe-form').on('beforeSubmit', function (e) {
                e.preventDefault();        
                let form = e.currentTarget,
                    url = form.action,
                    data = $(this).serialize(),
                    button = $('#{$buttonId}'),
                    info = $('#{$container} .info');
        
                $.ajax({
                    url: url,
                    dataType: 'json',
                    type: 'POST',
                    data: data,
                    beforeSend: function (XMLHttpRequest) {
                        button.html('Подписываемся ...');
                    }
                }).done(function (response) {
                    if (response.type == 'success') {
                        button.html('Проверьте почту');
                        button.prop('disabled', true);
                        info.html(response.message);                        
                    } else {
                        button.html('Email уже подписан');
                        button.prop('disabled', true);
                        info.html(response.message);
                    }
                }).fail(function (response) {
                    console.log(response);
                });
                return false;
            });
        ";
$this->registerJs($script);
?>
<div id="<?= $container ?>">
    <div class="info"></div>
	
    <!-- Форма -->
    <?php ActiveForm::begin([
	'id' => 'subscribe-form',
	'action' => Url::to(['/subscribe/default/sender']),
    ]);

	echo $form->field($this->model, 'email', [
                'template' => "{input}",
            ])->textInput([               
                'type' => 'email',
                'name' => 'email',
                'placeholder' => true,
            ])->label(false) . PHP_EOL;
            
        echo Html::submitButton('Subscribe', [
                'id' => $buttonId,
                'class' => 'btn btn-primary',
            ]) . PHP_EOL;
            
    ActiveForm::end(); ?>
</div>

Controller:

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

    /**
     * Отправка Email для проверки на принадлежность
     * @return array
     * @throws NotFoundHttpException
     */
    public function actionSender()
    {
        if (Yii::$app->request->isAjax) {
            $model = new Subscribe();
            Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->email = Yii::$app->request->post('email')) {
                if ($model->sendEmail()) {
                    return [
                        'type' => 'success',
                        'message' => Module::t('module', 'To confirm, we sent you a letter, check your mail.'),
                    ];
                }
                return [
                    'type' => 'error',
                    'message' => Module::t('module', 'If you did not receive a confirmation letter, contact the administrator, thank you.'),
                ];
            }
            return [
                'type' => 'error',
                'message' => Module::t('module', 'Oops, something went wrong.'),
            ];
        }
        throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
    }
В зависимости от результата, выполнять какие либо действия и формировать ajax ответ.
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!
Fixpix
Сообщения: 38
Зарегистрирован: 2018.07.31, 15:33

Re: Смена статуса в editable kartik с подтверждением.

Сообщение Fixpix »

Оргромное спасибо! Все получилось:)
Закрыто