Yii2具有強(qiáng)大的表單驗(yàn)證功能,能用好表單驗(yàn)證,用戶輸入就基本掌握了,在這里我和各位聊聊Yii2的客戶端驗(yàn)證器
。
所謂客戶端驗(yàn)證器
,就是在HTML代碼中使用JavaScript進(jìn)行驗(yàn)證的驗(yàn)證器。
什么?你在Yii2中沒有編寫過客戶端驗(yàn)證器!是的,那是因?yàn)閅ii2幫你把客戶端驗(yàn)證器自動生成
了,讓我們一起來看一看Yii2自動生成的客戶端驗(yàn)證器長什么樣子吧!
上圖是一個很簡單的輸入表單,需要用戶輸入姓名和年齡,注意看一下,現(xiàn)在表單的兩個輸入框是灰色
的。
如上圖,在“年齡”輸入框中輸入22,點(diǎn)擊“提交”按鈕后,“姓名”輸入框變成了紅色
,并在其下方出現(xiàn)了一個提示信息:姓名不能為空。“年齡”輸入框變?yōu)?code>綠色,表示驗(yàn)證通過。這里就是Yii2客戶端驗(yàn)證器實(shí)現(xiàn)的驗(yàn)證效果。
Tip:如果你看到的提示信息是“姓名 cannot be blank”
,修改一下你的Yii2語言設(shè)置:
配置文件:\advanced\frontend\config\main.php
將:
'language' => 'en',
修改為:
'language' => 'zh-CN',
如上圖,瀏覽器中,在“姓名不能為空。”
文字上點(diǎn)擊鼠標(biāo)右鍵
,在下拉框中選中“檢查”
就會在界面下方出現(xiàn)前端調(diào)試窗口
(我使用的Chrome
瀏覽器)。
如上圖,在下方的前端調(diào)試窗口
任意位置,點(diǎn)擊一下鼠標(biāo)左鍵
,按Ctrl+f
,會出現(xiàn)左下角
紅框所示的搜索框,輸入“姓名不能為空”,你將會搜索出兩個結(jié)果
,點(diǎn)擊搜索框右邊的箭頭
,就可以查看到如圖中藍(lán)框所示的客戶端驗(yàn)證器代碼
了。我們仔細(xì)看一下這部分JavaScript代碼:
jQuery(document).ready(function () {
jQuery('#w0').yiiActiveForm([{"id":"form1-name","name":"name","container":".field-form1-name","input":"#form1-name","error":".help-block.help-block-error","validate":function (attribute, value, messages, deferred, $form) {yii.validation.required(value, messages, {"message":"姓名不能為空。"});yii.validation.string(value, messages, {"message":"姓名必須是一條字符串。","min":2,"tooShort":"姓名應(yīng)該包含至少2個字符。","max":30,"tooLong":"姓名只能包含至多30個字符。","skipOnEmpty":1});}},{"id":"form1-age","name":"age","container":".field-form1-age","input":"#form1-age","error":".help-block.help-block-error","validate":function (attribute, value, messages, deferred, $form) {yii.validation.required(value, messages, {"message":"年齡不能為空。"});yii.validation.number(value, messages, {"pattern":/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/,"message":"年齡必須是一個數(shù)字。","min":18,"tooSmall":"年齡的值必須不小于18。","max":60,"tooBig":"年齡的值必須不大于60。","skipOnEmpty":1});}}], []);
});
這些JavaScript就是Yii2為我們自動生成
的客戶端驗(yàn)證器
,正是通過它們,前端的表單驗(yàn)證工作才得以有效實(shí)現(xiàn),而我們所需要做的就是去編寫rules()
中的驗(yàn)證規(guī)則即可。Yii2框架已為我們做好了大量基礎(chǔ)工作
!
好,現(xiàn)在我們就一起來看看rules()
是怎么編寫的吧!請仔細(xì)閱讀代碼中的注釋。
public function rules() {
return [
[['name','age'],'required'],//name,age是必填項(xiàng)'required'
//name項(xiàng)是個字符串(string),其長度不能少于2個字符,也不能多于30個字符
['name','yii\validators\StringValidator','min'=>2,'max'=>30,'enableClientValidation' =>true],//在一條規(guī)則中設(shè)置enableClientValidation可以控制此條驗(yàn)證規(guī)則的客戶端驗(yàn)證是否生效,默認(rèn)值是true
//['name','string','min'=>2,'max'=>30],//與上句等效,'string'是驗(yàn)證器'yii\validators\StringValidator'的別名
//age項(xiàng)必須是一個有效的整數(shù)(integer),其值不能小于18,也不能大于60
['age','integer','min'=>18,'max'=>60],
];
}
在本例中提到了'string'是驗(yàn)證器'yii\validators\StringValidator'的別名
,Yii2提供了23個核心驗(yàn)證器
,都是可以使用別名
直接書寫,非常簡潔。
關(guān)于這23個核心驗(yàn)證器
,請參閱文檔:
http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html
需要說明的是,這23個核心驗(yàn)證器
,并不是都能夠提供客戶端驗(yàn)證功能的,比如:unique
、exist
等,這些驗(yàn)證器是需要在數(shù)據(jù)庫
中查詢的驗(yàn)證器,在客戶端當(dāng)然是無法直接完成的了。當(dāng)然,這些驗(yàn)證器通過Ajax技術(shù)
也實(shí)現(xiàn)了仿客戶端驗(yàn)證
的良好效果。
客戶端驗(yàn)證可以使用通過enableClientValidation
來進(jìn)行控制,默認(rèn)值是true
,即客戶端驗(yàn)證默認(rèn)是生效的。
enableClientValidation
可以在三處進(jìn)行設(shè)置:
1、在ActiveForm中對整個form進(jìn)行設(shè)置,請參見源碼中的注釋
2、在ActiveField中對field進(jìn)行單獨(dú)設(shè)置,請參見源碼中的注釋
3、在Model的rules中對驗(yàn)證規(guī)則進(jìn)行設(shè)置,請參見源碼中的注釋
本文所涉及到的程序源碼
:
文件位置:D:\phpwork\advanced\frontend\controllers\DemoController.php
<?php
namespace frontend\controllers;
use Yii;
class DemoController extends CommonController{
public function actionForm1() {
$model=new \frontend\models\Form1();
if ($model->load(Yii::$app->request->post())) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return \yii\bootstrap\ActiveForm::validate($model);
}
if($model->validate()){
if ($model->save()) {
return $this->render('form1a',['model'=>$model]);
}else{
$this->error('Sorry,Data save fail!');
}
}else{
return $this->errorDisplay($model->getErrors());
}
}else{
return $this->render('form1',['model'=>$model]);
}
}
}
其中errorDisplay()
方法是調(diào)用自CommonController
,請參見:
http://www.lxweimin.com/p/5d2c42166702
文件位置:D:\phpwork\advanced\frontend\models\Form1.php
<?php
namespace frontend\models;
use Yii;
class Form1 extends \yii\base\Model{
public $name,$age;
public function attributeLabels() {
return [
'name'=>'姓名',
'age'=>'年齡',
];
}
public function rules() {
return [
[['name','age'],'required'],//name,age是必填項(xiàng)'required'
//name項(xiàng)是個字符串(string),其長度不能少于2個字符,也不能多于30個字符
['name','yii\validators\StringValidator','min'=>2,'max'=>30,'enableClientValidation' =>true],//在一條規(guī)則中設(shè)置enableClientValidation可以控制此條驗(yàn)證規(guī)則的客戶端驗(yàn)證是否生效,默認(rèn)值是true
//['name','string','min'=>2,'max'=>30],//與上句等效,'string'是驗(yàn)證器'yii\validators\StringValidator'的別名
//age項(xiàng)必須是一個有效的整數(shù)(integer),其值不能小于18,也不能大于60
['age','integer','min'=>18,'max'=>60],
];
}
public function save() {
return true;
}
}
文件位置:D:\phpwork\advanced\frontend\views\demo\form1.php
<?php
use yii\bootstrap\ActiveForm;
use yii\helpers\Html;
$form = ActiveForm::begin([
//在ActiveForm中設(shè)置enableClientValidation可以設(shè)置整個表單(form)的客戶端驗(yàn)證是否生效,默認(rèn)值是true;如果此值設(shè)置為false,則前端的js驗(yàn)證代碼將不會再生成。
'enableClientValidation' => true,
'layout' => 'horizontal',
]);
?>
<div class="panel panel-warning">
<div class="panel-heading">
<div class="panel-title">
二、Yii2的表單驗(yàn)證——客戶端驗(yàn)證的驗(yàn)證器
</div>
</div>
<div class="panel-body" style="height:500px;">
<!-- 在ActiveField中設(shè)置enableClientValidation可以控制field項(xiàng)的客戶端驗(yàn)證是否生效,默認(rèn)值是true -->
<?=$form->field($model,'name',['enableClientValidation'=>true])->textInput()?>
<?=$form->field($model,'age',['inputOptions'=>['class'=>'form-control']])->textInput()?>
<div class="row">
<div class='col-md-2 col-md-offset-4'><?= Html::submitButton('提 交', ['class' => 'btn btn-primary form-control']) ?></div>
<div class='col-md-2 col-md-offset-1'><?= Html::resetButton('重 置', ['class' => 'btn btn-default form-control']) ?></div>
</div>
</div>
</div>
<?php ActiveForm::end(); ?>
文件位置:D:\phpwork\advanced\frontend\views\demo\form1a.php
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
?>
<div class="panel panel-warning">
<div class="panel-heading">
<div class="panel-title">
二、Yii2的表單驗(yàn)證——客戶端驗(yàn)證的驗(yàn)證器(提交數(shù)據(jù)的顯示)
</div>
</div>
<div class="panel-body" style="height:500px;">
<?php
echo DetailView::widget([
'model' => $model,
'attributes' => [
'name:html',
'age',
],
'template' => '<tr><th class="text-right" style="width:150px;">{label}</th><td>{value}</td></tr>',
]);
?>
<button onclick="history.back()" class="btn btn-default">返 回</button>
</div>
</div>
歡迎深入閱讀:
一處編寫,三處運(yùn)行的Yii2表單驗(yàn)證
(全文完)