johnny1991 2017-04-17 19:35:07 3813次浏览 0条评论 0 0 0

需求:form表单里面有字段:中文名(name_cn),英文名(name_en)。验证要求:中文名或是英文名必须要一个字段不能为空
设计思路:使用yii2里面的rules,实现form的前端及后端的验证
步骤:
第一步:设计一个validator类,能够实现这个验证
第二步:使用这个验证器,写入rules
第三步:在view文件里面使用

第一步:设计一个validator类,能够实现这个验证(包括一个validator类,一个js用于生成前端js验证,assets管理器)

// OrRequiredValidator.php

namespace common\models\validator;
use yii\validators\Validator;
use Yii;

/**
 * Created by PhpStorm.
 * User: johnny
 * Date: 17-2-10
 * Time: 上午12:35
 */
class OrRequiredValidator extends Validator
{
    public $or_attributes;
    public $requiredValue;
    public $strict = false;

    /**
     * @inheritdoc
     */
    public function validateAttribute($model, $attribute)
    {
        if (!empty($model->$attribute)) {
            return null;
        }

        if (empty($this->or_attributes) || !is_array($this->or_attributes)) {
            return [$this->message, []];
        }

        foreach ($this->or_attributes as $or_attribute) {
            if (!empty($model->$or_attribute)) {
                return null;
            }
        }

        return [$this->message, []];
    }

    /**
     * @inheritdoc
     */
    public function clientValidateAttribute($model, $attribute, $view)
    {
        $options = [];
        if ($this->requiredValue !== null) {
            $options['message'] = Yii::$app->getI18n()->format($this->message, [
                'requiredValue' => $this->requiredValue,
            ], Yii::$app->language);
            $options['requiredValue'] = $this->requiredValue;
        } else {
            $options['message'] = $this->message;
        }
        if ($this->strict) {
            $options['strict'] = 1;
        }

        $options['message'] = Yii::$app->getI18n()->format($options['message'], [
            'attribute' => $model->getAttributeLabel($attribute),
        ], Yii::$app->language);

        $options['or_attributes'] = $this->or_attributes;
        preg_match('/\w+$/', get_class($model), $matches);
        $options['id_prefix'] = strtolower($matches[0]);

        ValidationAsset::register($view);

        return 'yii.customerValidation.orRequired(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');';
    }
}


//ValidationAsset.php

namespace common\models\validator;

use yii\web\AssetBundle;

/**
 * This asset bundle provides the javascript files for client validation.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class ValidationAsset extends AssetBundle
{
    public $sourcePath = '@common\models\validator\assets';

    public $js = [
        'yii.customerValidation.js',
    ];
    public $depends = [
        'yii\web\YiiAsset',
    ];
}

// 这是js文件,仿照yii.validation.js写出来的,
// yii.customerValidation.js
yii.customerValidation = (function ($) {
    var pub = {
        isEmpty: function (value) {
            return value === null || value === undefined || value == [] || value === '';
        },

        addMessage: function (messages, message, value) {
            messages.push(message.replace(/\{value\}/g, value));
        },

        orRequired: function (value, messages, options) {
            if (options.requiredValue === undefined) {
                var isString = typeof value == 'string' || value instanceof String;
                if (!pub.isEmpty(isString ? $.trim(value) : value)) {
                    return ;
                }
            }

            var object=this.constructor;

            if (value == options.requiredValue) {
                return ;
            }

            // 通过获取field的id,找到相对应的值,来进行验证
            for(var i = 0; i < options['or_attributes'].length; i++) {
                var attribute_id = options['id_prefix'] + '-' + options['or_attributes'][i];
                var attribute = $('#' + attribute_id);
                if (!pub.isEmpty(attribute.val())) {
                    return ;
                }
            }

            pub.addMessage(messages, options.message, value);
        }
    };

    return pub;
})(jQuery);

第二步:在rules里面使用这个validator

public function rules() {
        return [
            Yii::createObject([
                'class'=>OrRequiredValidator::className(),
                'attributes'=>[
                    'name_en',
                ],
                'or_attributes'=>[
                    'name_cn'
                ],
                'message'=>'中文名或英文名称必须有一个不为空'
            ]),
        ];
    }

第三步:在view文件里使用

<div class="col-md-6">
<label>中文名:</label>
<?= $form->field($model,'name_cn')->textInput([
'value'=>isset($formData['name_cn'])?$formData['name_cn']:'',
'placeholder'=>"请输入品牌的中文名",
])->label(false)?>
</div>
<div class="col-md-6">
<label>英文名:</label>
<?= $form->field($model,'name_en')->textInput([
'value'=>isset($formData['name_en'])?$formData['name_en']:'',
'placeholder'=>"请输入品牌的英文名",
])->label(false)?>
</div>
    没有找到数据。
您需要登录后才可以评论。登录 | 立即注册