Jquery 验证助手
JQuery 验证助手减少了 Javascript 中 Cake 模型配置的重复。
我第一次实现 JQuery Validate 插件,很快就意识到它需要添加与 Cake 模型中相同的验证规则。由于这似乎违反了 DRY 原则,我想出了一个助手,它扫描模型验证规则并创建等效的 JQuery 插件验证规则,并将它们存储为一个字符串在对话框类项中。
https://github.com/vz28bh/CakePHP-JqueryValidationHelper
首先,在你的布局中包含 JQuery 和 Validate 插件。还有一个“additional-methods”文件定义了一些额外的验证规则。你还需要元数据插件来解码包含验证规则的字符串。
echo $this->Html->script('jquery-1.7.2.min');
echo $this->Html->script('jquery.validate.min');
echo $this->Html->script('additional-methods.js');
echo $this->Html->script('jquery.metadata');
然后在你的控制器中添加助手
public $helpers = array( 'Html','Form', 'Js' => array('Jquery'), 'JqueryValidation' );
当你创建一个对话框时,你需要提供一个特殊的类,它用于 Javascript 中来检测要验证的表单。
echo $this->Form->create('Order', array('class' => 'jquery-validation'));
然后对于每个要验证的元素,使用助手的输入函数
echo $this->JqueryValidation->input('serial', $options);
这个函数在修改选项数组后调用 Form->input。
这是助手代码。这仍然是一个正在进行的工作,所以有一些 Cake 验证规则我没有实现,所以请随意更新或添加新的规则。好消息是基本验证规则在几乎不需要额外工作的情况下就涵盖了。请注意,它只适用于每个字段格式的多个规则。
App::uses('AppHelper', 'View/Helper');
class JqueryValidationHelper extends AppHelper {
public $helpers = array('Form');
#-- Map to replace constants with jquery and class info
#-- Pass as $options['jquery-validate']
public $options = array(
'map' => array(
'__formSelector__' => '.jquery-validation',
'__errorElement__' => 'span',
'__errorClass__' => 'help-block',
'__hilightClass__' => 'form-error',
'__closestSelector__' => '.control-group',
'__closestErrorClass__' => 'error'
)
);
private $validation_messages = array();
private $js = "
$(document).ready(function(){
$('__formSelector__').each( function(index) {
$(this).validate({
'errorElement': '__errorElement__',
'errorClass': '__errorClass__',
'highlight': function(element,errorClass) {
$(element)
.siblings().remove();
$(element)
.addClass('__hilightClass__')
.closest('__closestSelector__').addClass('__closestErrorClass__');
},
'unhighlight': function(element,errorClass) {
$(element)
.removeClass('__hilightClass__')
.closest('__closestSelector__').removeClass('__closestErrorClass__')
},
});
});
});";
/**
* input
*
* Routine to mimic form helper in order to get needed info.
*
* @param type $fieldName
* @param type $options
*/
public function input($fieldName, $options = array()) {
$map = $this->options['map'];
if (isset($options['jquery-validate'])) {
if (isset($options['jquery-validate']['map'])) {
$map = array_merge($map, $options['jquery-validate']['map']);
}
unset($options['jquery-validate']);
}
$model = $this->Form->defaultModel;
$meta = $this->meta($model, $fieldName);
if (!empty($options['class'])) {
$options['class'] .= ' {' . $meta . '}';
} else {
$options['class'] = $meta;
}
$response = '';
#-- Inlcude the js if needed
if (!empty($this->js)) {
$formatted_js = strtr($this->js, $map);
$response .= "<script type=\"text/javascript\">" . $formatted_js . "</script>";
$this->js = '';
}
$response .= $this->Form->input($fieldName, $options);
return $response;
}
/**
* meta
*
* Returns a meta string to be added to the class of a dialog input
*
* @param type $model
* @param type $field
* @return string
*/
public function meta($model, $field) {
$model_object = new $model();
foreach ($model_object->validate as $validateField => $validateItem) {
CakeLog::write('debug', 'JqueryValidate->meta: validateField=' . $validateField);
if ($field == $validateField) {
if (is_array($validateItem)) {
CakeLog::write('debug', 'JqueryValidate->meta: validateItem=' . print_r($validateItem, true));
foreach ($validateItem as $validateName => $validateParams) {
if (!empty($validateParams['rule'])) {
$rule = $validateParams['rule'];
CakeLog::write('debug', 'JqueryValidate->meta: $rule=' . print_r($rule, true));
if (is_array($rule)) {
$msg = $rule[0];
} else {
$msg = $rule;
}
if (!empty($validateParams['message'])) {
$msg = $validateParams['message'];
}
$ruleName = $rule[0];
CakeLog::write('debug', 'JqueryValidate->meta: ruleName=' . $ruleName);
$methodName = 'jquery_validate_' . $ruleName;
if (method_exists($this, $methodName)) {
$meta[] = $this->$methodName($model, $field, $rule, $msg);
CakeLog::write('debug', 'JqueryValidate->meta: $meta=' . $meta);
} else {
CakeLog::write('debug', 'JqueryValidate->meta: function $ruleName not found');
}
}
}
}
}
}
if (is_array($meta)) {
$messages_str = '';
if (is_array($this->validation_messages)) {
$messages_str = implode($this->validation_messages, ', ');
}
$meta_str = implode($meta, ', ');
return "'rules': {" . $meta_str . ", 'messages': { " . $messages_str . "}}";
} else {
return '';
}
}
/**
* Various functions to convert a CakePHP validation to a Jquery Validate meta tag
*/
private function jquery_validate_alphaNumeric($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->date: params=' . print_r($params, true));
$this->validation_messages[] = "date: '" . $msg . "'";
return "'date': true";
}
private function jquery_validate_between($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->between: params=' . print_r($params, true));
$this->validation_messages[] = "between: '" . $msg . "'";
return "'min': " . $params[1] . ", 'max': " . $params[2];
}
private function jquery_validate_blank($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->blank: params=' . print_r($params, true));
$this->validation_messages[] = "rangelength: '" . $msg . "'";
return "'rangelength': [0, 0]";
}
private function jquery_validate_boolean($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->boolean: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "boolean: '" . $msg . "'";
return "'boolean': true";
}
private function jquery_validate_cc($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->cc: params=' . print_r($params, true));
$this->validation_messages[] = "creditcard: '" . $msg . "'";
return "'creditcard': true";
}
private function jquery_validate_comparison($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->comparison: params=' . print_r($params, true));
$op = $params[1];
$value = $params[2];
switch ($op) {
case '>':
$value++;
$this->validation_messages[] = "'min': '" . $msg . "'";
return "'min': " . $value;
break;
case '>=':
$this->validation_messages[] = "'min': '" . $msg . "'";
return "'min': " . $value;
break;
case '<':
$value--;
$this->validation_messages[] = "'max': '" . $msg . "'";
return "'max': " . $value;
break;
case '<=':
$this->validation_messages[] = "'max': '" . $msg . "'";
return "'max': " . $value;
break;
case '!=':
$value++;
$this->validation_messages[] = "'min': '" . $msg . "'";
$str = "'min': " . $value;
$value = $value - 2;
$this->validation_messages[] = "'max': '" . $msg . "'";
return $str . ", 'max': " . $value;
break;
default:
return '';
}
}
private function jquery_validate_date($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->date: params=' . print_r($params, true));
$this->validation_messages[] = "date: '" . $msg . "'";
return "'date': true";
}
private function jquery_validate_datetime($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->datetime: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "datetime: '" . $msg . "'";
return "'datetime': true";
}
private function jquery_validate_decimal($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->decimal: params=' . print_r($params, true));
$this->validation_messages[] = "number: '" . $msg . "'";
return "'number': true";
}
private function jquery_validate_email($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->email: params=' . print_r($params, true));
$this->validation_messages[] = "email: '" . $msg . "'";
return "'email': true";
}
private function jquery_validate_equalTo($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->equalTo: params=' . print_r($params, true));
$this->validation_messages[] = "equalTo: '" . $msg . "'";
return "'equalTo': '" . Inflector::camelize($model) . Inflector::camelize($params[1]) . "'";
}
private function jquery_validate_extension($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->extension: params=' . print_r($params, true));
$this->validation_messages[] = "accept: '" . $msg . "'";
return "'accept': '" . implode($params[1], "|") . "'";
}
private function jquery_validate_inList($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->inList: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "inList: '" . $msg . "'";
return "'inList': true";
}
private function jquery_validate_ip($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->ip: params=' . print_r($params, true));
$this->validation_messages[] = "ipv4: '" . $msg . "'";
return "'ipv4': true";
}
private function jquery_validate_luhn($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->luhn: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "luhn: '" . $msg . "'";
return "'luhn': true";
}
private function jquery_validate_maxLength($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->maxLength: params=' . print_r($params, true));
$this->validation_messages[] = "'maxlength': '" . $msg . "'";
return "'maxlength': " . $params[1];
}
private function jquery_validate_minLength($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->minLength: params=' . print_r($params, true));
$this->validation_messages[] = "'minlength': '" . $msg . "'";
return "'minlength': " . $params[1];
}
private function jquery_validate_money($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->money: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "money: '" . $msg . "'";
return "'money': true";
}
private function jquery_validate_notEmpty($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->notEmpty: params=' . print_r($params, true));
$this->validation_messages[] = "required: '" . $msg . "'";
return "'required': true";
}
private function jquery_validate_numeric($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->numeric: params=' . print_r($params, true));
$this->validation_messages[] = "number: '" . $msg . "'";
return "'number': true";
}
private function jquery_validate_naturalNumber($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->naturalNumber: params=' . print_r($params, true));
$this->validation_messages[] = "digits: '" . $msg . "'";
return "'digits': true";
}
private function jquery_validate_required($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->required: params=' . print_r($params, true));
$this->validation_messages[] = "required: '" . $msg . "'";
return "'required': true";
}
private function jquery_validate_phone($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->phone: params=' . print_r($params, true));
$this->validation_messages[] = "phoneUS: '" . $msg . "'";
return "'phoneUS': true";
}
private function jquery_validate_postal($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->postal: params=' . print_r($params, true));
$this->validation_messages[] = "minlength: '" . $msg . "'";
$this->validation_messages[] = "maxlength: '" . $msg . "'";
return "'minlength': 5, 'maxlength': 5";
}
private function jquery_validate_range($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->range: params=' . print_r($params, true));
$this->validation_messages[] = "min: '" . $msg . "'";
$this->validation_messages[] = "max: '" . $msg . "'";
return "'min': " . $params[1] . ", 'max': " . $params[2];
}
private function jquery_validate_ssn($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->ssn: params=' . print_r($params, true));
$this->validation_messages[] = "minlength: '" . $msg . "'";
$this->validation_messages[] = "maxlength: '" . $msg . "'";
return "'minlength': 9, 'maxlength': 9";
}
private function jquery_validate_time($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->time: params=' . print_r($params, true));
$this->validation_messages[] = "time: '" . $msg . "'";
return "'time': true";
}
private function jquery_validate_url($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->url: params=' . print_r($params, true));
$this->validation_messages[] = "url: '" . $msg . "'";
return "'url': true";
}
private function jquery_validate_uuid($model, $field, $params, $msg) {
CakeLog::write('debug', 'JqueryValidate->uuid: params=' . print_r($params, true));
return '';
$this->validation_messages[] = "uuid: '" . $msg . "'";
return "'uuid': true";
}
}