1
votes

I have a model with a custom validation method. For testing it always returns an error message.

public function rules()
{
    return [
     ...
        ['staff_ids', 'each', 'rule' =>  ['string']],
        [['staff_ids'], 'validateStaffIds'],
     ...
    ];
}

public function validateStaffIds($attribute, $params, $validator) {
    $this->addError($attribute, 'There is an error in the staff ids');
}

In the view.php is the modal element

<p>      
    <?= Html::button('Add Ensemble Staff',
            ['value' => Url::to(['ensemble/add', 'id' => $model->id]), 
             'title' => 'Adding New Ensemble Staff',
             'class' => 'showModalButton btn btn-primary']); 
    ?>
</p>

<?php
    Modal::begin([
        'closeButton' => [
              'label' => 'x',
        ],
        'headerOptions' => ['id' => 'modalHeader'],
        'id' => 'modal',
        'size' => 'modal-lg',
    ]);
    echo "<div id='modalContent'></div>";
    Modal::end();
?>

The js code which fires everything up...

$(function(){
    $(document).on('click', '.showModalButton', function(){

        if ($('#modal').data('bs.modal').isShown) {
            $('#modal').find('#modalContent')
                    .load($(this).attr('value'));
        } else {
            //if modal isn't open; open it and load content
            $('#modal').modal('show')
                    .find('#modalContent')
                    .load($(this).attr('value'));      
        }

        //dynamiclly set the header for the modal
        ...
    });
});

And the ensemble controller which handles the add action

public function actionAdd($id)
{
    $model = $this->findModel($id);

    // in the post ( 'ensembleStaff_ids' => [0 => '2']); where the id actually is staff_id
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' =>  $id]);
    } else {
        return $this->renderAjax('add', [
            'model' => $model,
        ]);
    }
}

And the form which is injected by the js into the model (Url::to(['ensemble/add', 'id' => $model->id]), )

<?php $form = ActiveForm::begin(['id' => 'add-theater-stuff-form']); ?>  

<?= $form->field($model, 'staff_ids')->widget(Select2::className(), [
       'model' => $model,
       'data' => ArrayHelper::map(app\models\TheaterStaff::find()->where(['theater_id' => $model->theater_id])->all(), 'staff_id', 'staff.fullname'),
       'options' => [
           'multiple' => true,
           'prompt' => 'Ensemble Staff',
       ], 
        'pluginOptions' => [
            'tags' => true
        ]
   ]); ?>

<div class="form-group">
    <?= Html::submitButton('Add', ['class' => 'btn btn-primary']) ?>
</div>

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

Clicking on the Add Ensemble Staff Button works fine and brings up the modal window. The form itself works fine so far; also the default validation works. Even the custom validation is called, but return $this->renderAjax(...) isn't load in the modal window anymore; it is separately.

A picture showing the modal loaded, the result after submit and a modal with default validation.

I found a similar problem here. But adding an id to the form, doesn't solve the problem. So how to get the default validation showing up properly in the modal window? Does anyone have a clue?

Solution

Thanks for the response. For me the solution was: Enable ajax in the form

<?php $form = ActiveForm::begin(['id' => 'add-ensemble-stuff-form', 'enableAjaxValidation' => true]); ?>  

And to add the following logic in the controller

public function actionAdd($id)
    {
        $model = $this->findModel($id);

        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ActiveForm::validate($model);
        } else {
            // in the post ( 'ensembleStaff_ids' => [0 => '2']); where the id actually is staff_id
            if ($model->load(Yii::$app->request->post()) && $model->save()) {
                return $this->redirect(['view', 'id' =>  $id]);
            } else {
                return $this->renderAjax('add', [
                    'model' => $model,
                ]);
            }
        }
    }
1
Try enableAjaxValidation => true in form options.Insane Skull
@InsaneSkull Yes that worked! I really thought i tried this already ... hrrr .. thanks anyway!Luc

1 Answers

0
votes
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ActiveForm::validate($model);
    }else{/* your code */}

add this in controller use yii\web\Response