web-dev-qa-db-ja.com

Yii2:activeformにカスタム検証関数を使用する方法は?

フォームのモデルには、この方法で定義されたフィールドのカスタム検証関数があります

_class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],

            // other rules
        ];
    }

    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}
_

送信ボタンを押しても、フォームビューのフィールドの下にエラーメッセージは表示されませんが、必要なメールやパスワードなどの他のルールは表示されます。

私はサインアップネイティブフォームで作業しているので、それが提出された問題ではないことを確認するために、私はルールを設定しました

_['username', 'checkDateFormat']
_

ユーザー名フィールドに関連する他のすべてのルールを削除しましたが、メッセージも表示されません。

私はcheckDateFormatにパラメーターとして何も渡そうとしませんでした。明示的にフィールド名をaddError()に渡そうとしました

_$this->addError('username', '....');
_

しかし、何も表示されません。

カスタム検証関数を設定する正しい方法はどれですか?

22
Alhazred

ドキュメントを読みましたか?

上記の検証手順に従って、属性は、scenarios()で宣言されたアクティブな属性であり、rules()で宣言された1つまたは複数のアクティブなルールに関連付けられている場合にのみ検証されます。

したがって、コードは次のようになります。

class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],

            // other rules
        ];
    }

    public function scenarios()
    {
        $scenarios = [
            'some_scenario' => ['birth_date'],
        ];

        return array_merge(parent::scenarios(), $scenarios);
    }

    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

また、コントローラセットのシナリオでは、例:

$signupForm = new SignupForm(['scenario' => 'some_scenario']);
10
TomaszKane

yii 2でカスタム検証を行うには、モデルにカスタム関数を記述し、ルールにその関数を割り当てることができます。たとえば、passwordフィールドにパスワード条件を適用する必要があります。このようにモデルに書き込みます。

public function rules()
{
    return [
        ['new_password','passwordCriteria'],
    ];
}

public function passwordCriteria()
{
    if(!empty($this->new_password)){
        if(strlen($this->new_password)<8){
            $this->addError('new_password','Password must contains eight letters one digit and one character.');
        }
        else{
            if(!preg_match('/[0-9]/',$this->new_password)){
                $this->addError('new_password','Password must contain one digit.');
            }
            if(!preg_match('/[a-zA-Z]/', $this->new_password)){
                $this->addError('new_password','Password must contain one character.');
            }
        }
    }
}

参照:- yii 2 のフォーム検証

7

空のフィールドで検証を強制してみてください

['birth_date', 'checkDateFormat', 'skipOnEmpty' => false, 'skipOnError' => false],

また、ビューのbirth_dateフィールドにidを割り当てないようにしてください。

birth_dateのIDがある場合は、selectorsを指定する必要があります

<?= $form->field($model, 'birth_date', ['selectors' => ['input' => '#myBirthDate']])->textInput(['id' => 'myBirthDate']) ?>
6
Michael Nguyen

クラスModelから拡張する場合は、$model->validate()をどこかでトリガーする必要があります。

5
Josue Mota

CRUDジェネレーターを使用しているときに、私はこれにつまずきました。生成されたactionCreate()関数にはモデル検証呼び出しが含まれていないため、カスタム検証は呼び出されません。また、_formにはエラーの概要は含まれません。

したがって、エラーの概要を_formに追加します。

<?= $form->errorSummary($model); ?>

...検証呼び出し-$ model-> validate()-をコントローラーアクションに追加します

public function actionCreate()
{
    $model = new YourModel();

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {...
2
Steven McElveen

コントローラーからモデルをレンダリングする必要があります。ビューでモデルを初期化せずに。そしてコントローラーで、validate関数を呼び出す必要があります

1
Betson

それは古い投稿ですが、答えるべきだと思いました。

カスタムバリデータクラスを作成し、クライアント側の検証をサポートするバリデータを作成するには、クライアント側で検証を実行するJavaScriptコードを返すyii\validators\Validator::clientValidateAttribute()メソッドを実装する必要があります。 JavaScriptコード内。

次の定義済み変数を使用できます。

_attribute:_検証される属性の名前。

_value:_検証される値。

_messages:_属性の検証エラーメッセージを保持するために使用される配列。

_deferred:_遅延オブジェクトをプッシュできる配列(次のサブセクションで説明)。

つまり、messages配列を使用して、このメソッドのjavascriptコードブロック内でランタイム時にメッセージをクライアントエンドにプッシュできます。

ダミーチェックを含むクラスを作成します。ダミーチェックは、必要に応じて置き換えることができます。 yii2 namespaceまたはadvancedに従ってbasicを変更します。

_Custom Client-side Validator_

_namespace common\components;
use yii\validators\Validator;

class DateFormatValidator extends Validator{
public function init() {
        parent::init ();
        $this->message = 'You entered an invalid date format.';
    }

    public function validateAttribute( $model , $attribute ) {

        if ( /*SOME CONDITION TO CHECK*/) {
            $model->addError ( $attribute , $this->message );
        }
    }

    public function clientValidateAttribute( $model , $attribute , $view ) {

        $message = json_encode ( $this->message , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
        return <<<JS
if ($("#DATE-1").val()=="" || $("#DATE-2").val() =="") {
    messages.Push($message);
}
JS;
    }
}
_

そして、モデルの中にSigupFormを追加しますrule

_['birth_date', 'common\components\DateFormatValidator'],
_

_Deferred Validation_

clientValidateAttribute関数内にajax呼び出しを追加することもでき、そのajax呼び出しの結果に基づいてメッセージをクライアントエンドにプッシュできますが、yiiによって提供されるdeferredオブジェクトを使用できます遅延オブジェクトとその配列内に呼び出しをプッシュするか、遅延オブジェクトを明示的に作成してそのresolve()メソッドを呼び出します。

_Default Yii's deferred Object_

_public function clientValidateAttribute($model, $attribute, $view)
{
    return <<<JS
        deferred.Push($.get("/check", {value: value}).done(function(data) {
            if ('' !== data) {
                messages.Push(data);
            }
        }));
JS;
}
_

_Deferred Validation_ の詳細

1

addErrorの最初のパラメーターはこのようにすべきではありませんか?

$this->addError(**'attribute'**, Yii::t('user', 'You entered an invalid date format.'));
1
Pino Wackers

よくある問題がありました。

検証関数で:

public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }

$ paramsは値をまったく取得しません。実際には常にNullに等しくなります。 functionで属性値を確認する必要があります。

public function checkDateFormat($attribute, $params)
{
    if($this->birth_date == False)
    {
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

それは私のために働いた方法です。

1
Максим

モデルにシナリオを使用しない場合、属性を「安全」としてマークする必要があります。

    ['birth_date','safe'],
    ['birth_date', 'checkDateFormat'],

一方、これは日付検証に使用できます。

    ['birth_date','safe'],
    [['birth_date'],'date', 'format'=>'php:Y-m-d'],

必要に応じてフォーマットを変更できます。

0
hesselek