2016-08-29 5 views
0

я следующие правила проверки:правило проверки, которое требует, чтобы выбрать, по крайней мере, два варианта

['dagen_ids', 'required', 'message' => 'Selecteer.', 'when' => function($model) { 
    return $model->frequentie == 2; 
}] 

dagen_ids Атрибут является массивом то будет быть заселена Select2 виджет (множественный выбор).

То, что я добиться того, чтобы иметь правила проверки, что только требуется, когда $model->frequentie == 2, и когда пользователь должен выбрать по крайней мере 2 варианта.

Во второй части я попытался следующий код проверки инлайн, но это, кажется, не имеет никакого эффекта, к сожалению ..

['dagen_ids', function ($attribute, $params) { 
    if (count($this->$attribute) < 2) { 
     $this->addError($attribute, 'Selecteer minimaal 2 dagen.'); 
    } 
}] 

Может кто-то помочь мне немного дальше и объяснить мне, как объединить эти правила проверки?

EDIT

Контроллер:

public function actionView($id) 
{ 
    $planning = $this->findModel($id); 
    $post = Yii::$app->request->post(); 

    if (Yii::$app->request->isAjax && $planning->load($post) && $planning->validate() && $planning->save()) { 
      Yii::$app->session->setFlash('success', [ 
       'type' => 'success', 
       'duration' => 10000, 
       'icon' => 'fa fa-check', 
       'message' => 'Opdracht is succesvol bijgewerkt.'.Html::button(Icon::show('hand-o-right', ['class' => ''], Icon::FA). Yii::t('app', 'View'), ['class' => 'btn btn-sm btn-success modalButton pull-right', 'data-notify' => 'dismiss', 'data-content' => Url::to(['planning/view', 'id' => $id])]), 
       'title' => Html::tag('span', 'Opdracht bijgewerkt', ['style' => 'font-weight: bold;']), 
       'positonY' => 'top', 
       'positonX' => 'right' 
      ]); 
    } 
    else { 
     return $this->renderAjax('view', ['planning' => $planning]); 
    } 
} 

JQuery:

$('body').on('beforeSubmit', 'form#view_form', function() { 

    var form = $(this); 
    // return false if form still have some validation errors 
    if (form.find('.has-error').length) { 
     return false; 
    } 

    // submit form 
    $.ajax({ 
     url: form.attr('action'), 
     data: form.serialize(), 
     type: 'post' 
    }).done(function(){ 
     $('.modal').modal('hide'); 
     console.log('Form send!'); 
     $.pjax.reload({ 
      container: '#planner_grid', 
      timeout: 10000, 
      replace: false 
     }); 
    }).fail(function(){ 
     console.log('Server error...'); 
    }); 

    return false; 
}); 

ответ

1

Цитата The Definitive Guide to Yii 2.0: Validating Input - Inline Validators:

Примечание. По умолчанию встроенные валидаторы не применяются, если их ассоциированные атрибуты получают пустые входы или если они уже не выполнили некоторые правила проверки. Если вы хотите, чтобы правило всегда применялось, вы можете настроить свойства skipOnEmpty и/или skipOnError как ложные в объявлениях правил.

Так что вам может понадобиться, чтобы добавить эти 2 свойства ложным, и вы можете также изменить свое состояние, так он проверяет значение на frequentie:

['dagen_ids', function ($attribute, $params) { 
    if ($this->frequentie == 2 && count($this->$attribute) < 2) { 
     $this->addError($attribute, 'Selecteer minimaal 2 dagen.'); 
    } 
}, 'skipOnEmpty' => false, 'skipOnError' => false] 

Таким образом, вам не нужно иметь 2 разных правила валидации.

+0

