yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

Form Submission and error handling with Pjax #15885

Closed buttflattery closed 6 years ago

buttflattery commented 6 years ago

What steps will reproduce the problem?

Create a form within pjax

<?php 
use yii\widgets\Pjax;
use yii\bootstrap\Html;

?>
<?php Pjax::begin(); ?>
<?php 
$form=yii\widgets\ActiveForm::begin(['action'=>'pjax', 'method'=>'post', 'options'=>['data' => ['pjax'=>'   ']]]);

echo $form->field($model , 'name')->textInput();
echo Html::submitButton('submit');

yii\widgets\ActiveForm::end();
?>

<?php Pjax::end(); ?>

Add an action into your controller

public function actionPjax() {
        $model = new \frontend\models\Product();

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

            if ( $model->hasErrors () ) {

                $result = [];
                // The code below comes from ActiveForm::validate(). We do not need to validate the model
                // again, as it was already validated by save(). Just collect the messages.
                foreach ( $model->getErrors () as $attribute => $errors ) {
                    $result[Html::getInputId ( $model , $attribute )] = $errors;
                }

                $errors=\yii\helpers\Json::encode([ 'validation' => $result ] );
                $this->getView()->registerJs("var data='".$errors."';\$yiiform.yiiActiveForm('updateMessages', data.validation, true); // renders validation messages at appropriate places",\yii\web\View::POS_READY);
            }
        }

        return $this->render ( 'pjax' , [
                    'model' => $model
                ] );
    }

Now i want to update the error messages related to the form / model via javascript when i submit my form i call $model->validate() collect the messages into an array

foreach ( $model->getErrors () as $attribute => $errors ) {
      $result[Html::getInputId ( $model , $attribute )] = $errors;
}

Encode them to json using $errors=\yii\helpers\Json::encode([ 'validation' => $result ] ); and then register a script from inside the action


$this->getView()->registerJs("var data='".$errors."';\$yiiform.yiiActiveForm('updateMessages', data.validation, true); 

What is the expected result?

Update messages to the form

What do you get instead?

Nothing happens even if you replace the statement

$this->getView()->registerJs("var data='".$errors."';\$yiiform.yiiActiveForm('updateMessages', data.validation, true);

with

$this->getView()->registerJs("alert('hello')");

Although there is a workaround to add $form->errorSummary($model) inside your view and just call validate and render without collecting the messages but what if the error is not related to model or I am throwing and catching an exception and I want to use sessionFlash to show this message it won't work with the session->setFlash too.

Am i doing it wrong altogether

Additional info

Q A
Yii version 2.0.14.1
PHP version 5.6
Operating system Windows
buttflattery commented 6 years ago

sorry for this

pengchengzhang commented 5 years ago

The same problem bothers me. How can this problem be solved? Ask for help.