- jQuery EasyUI從零開始學
- 施堯
- 9296字
- 2019-12-06 14:08:59
2.1 文本框簡介
文本框通常用來接收用戶輸入的數據。我們先來看一個使用HTML設計的登錄頁面,部分代碼如下:
01 <div>賬號<input type="text"></div> 02 <div>密碼<input type="password"></div> 03 <button>提交</button>
運行結果如圖2.1所示。

圖2.1 HTML登錄頁面
讀者先想一想這個登錄頁面有哪些問題。
首先我們沒有限制賬號、密碼文本框為必填字段,這就導致登錄用戶可以什么也不輸入就向服務器發送一個無效的登錄請求。
其次如果后端開發人員設計的登錄校驗SQL語句為:
SELECT * FROM accounts WHERE username='賬號' AND password = '密碼'
正常情況下用戶在賬號輸入框內輸入"admin",在密碼輸入框內輸入"password",后臺執行的SQL語句就為:
SELECT * FROM accounts WHERE username='admin' AND password = 'password'
但是如果在賬號輸入框內輸入"admin' AND 1=1 /*",在密碼輸入框內輸入任意字符串,那么后臺執行的SQL語句就變成了:
SELECT * FROM accounts WHERE username='admin' AND 1=1 /* and password = 'aaa'
可以看到數據庫實際執行的SQL為:
SELECT * FROM accounts WHERE username='admin' AND 1=1
“/*”后面的SQL語句被當作注釋而忽略掉了,此時用戶就可以繞開密碼登錄系統。
提示
SQL注入以及XSS攻擊等常見的網絡攻擊手段,其根本原理就是用戶輸入的數據沒有經過充分的檢查和過濾,意外變成了代碼被執行,我們在設計表單的各個輸入控件時,一定要進行相應的過濾,如限制用戶只能輸入數字、用戶輸入長度不能超過指定范圍等。
要解決上述問題我們必須限制賬號、密碼文本框的輸入內容,例如限制賬戶、密碼不能為空;限制用戶輸入的長度不能超過指定值,此外還需要限制賬號文本框的輸入僅能為字母、數字或者下畫線。在提交表單前,我們還需要檢查每個字段的輸入是否合法。要做到這些我們需要設計大量的JavaScript邏輯進行判斷,這無疑增加了前端開發的難度。
針對這個開發難點,EasyUI提供了驗證框(ValidateBox)來幫助開發者對用戶輸入的內容進行驗證。
2.1.1 驗證框(ValidateBox)
驗證框是為了防止提交無效字段而設計的,當用戶輸入無效值時,它將改變背景顏色,并且顯示警示圖標和提示消息。驗證框的默認配置定義在$.fn.validatebox.defaults中。
提示
許多初學者會誤以為文本框(TextBox)為EasyUI中最基本的輸入框,驗證框擴展于文本框。其實在EasyUI中文本框是擴展于驗證框的一個輸入框,一旦混淆了兩者之間的擴展關系,就會產生諸如如何給驗證框加上圖標等困惑。關于EasyUI中的依賴和擴展關系,本書將會在2.1.2小節詳細講解。
1. 創建驗證框
使用標記創建驗證框的方法如下:
<input id="v" class="easyui-validatebox" data-options="required:true,validType:'email'">
使用JavaScript創建驗證框的方法如下:
01 <input id="v"> 02 $('#v').validatebox({ 03 required: true, 04 validType: 'email' 05 });
2. 驗證框屬性
驗證框常用的屬性說明見表2.1。
表2.1 驗證框常用屬性說明

提示
通常我們稱光標進入某個組件時,該組件獲得焦點;當光標離開組件時,該組件失去焦點。
validType屬性定義該字段的驗證類型,例如email、url、length等。當驗證單個規則時,validType屬性的值為字符串類型,如validType:'email'。當驗證多個規則時,validType屬性的值為數組類型,如validType:['email','length[0,20]']。EasyUI提供的驗證規則有:
- email:檢查輸入是否為郵箱格式。
- url:檢查輸入是否為合法的地址格式。
- length[0,10]:檢查輸入的字符長度是否在指定范圍區間。
- remote['http://.../check.php','paramName']:發送ajax請求來驗證輸入值,驗證通過時返回'true'。
提示
length是按照字符計算長度,而非字節。字符與字節的區別在于:一個漢字和英文字母都只算一個字符,而一個漢字占兩個字節以上,一個英文字母只占一個字節。
對于EasyUI未支持的驗證規則,開發者也可以自定義驗證規則,如下代碼自定義一個驗證兩次密碼輸入是否一致的規則:
01 <input id="pw1" name=" pw1" type="password" class="easyui-validatebox" 02 data-options="required:true"><!—密碼文本框A--> 03 <input id="pw2" name="pw2" type="password" class="easyui-validatebox" 04 required="required" validType="equals['#pw1]"> <!—密碼文本框B--> 05 <script> 06 $.extend($.fn.validatebox.defaults.rules, { 07 equals: { 08 validator: function(value,param){ 09 return value == $(param[0]).val(); 10 }, 11 message: '兩次密碼輸入不一致' 12 } 13 }); 14 </script>
其中$.extend($.fn.validatebox.defaults.rules,{})函數的意思是在EasyUI默認的驗證規則中添加我們自定義的驗證規則。equals為我們自定義的驗證規則名稱,validator函數中value參數為密碼文本框B的值。param為傳遞的參數;是一個數組,本例中傳輸的參數為#pw1,它是密碼文本框A的id,通過id可以獲取密碼文本框A的值$(param[0]).val()。最后判斷其與密碼文本框B的值是否相等,如果相等的話返回true,此時驗證通過;如果不相等的話,返回false,同時將顯示message中定義的驗證失敗提示內容。
提示
使用自定義驗證規則時,最重要的是理解validator函數的用法,其中value參數是驗證字段的值,param是其附帶的數據。
3. 驗證框事件
驗證框常用事件說明見表2.2。
表2.2 驗證框常用事件說明

4. 驗證框方法
驗證框常用方法說明見表2.3。
表2.3 驗證框常用方法說明

提示
enableValidation和disableValidation僅僅是啟用/禁用驗證,設置disableValidation為true后不會對用戶的輸入進行驗證,而disable則禁用整個驗證框,用用用戶無法進行輸入操作。
readonly可以啟用或者禁用只讀模式,例如:
01 $('#v').validatebox('readonly'); // 啟用只讀模式 02 $('#v').validatebox('readonly',true); // 啟用只讀模式 03 $('#v').validatebox('readonly',false); // 禁用只讀模式
isValid方法可以返回當前驗證結果,通常用于提交數據前檢測用戶輸入是否通過驗證,例如:
$("#v").validatebox('isValid');
接下來我們使用驗證框設計一個用戶登錄頁面,部分代碼如下:
01 <div style="margin:20px 20px;"> 02 賬號 <input id="account"> 03 </div> 04 <div style="margin:20px 20px;"> 05 密碼 <input id="password"> 06 </div> 07 <div style="margin:20px 150px;"> 08 <button id='login'> 登錄</button> 09 </div> 10 <script> 11 $(function(){ 12 //自定義驗證規則,只能輸入英文和數字或者下畫線 13 $.extend($.fn.validatebox.defaults.rules, { 14 englishOrNum : { 15 validator : function(value) { 16 return /^[a-zA-Z0-9_]{1,}$/.test(value); 17 }, 18 message : '請輸入英文、數字、下畫線或者空格' 19 } 20 }); 21 $("#account").validatebox({ 22 required :true, //設置輸入不能為空 23 missingMessage :'請輸入賬號', //輸入為空時顯示的提示 24 invalidMessage:'請輸入合法的賬號格式', //輸入驗證失敗時顯示的提示 25 validType: ['length[5,10]','englishOrNum'], 26 //多個驗證規則使用數組表示,長度在5至10個字符,英文、數字、下畫線 27 tipPosition:'bottom', //提示框的位置 28 validateOnCreate:false, //頁面加載完成后不進行一次驗證 29 }); 30 31 $("#password").validatebox({ 32 required :true, //設置輸入不能為空 33 missingMessage :'請輸入密碼', //輸入為空時顯示的提示 34 invalidMessage:'請輸入合法的密碼格式', //輸入驗證失敗時顯示的提示 35 validType: 'length[6,13]', 36 //單個驗證規則使用字符串表示,長度在5至10個字符,英文、數字、下畫線 37 deltaX:-10, 38 //提示框向左邊便宜10個單位,數值為負數向左偏移,為正數向右偏移。 39 validateOnCreate:false, //頁面加載完成后不進行一次驗證 40 }); 41 $("#login").click(function(){ 42 //通過isValid方法檢查是否驗證通過 43 if($("#account").validatebox('isValid')){ 44 alert("賬號通過驗證"); 45 }else{ 46 alert("賬號未通過驗證"); 47 } 48 if($("#password").validatebox('isValid')){ 49 alert("密碼通過驗證"); 50 }else{ 51 alert("密碼未通過驗證"); 52 } 53 }); 54 }); 55 </script>
最終運行結果如圖2.2所示。

圖2.2 使用驗證框設計登錄頁面
【本節詳細代碼參見隨書源碼:\源碼\easyui\example\c2\validateLogin.html】
5. 服務器端驗證用戶輸入
驗證框可以通過remote規則來向服務器請求遠程驗證,注意當驗證通過時服務器需要返回字符串'true'。通常我們會在自定義規則中使用ajax來請求遠程驗證,如下代碼使用自定義規則來驗證賬號是否已被注冊,部分代碼如下:
01 //該規則用于驗證賬號是否已被注冊 02 accountvalidate : { 03 validator : function(value, param) { 04 //獲取用戶輸入的賬戶名 05 var account = value.trim(); 06 var result;//保存驗證的結果 07 $.ajax({ 08 type : 'post', 09 async : false,//設置同步請求 10 url : 'server/checkaccount.php', 11 data : { 12 //向服務器傳遞的參數,php中可以使用$_POST['account']來獲取該值 13 "account" : account 14 }, 15 success : function(data) { 16 //data為服務器處理完畢后傳遞給客戶端的值 17 result = data; 18 } 19 }); 20 //resault為true時驗證通過 21 if(result=='0'){ 22 return true; 23 } 24 else{ 25 return false; 26 } 27 }, 28 message : '用戶名已經被占用' 29 },
【本節詳細代碼參見隨書源碼:\源碼\easyui\example\c2\remoteValidate.html】
提示
使用服務器端驗證時必須設置ajax為同步請求。所謂的同步請求,就是必須獲取到服務器返回的值后JavaScript代碼才會向下執行,否則會一直等待服務器處理結果。因為驗證規則中必須通過服務器返回的結果來判斷驗證是否通過,因此此時需要設置其為同步請求。
讀者可以運行實例程序,在賬號中輸入sj123、xiaom11、admin、vsi1sk,此時會出現用戶名已被占用的提示。
2.1.2 文本框(TextBox)
回到圖2.1中,我們使用HTML創建了一個登錄頁面,在2.1.1小節中帶領讀者使用EasyUI驗證框解決了如何驗證用戶輸入的問題。使用HTML開發還面臨著另一個巨大的挑戰,就是頁面美觀問題,通常前端開發人員都需要編寫大量的CSS來美化頁面。由于CSS編寫規范不統一,經常會出現不同的CSS文件沖突,從而導致網站整體設計無法達到預期效果。例如,在圖2.2所示的登錄頁面中通過給驗證框添加外邊框來進行簡單的頁面排版。文本框會使用指定的主題樣式對組件進行渲染,從而節省開發者的美化時間。
文本框的依賴關系如下:
- validatebox
- linkbutton
文本框擴展于:
- validatebox
文本框的默認配置定義在$.fn.textbox.defaults中。
1. 創建文本框
使用標記創建文本框的方法如下:
<input class= "easyui-textbox" >
使用JavaScript創建文本框的方法如下:
01 <input id="tb" type="text "> 02 $('#tb').textbox();
2. 文本框屬性
文本框常用的屬性說明見表2.4。
表2.4 文本框常用屬性說明

提示
文本框繼承了驗證框全部屬性、事件和方法,在實際開發中我們幾乎不會直接使用到驗證框,而由文本框派生出各類豐富的EasyUI組件。
在下面的內容中,本書將詳細講解文本框的屬性、事件和方法,在本節末尾介紹屬性、事件和方法的含義,并帶領讀者探討EasyUI中的依賴關系。
首先來看一下width、height屬性,從字面意思可以理解這是一個設置文本框尺寸的屬性,可以通過比例或者固定的像素值來設置寬度,使用像素值來設置高度。例如:
<input class="easyui-textbox" data-options="width:’90%’"> <input class="easyui-textbox" data-options="width:360,height:20">
提示
此處我們設置的width:100%是相對于它的上一層父元素的寬度比,當設置為比例時應給值加上引號,請看下面示例:
01 <div id="parent2" style="width: 500px;"> 02 <div id="parent1" style="width: 400px;"> 03 <input class="easyui-textbox" data-options="width:'90%'"> 04 </div> 05 </div>
最終運行結果如圖2.3所示。

圖2.3 使用比例設置寬度
這個例子里面parent1為文本框的父元素,它的寬度為400px,parent2為parent1的父元素,它的寬度為500px,我們設置文本框的寬度比為90%,這個比例是相對于parent1的,因此文本框的寬度也就是360px。如果組件通過像素值設置尺寸,我們稱其為靜態布局。如果使用百分比設置尺寸,我們稱其為流式布局。
cls參數用于給文本框添加一個新的風格,例如設置文本框的下外邊距為10,相關CSS代碼如下:
01 <style> 02 .newStyle{ 03 margin-bottom:10px; 04 } 05 </style>
給文本框添加該風格的相關代碼如下:
01 $('#tb).textbox({ 02 cls:'newStyle' 03 });
prompt屬性用于當文本框中無任何內容時顯示的提示,例如:
$('#tb).textbox({prompt:'請輸入賬號'});
value屬性為文本框加載完畢后顯示的初值。
type屬性可以設置文本框的輸入類型,當設置為password時,用戶的輸入將會被替換成指定的字符以避免密碼泄露。
label為文本框中的一個標簽,在圖2.2所示的例子中,“賬號”“密碼”這些提示用戶輸入的字符串通常會寫在對應組件的前面,但是當這些字符串長度不一致時頁面就會變得混亂,如圖2.4所示。

圖2.4 一個排版混亂的頁面
通過label屬性可以解決這個問題,其中labelWidth為標簽的寬度,labelPosition為標簽的顯示位置,labelAlign為標簽的對齊方式,詳細的用法示例如下:
01 <div><input id="nickname"></div> 02 <div><input id="phone"></div> 03 <script> 04 $(function(){ 05 $('#nickname').textbox({ 06 label:'昵稱', 07 labelPosition:'left',//顯示在文本框的左側 08 labelAlign:'right', //右側對齊,字符串的最后一個字符對齊 09 width: 300, 10 cls:'newStyle' 11 }); 12 $('#phone').textbox({ 13 label:'手機號碼', 14 labelPosition:'left', 15 labelAlign:'right', 16 width: 300, 17 }); 18 }); 19 </script>
最終運行結果如圖2.5所示。

圖2.5 使用標簽對齊字符串
icons可以給文本框添加圖標,icons為包含icons對象的數組,icons對象有如下屬性:
- iconCls:圖標類型。
- disabled:定義單擊圖標后是否觸發事件。
- handler:單擊圖標后觸發的事件。
具體的代碼示例如下:
01 $('#tb').textbox({ 02 icons:[ 03 { 04 iconCls:'icon-man', 05 handler:function(e){ 06 alert("圖標被單擊"); 07 } 08 }, 09 ], 10 });
最終運行效果如圖2.6所示。

圖2.6 帶圖標的文本框
iconAlign、iconWidth屬性定義了圖標的對齊方式以及寬度,使用代碼如下:
01 $('#tb').textbox({ 02 icons:[ 03 { 04 iconCls:'icon-man', 05 handler:function(e){ 06 alert("圖標被單擊"); 07 } 08 }, 09 ], 10 });
上面的例子中使用的圖標類型icon-man為EasyUI自帶的圖標,我們也可以添加一個自定義圖標,詳細步驟如下:
- 找到EasyUI框架下themes文件夾中的icons文件夾,將自定義的圖標保存到該文件
夾下。
- 打開themes文件夾下的icon.css文件,在文本末尾添加如下代碼:
01 .icon-extend-lock{ 02 background:url('icons/extend_lock.png') no-repeat center center; 03 }
其中extend_lock.png為自定義圖標的名稱,icon-extend-lock為我們自定義的圖標的類型名稱,使用圖標類型名就可以顯示我們自定義的圖標,代碼如下:
01 $(‘#tb’).textbox({ 02 icons:[ 03 { 04 iconCls:’icon-extend-lock’, 05 handler:function(e){ 06 alert(“圖標被單擊”); 07 } 08 }, 09 ], 10 });
本書在隨書資料【\資源\圖標\】目錄下提供了大量可供讀者使用的自定義圖標。
文本框允許開發者為其添加一個按鈕,buttonText為按鈕的名稱,buttonIcon為按鈕的圖標,buttonAlign為按鈕的對齊方式。示例代碼如下:
01 $(‘#tb’).textbox({ 02 buttonText:”按鈕”, 03 buttonIcon:’icon-extend-lock’, 04 buttonAlign:’left’//左對齊 05 });
最終運行結果如圖2.7所示。

圖2.7 帶按鈕的文本框
3. 文本框事件
文本框常用事件說明見表2.5。
表2.5 文本框常用事件說明

提示
onChange只能在內容發生改變且失去焦點時觸發。
4. 文本框方法
文本框常用方法說明見表2.6。
表2.6 文本框常用方法說明

提示
textbox返回的是展示值框對象,因此開發者無法使用該對象重新初始化文本框,關于展示值框的概念請查看2.1.3節內容。如下代碼是錯誤的:
01 var tb = $("#tb").textbox("textbox"); 02 tb.textbox({ 03 width:100 04 });
運行后會發現在文本框中又嵌套了一個文本框。
5. 屬性、方法和事件
一個手機都會擁有尺寸、音量、屏幕等元素,這些是組成一個手機的必要元素,我們稱這些元素為屬性。手機出廠后通常都會替消費者設置好默認的屏幕亮度以及音量,這一個過程我們稱為初始化。在EasyUI中組件的屬性在頁面加載完畢后就會將其初始化好。如下代碼設置文本框的初始值和初始類型屬性,代碼如下:
01 $('#tb).textbox({ 02 value:'初始值', 03 type:’text’ 04 });
提示
在jQuery中可以通過$(function(){//頁面加載完畢后的代碼})的方式來處理頁面加載完畢后的代碼。
當手機接收到來電消息時,會亮起屏幕并且播放響鈴,這一過程叫作事件。事件必須有特定的消息才會觸發,事件也是在初始化時設置,例如當文本框中的內容發生改變時會觸發onChange事件,寫法如下:
01 $('#tb).textbox ({ 02 onChange:function(newValue,oldValue){ 03 } 04 });
使用者可以調節手機的音量大小以及屏幕顯示的亮度,這一過程稱為方法。方法通常是在屬性初始化后改變屬性的值,在文本框中的editable、disabled、readonly、width、height、value等屬性都可以通過對應的方法將其改變,如resize方法改變寬度,initValue方法重新設置初始值等。如下代碼設置文本框為只讀模式。
$('#tb').textbox('readonly',true);
使用者可以在手機設置功能中查看當前手機的各種配置,也就是說方法不僅可以修改屬性的值也可以查看屬性的值。例如,options方法可以查看當前文本框的全部配置,我們稱組件的當前配置對象為其選項對象。
使用者可以在手機上設置鬧鈴,鬧鈴只會在指定的時間才會觸發,因此鬧鈴是一個事件,而使用者設置鬧鈴這一過程是一個方法,因此通過方法同樣可以增加事件。文本框中textbox方法可以綁定任意的事件。如下代碼給文本框綁定一個鍵盤按下的事件:
01 $('#tb').textbox("textbox").bind("keydown",function(e){ 02 var v = e.keyCode;//當前按鍵的ASCII碼 03 });
6. 依賴與擴展
依賴更多的是含有一種組合的含義,而擴展更多的是繼承含義,如果組件A依賴于組件B,說明組件A由組件B組成。如果組件A擴展于組件B,那么組件A中可以使用組件B的全部屬性、事件、方法。關于依賴與擴展的含義本書將在第6章中做進一步講解,目前讀者僅需了解擴展組件可以使用被擴展組件的全部屬性、方法、事件,例如文本框擴展于驗證框,此時我們可以在文本框中使用驗證框屬性required,例如:
<input class= "easyui-textbox" data-options ="required:true" >
所有的組件都擁有options方法,該方法以JSON格式返回一個選項對象,所謂的選項對象就是指組件初始化完畢后的配置??梢酝ㄟ^下面的JavaScript函數打印文本框的options對象:
01 function writeObj(obj){ 02 var description = ""; 03 for(var i in obj){ 04 var property=obj[i]; 05 description+=i+" = "+property+"\n"; 06 } 07 alert(description); 08 } 09 writeObj($('#tb').textbox('options'));
運行結果如圖2.8所示。

圖2.8 文本框選項對象的值
提示
EasyUI組件通常會使用對象作為屬性、事件或者方法的參數,如果讀者無法明確參數的含義,可以使用writeObj函數打印參數,或者使用console.log()函數在控制臺中打印參數。
options是一個JSON格式的對象,我們可以通過相應的方法獲取指定的字段值,例如通過options方法獲取組件的required屬性值,代碼如下:
01 var option = $('#tb').textbox('options'); 02 var required = option.required;
7. 默認配置
每個組件都會定義自己的默認配置,每當初始化組件時都會使用默認配置來初始化那些開發者未設置的屬性或事件,例如我們可以獲取文本框的默認寬度,代碼如下:
$.fn.textbox.defaults.width
8. EasyUI組件中的值
在EasyUI組件中有三種值,分別是:
- 輸入值。用戶輸入的值可以是任意的字母。
- 存儲值。根據用戶輸入不可信原則,用戶輸入的值必須經過相應的過濾和限制,存儲值是將用戶的輸入進行過濾以及解析后的最終值。
- 展示值。用戶并不希望顯示一些枯燥的數字,例如用戶更希望看到XX年XX月XX日格式的日期,而非一串時間戳數字,展示值就是將存儲值格式化為指定的格式后的值。
我們稱用戶輸入值為Input,存儲值為Value,展示值為Text??梢酝ㄟ^initValue、getValue、setValue方法來初始化存儲值、獲取存儲值以及設置存儲值??梢酝ㄟ^getText、setText方法來獲取展示值、設置展示值。關于存儲值和展示值的區別,下面舉個簡單的例子。中國的用戶更希望看到例如XX年XX月XX日這樣格式的日期,然而對于計算機而言,更希望處理時間戳格式的日期。此時我們會設計兩個輸入框,其中一個輸入框展示XX年XX月XX日格式的日期,另一個輸入框通常會隱藏起來,保存計算機能理解的時間戳,最終在提交表單時將時間戳傳輸給服務器。將存儲值轉化成展示值的過程稱為格式化(formatter),將輸入值轉化成存儲值的過程稱為解釋(parser)。EasyUI中通常會使用包含Value的字符串來命名存儲值的屬性或者方法,使用包含Text的字符串來命名展示值的屬性或者方法。讀者在后續的學習中應當作到望文生義。
提示
在文本框中必須先設置存儲值,之后才能設置展示值。如下代碼運行后會發現存儲值和展示值都被設置為2。
01 $('#tb').textbox('setText',"1"); 02 $('#tb').textbox('setValue',"2");
9. EasyUI方法的鏈式操作
EasyUI組件的方法(除獲取數據的方法外)返回的為該組件對象,因此可以對EasyUI方法使用鏈式操作,例如:
$('#tb').textbox('setValue',"2").textbox('setText',"1");
2.1.3 密碼框(PasswordBox)
EasyUI提供了專門用于輸入密碼的組件密碼框。密碼框提高了用戶的交互性,它通過使用指定的字符來替換用戶輸入的密碼從而防止用戶密碼泄露,密碼框的右側是一個眼狀圖標,可以通過單擊該圖標顯示用戶輸入的密碼。
密碼框的依賴關系如下:
- textbox
密碼框擴展于:
- textbox
密碼框的默認配置定義在$.fn.passwordbox.defaults中。
1. 密碼框用法
使用標記創建密碼框的方法如下:
<input class="easyui-passwordbox" >
使用JavaScript創建密碼框的方法如下:
01 <input id="pb" type="text" style="width:300px"> 02 $(function(){ 03 $('#pb').passwordbox({ 04 prompt: 'Password', 05 showEye: true 06 }); 07 });
2. 密碼框屬性
密碼框常用屬性說明見表2.7。
表2.7 密碼框常用屬性說明

3. 密碼框事件
密碼框在文本框的基礎上無新增事件。
4. 密碼框方法
密碼框常用方法說明見表2.8。
表2.8 密碼框常用方法說明

2.1.4 數字框(NumberBox)
數字框用于過濾用戶的輸入值使用戶僅能輸入數字,可以把存儲值轉換為不同類型的展示值(比如:數字、百分比、貨幣,等等)。可以通過formatter方法來自定義展示格式,通過parser方法將輸入值解析成存儲。
數字框的依賴關系如下:
- textbox
數字框擴展于:
- textbox
數字框的默認配置定義在$.fn.numberbox.defaults中。
1. 數字框的用法
使用標記創建數字框的方法如下:
<input type="text" class="easyui-numberbox" value="100" data-options="min:0,precision:2">
使用JavaScript創建數字框的方法如下:
01 <input type="text" id="nn"> 02 $('#nn').numberbox({min:0,precision:2});
2. 數字框屬性
數字框常用屬性說明見表2.9。
表2.9 數字框常用屬性說明

其中min、max、precision屬性主要用于控制輸入值與存儲值之間的轉換規則,例如設置precision的值為2,那么用戶如果輸入的是3.12345則會被自動過濾成3.12。filter屬性主要用于過濾輸入值,其參數e是一個事件對象,可以通過e.keyCode獲取當前按下的鍵的ASCII碼,返回true則接收該字符,返回false則禁止輸入該字符。
decimalSeparator、groupSeparator、prefix、suffix參數則為數字框內置的一些將存儲值轉換成展示值的規則,例如設置prefix值為美元符“$”,當存儲值為1時,展示值則為“$1”。
formatter、parser屬性可以用來自定義輸入值、存儲值以及展示值之間的轉化規則。formatter用于將存儲值格式化為展示值,parser用于將輸入值解析成存儲值。初學者在使用這兩個屬性時經常會出現一系列的問題,這是因為沒有理順這兩個屬性觸發的時機,下面我們將重點講解,先看下面的代碼:
01 <input type="text" id="nn"> 02 <script> 03 $(function(){ 04 $('#nn').numberbox({ 05 prefix:'$', 06 //formatter中接收的是一個存儲值 07 formatter:function(value){ 08 alert("formatter"); 09 return parseInt(value)+1; 10 }, 11 //parser中接收的是一個輸入值 12 parser:function(s){ 13 alert("parser"); 14 return parseInt(s)-1; 15 } 16 }); 17 }); 18 </script>
讀者可以將其復制到自己的文件中運行,運行這段代碼后我們可以發現:
- prefix屬性無法定義展示值前綴。
- 當頁面刷新時會先執行parser中定義的方法,再執行一次formatter。
- 當文本框內的內容發生改變時,會依次執行parser、parser、formatter、formatter屬性中的方法。
第一個問題很容易理解,因為數字框默認在formatter屬性方法中將存儲值轉化成展示值,在parser屬性中將輸入值轉化成存儲值。因此設置prefix屬性后數字框會在默認的parser屬性方法中檢查用戶輸入值是否有指定前綴,有的話就將前綴移除并將處理后的值作為存儲值保存,然后在formatter方法中的存儲值前面加上前綴。上述代碼中重新定義了parser和formatter屬性,此時數字框默認的parser以及formatter屬性將會被覆蓋,因此prefix屬性會失效。
在文本框中向讀者講解了值的概念,其實文本框在創建時會新增兩個輸入框,此時HTML如下:
01 <!—初始化框,開發者編寫的標記,用于保存初始化配置和存儲值, 02 通常也會將選項對象綁定到初始化框上-> 03 <input type="text" id="nn" type="hidden"> 04 <!—展示值框,文本框新增的標記,用于存放展示值--> 05 <input class="textbox-text"> 06 <!---存儲值框,文本框新增的標記,用于存放存儲值--> 07 <input type="hidden" class="textbox-value">
讀者可以發現,其實文本框向用戶顯示的僅僅是展示值框,而初始化框和存儲值框會被隱藏,也就是說用戶其實是在展示值框中進行輸入的。此時我們再看這段代碼:
01 <input type="text" id="nn"> 02 <script> 03 $(function(){ 04 $('#nn').numberbox({ 05 prefix:'$', 06 }); 07 }); 08 </script>
這段代碼的含義是在數字前面加上一個美元符$前綴,它的運行原理如下:當組件加載時會先將初始化框中的初始值使用parser屬性中的方法進行解析,如果初始值是$111的話會將其解析成111,如果是其他格式的話例如222則仍然會解析成222并將解析后的值保存到存儲值框中,接下來formatter屬性會取出存儲值,并在其前面加上前綴后保存到展示值框中顯示。具體的過程如圖2.9所示。
提示
由于用戶輸入值有可能是合法展示值,也有可能是合法的存儲值,還有可能是一些非法值,所以在parser中需要對用戶輸入值進行判斷和過濾。

圖2.9 數字框初始化流程圖
當數字框失去焦點時,數字框會調用一次fix方法,該方法中調用一次parser屬性方法,將用戶輸入數據轉換成存儲值,接著該方法中會使用數字框的setValue方法保存存儲值,但是在setValue方法中也會調用一次parser屬性方法,這是因為setValue方法可以被開發者直接調用,例如:
$('#nn').numberbox('setValue',’$11’)
因為該方法中仍然需要對傳入的值進行解析,并將其轉化成合法的存儲值,這就是為什么parser屬性會被調用兩次的原因。接著會使用一次formatter屬性方法格式化存儲值,注意在處理完畢后會再調用一次formatter屬性方法格式化存儲值,這兩次的調用區別是,第一次格式化的存儲值是parser處理完畢后返回的值,第二次格式化的存儲值是通過getValue方法獲取的數字框存儲值。
如果讀者目前無法完全理解這兩個屬性的話也沒關系,對于parser屬性和formatter屬性,讀者只需要記住一句話,parser屬性是將用戶輸入的數據解析成合法的存儲值,而formatter是將存儲值格式化為展示值。下面我們利用這兩個屬性給文字添加美元符前綴,部分代碼如下:
01 <input type="text" id="nn" value="111"> 02 <script> 03 $(function(){ 04 $("#nn").numberbox({ 05 parser:function(s){ 06 s = $.trim(s.replace("$","")); 07 return s; 08 }, 09 formatter:function(value){ 10 return '$'+value; 11 } 12 }); 13 }); 14 </script>
通過上述的講解,讀者必須理解如下兩個知識點:
- 所有直接或間接擴展于文本框的組件向讀者展示的都是其展示值框,由于初始化框被隱藏,因此除了部分樣式外,一切在初始化框中設置的樣式都不能生效,此時可以使用cls屬性給展示值框添加新的風格,不過該風格只適用于展示值框,并不適用于文本框的標簽。通常我們使用<div>標記作為文本框類組件的父容器,并在父容器中添加相關的風格。由于初始化框被隱藏,我們無法通過選擇器來選中指定的文本框組件并為其綁定事件,因此文本框提供了textbox方法,該方法返回文本框中的展示值框對象,開發者可以為展示值框綁定相關的時間。
- parser屬性是將輸入值轉換成存儲值,用戶的輸入值可能就是合法的存儲值,也可能是展示值,還有可能是非法值,開發者在parser屬性中一定要做充分的判斷。
3. 數字框事件
數字框在文本框的基礎上無新增事件。
4. 數字框方法
數字框常用方法的說明見表2.10。
表2.10 數字框常用方法說明

5. 深入理解數字框的值
我們已經向讀者講解了EasyUI中的三個值,它們分別是輸入值、展示值以及存儲值,這里講到數字框實際上由以下三部分組成:
- 初始化框:用于保存組件初始化的配置以及存儲值。
- 存儲值框:用于保存存儲值。
- 展示值框:用于顯示展示值,以及接收用戶的輸入值。
其中初始化框中保存的是初始化的配置以及存儲值,一些jQuery開發者習慣使用例如$('#nn').val('11')的方法給數字框賦值,讀者可以發現此這種方法其實只是給初始化框賦值,并不會改變數字框的值。但是通過$('#nn').val()方法可以取出數字框的存儲值,這是因為存儲值也會被保存在初始化框中。這樣做的好處很多,例如在提交表單時,服務器端可以直接根據初始化框中的name屬性獲取數字框的存儲值。
展示值框有兩個作用,首先它接收用戶的輸入,也就是說輸入值其實是被輸入到展示值框中的;其次它向用戶顯示展示值,用戶的輸入值與展示值之間的轉換在數字框中需要先使用parser屬性方法將輸入值轉換成存儲值,再使用formatter屬性方法將存儲值轉化成展示值。
存儲值框中會保存存儲值,可以通過getValue方法獲取其值。
接下來請讀者思考自定義驗證規則時到底是對數字框的哪個值進行驗證呢?請看下面的代碼:
01 <input type="text" id="nn" value="1"> 02 <script> 03 $(function(){ 04 $("#nn").numberbox({ 05 validType:"englishOrNum", 06 prefix:'$', 07 }); 08 //自定義驗證規則,只能輸入數字 09 $.extend($.fn.validatebox.defaults.rules, { 10 englishOrNum : { 11 validator : function(value) { 12 return /^[0-9]{1,}$/.test(value); 13 }, 14 message : '請輸入數字' 15 } 16 }); 17 }); 18 </script>
最終運行結果如圖2.10所示。

圖2.10 帶驗證的數字框
我們知道該示例中存儲值為一個純數字,而展示值為一個帶美元符號前綴的數字,驗證規則中自定義了一個驗證用戶輸入是否為數字的規則??梢园l現當用戶輸入一串數字后仍然無法通過驗證,這是因為驗證方法也會對展示值進行驗證,如果我們希望僅僅驗證存儲值的話,那就必須在自定義驗證規則中對展示值進行解析,如下代碼所示。
01 $.extend($.fn.validatebox.defaults.rules, { 02 englishOrNum : { 03 validator : function(value) { 04 value = $.trim(value.replace("$",""));//去除前綴 05 return /^[0-9]{1,}$/.test(value); 06 }, 07 message : '請輸入數字' 08 } 09 });
- 程序員修煉之道:程序設計入門30講
- Visual C++程序設計教程
- Java Web開發學習手冊
- SoapUI Cookbook
- JavaScript+jQuery網頁特效設計任務驅動教程(第2版)
- Rust編程從入門到實戰
- R語言數據可視化實戰
- Learn Programming in Python with Cody Jackson
- Android項目實戰:手機安全衛士開發案例解析
- Java SE實踐教程
- Application Development with Parse using iOS SDK
- Android高級開發實戰:UI、NDK與安全
- 深入理解Kafka:核心設計與實踐原理
- Android開發進階實戰:拓展與提升
- Django 3 Web Development Cookbook