Я попробовал ваш код, но теперь я могу представить форма как-то .. Когда у меня есть запись с 5 'dagen_ids', выбранная на примере, и я редактирую строку и выбираю 0' dagen_ids' вместо этого, форма будет отправлена, но атрибут 'dagen_ids', кажется, не затронут и все еще имеет 5 значений. Я отредактирую свой вопрос и вставлю свой контроллер и JQuery. Я также попытался написать автономный валидатор с вашим кодом, используя документы Yii2 (http://www.yiiframework.com/doc-2.0/guide-input-validation.html#standalone-validators), но нет никакой разницы. – JK87

+0

Это поможет узнать, как вы используете эти dagen_ids, поскольку проверка не является тем же, что и код, который обрабатывает отношения many_to_many, которые, как я полагаю, использует ваша модель. – marche

0

Наконец понял это ..

В этом случае с инлайн/автономной валидатор мне нужно подтверждение Ajax.

Я использую DetailView плагин и это выглядит следующим образом:

echo DetailView::widget([ 
    'model' => $planning, 
    'attributes' => $attributes, 
    'mode' => 'view', 
    'panel' => [ 
     'heading' => $planning->stopTitel, 
     'type' => DetailView::TYPE_PRIMARY, 
    ], 
    'bordered' => false, 
    'responsive' => true, 
    'hover' => true, 
    'fadeDelay'=> 800, 
    'deleteOptions' => [ 
     'params' => ['id' => $planning->planning_id, 'delete' => true], 
     'url' => ['delete'] 
    ], 
    'container' => ['id' => 'opdracht-bewerken'], 
    'formOptions' => ['id' => 'view_form', 'action' => Url::current(['#' => 'opdracht-bewerken']), 'validationUrl' => Url::toRoute(['validate-form']), 'enableClientValidation' => true, /*'enableAjaxValidation' => true*/], // If you want Ajax validation on the whole form, uncomment this. 
]); 

Но я только хочу одно поле быть Ajax подтверждено поэтому в моем случае мне нужно добавить следующие строки в моем dagen_ids поле :

'fieldConfig' => ['enableAjaxValidation' => true] (Documentation)

Мои контроллеры выглядит следующим образом:

use yii\web\Response; 
use yii\helpers\Json; 
use kartik\widgets\ActiveForm; 

    public function actionView($id) 
    { 
     $planning = $this->findModel($id); 
     $post = Yii::$app->request->post(); 

     if ($planning->load($post) && $planning->save()) { 
      Yii::$app->session->setFlash('success', [ 
       'type' => 'success', 
       'duration' => 10000, 
       'icon' => 'fa fa-check', 
       'message' => 'Opdracht is succesvol bijgewerkt.'.Html::button(Icon::show('hand-o-right', ['class' => ''], Icon::FA). Yii::t('app', 'View'), ['class' => 'btn btn-sm btn-success modalButton pull-right', 'data-notify' => 'dismiss', 'data-content' => Url::to(['planning/view', 'id' => $id])]), 
       'title' => Html::tag('span', 'Opdracht bijgewerkt', ['style' => 'font-weight: bold;']), 
       'positonY' => 'top', 
       'positonX' => 'right' 
      ]); 
     } 
     else { 
      return $this->renderAjax('view', ['planning' => $planning]); 
     } 
    } 

    public function actionValidateForm() { 
     Yii::$app->response->format = Response::FORMAT_JSON; 

     $planning = new Planning(); 
     $post = Yii::$app->request->post(); 

     $planning->load($post); 
     return ActiveForm::validate($planning); 
    } 

И мой автономный валидатор:

namespace backend\components\validators; 

use yii\validators\Validator; 

class DagenValidator extends Validator 
{ 
    public function validateAttribute($model, $attribute) 
    { 
     if ($model->frequentie == 2 && count($model->$attribute) < 2) { 
      $this->addError($model, $attribute, 'Selecteer minimaal 2 dagen.'); 
     } 
    } 
} 

Теперь в моей Planning модели я могу добавить к следующему правилу:

['dagen_ids', DagenValidator::className(), 'skipOnEmpty' => false, 'skipOnError' => false]