返回列表 發帖

Ext JS 初探 - 美化表單的幾個簡單步驟

不久前有提到 Ext JS 推出新版後我才開始注意到了 Ext JS,官方網頁上的表單範例做的蠻簡潔美觀的,不會有過度裝飾的感覺 (完全是個人主觀偏好喔),這種內斂的美感正是我所想要的風格,因此馬上有了想利用 Ext JS 來改造目前現有的表單這樣的一個想法,以下是一些些的心得分享,希望能對想使用 Ext JS 的人有些幫助。

這是一個很單純的表單,有文字輸入框、下拉選單、日期輸入(目前看到的還是單純的文字輸入)、多行文字輸入及一個送出的按鈕:
<form id="form2" method="post">
<h3>表單範例</h3>
<table>
  <tr>
    <td class="title">文字輸入:</td>
    <td style="font-family: verdana;"><input type="text" id="text2" name="text2" /></td>
  </tr>
  <tr>
    <td class="title">下拉選單:</td>
    <td style="font-family: verdana;"><select id="st2" name="st2">
        <option></option>
        <option>Aeiou</option>
        <option>Andy</option>
        <option>Amy</option>
        <option>Aloha</option>
        <option>Apple</option>
        <option>Application</option>
        <option>Aprik</option>
        <option>Backup</option>
        <option>Book</option>
        </select>
    </td>
  </tr>
  <tr>
    <td class="title">日期選擇:</td>
    <td style="font-family: verdana;"><input type="text" id="dp2" name="dp2" /></td>
  </tr>
  <tr>
    <td class="title">多行輸入:</td>
    <td><textarea id="ta2" name="ta2" cols="50" rows="6"></textarea></td>
  </tr>
  <tr>
    <td class="title"> </td>
    <td>
      <input type="submit" id="bt2" name="bt2" value="按鈕" />
    </td>
  </tr>
</table>
</form>
現在我們要做的就是透過 Ext JS 所提供的功能來改造這個表單,除了要讓表單看起來漂亮一點之外,還可以加入一些和 user 互動的對話框以及基本的輸入條件檢查。如果你有看過 Ext JS 所提供的範例,你會發現 Ext JS 可以動態的產生表單,不過我想還是有很多人的需求會是需要改變現有的表單,一方面是現有的系統就可以直接拿來改造了,另一方面是表單畫面可能都是設計人員或美工作好的,用動態產生表單的話要怎麼和他們溝通啊,是吧?等我有機會做個 one page application 的時候再來考慮動態產生表單好了。

首先要準備 Ext JS 的最新版本,請直接上官方網站去下載並解開壓縮檔。先解釋一下我所了解的 Ext JS 運作方式,在 Ext JS 一開始的版本並不是可以獨立運作的,而是架構在例如 prototype 或 YUI 的一些基本 function 之上,所以你可以看到在解開的檔案中有個 adapter 的目錄,底下是各個不同 library 的橋接程式。但是在目前最新的 v1.1 版內,Ext JS 自己寫了一組相似的 function,因此只要使用 v1.1 以上的版本,就可以獨立運作不用搭配其他 library 了。這次的範例當然也是選擇搭配內建的 library 以求方便,以下是你在網頁內需要引用的 js 和 css:
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />
<script type="text/javascript" src="adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-all.js"></script>
這邊要再解釋一下,Ext JS 完整 library 的檔案也不算小,所以和其他 library 一樣,你可以選擇性的 include 要使用的 function 即可,包含 js 和 css,我們為了方便起見,直接引用 ext-all.css 和 ext-all.js。官方網站有提供 Build your own Ext 的功能,可以讓你挑出你所需要的功能再幫你壓縮並且讓你下載。


第一步:先加個外框吧

幫你的表單加個美美的外框很容易,只要你剛引用的 ext-all.css 路徑正確,再加入以下的 html 即可:
<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>
  <div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">
    這邊放你原本的表單
  </div></div></div>
<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>
順利的話,你的表單已經看起來不太一樣了:




第二步:Ext.form.BasicForm 粉墨登場

該 JavaScript 登場了,Ext.form.BasicForm 可以用來改造現有的表單,除了簡單的美化、可以有輸入驗證外,下拉選單可以直接變成有自動完成的功能、也提供以月曆選擇日期的功能等等。你需要加入以下的 JavaScript:
Ext.onReady(function(){
  var fm2 = new Ext.form.BasicForm('form2');
  fm2.add(new Ext.form.TextField().applyTo('text2'));
  fm2.add(new Ext.form.ComboBox({transform:'st2'}));
  fm2.add(new Ext.form.DateField().applyTo('dp2'));
  fm2.add(new Ext.form.TextArea().applyTo('ta2'));
})
Ext.onReady() 可以讓裡面的程式等到網頁載入完成後再執行,因為我們是利用現成的表單來做加強,所以必須確保網頁載入完成再做,這樣才不會有問題。從 new Ext.form.BasicForm() 開始,依序就是建立 BasicForm,加入 TextField、ComboBox、DateField、TextArea,你可以看到 new Ext.form.TextField().applyTo('text2') 這樣的語法就是直接將 id=text2 的這個欄位以 Ext JS 的 TextField 來套用,不同的是下拉選單做法不太一樣,必須使用  transform 這個參數傳入我們要改造的下拉選單的 id。先來看一下成果吧:



比較不一樣的地方就是下拉選單和輸入日期的欄位,有了 Ext JS 的加持後,馬上加入了特異功能。眼尖的人可能注意到了,我們還沒去動到表單原本的按鈕,沒錯,因為 Ext JS 沒有提供類似上面用到的技巧可以直接將表單的按鈕給取代掉,所以我們必須用不同的方式來產生按鈕,而且必須將原本表單內的按鈕給移除掉。


第三步:加入按鈕

先修改一下原本的 html ,把按鈕先隱藏或移除掉,再加入一個 newbutton 的 div 如下:
<!--input type="submit" id="bt2" name="bt2" value="按鈕" /-->
<div id="newbutton"></div>
Ext.onReady() 內再加入這一段:
var newbutton = new Ext.Button('newbutton', {text: '按鈕'});
這樣按鈕就順利加入了:



目前這個的按鈕是沒有任何作用的,我們得再加入一些料。在這之前先提示一下,在 Ext JS 的設計中,表單的 submit 方式都是以 Ajax 的方式在運作,而不是傳統的 post 到另一頁的方式。當我們用了 Ext.form.BasicForm 的時候,這個 form 的 submit 事件就已經被攔截了,即使原本表單內的 submit 按鈕也不會有作用,所以我們得先將這個攔截掉 submit 事件的 listener 給取消掉,然後在新增的 button 內加入事件的處理。剛那一段新增 button 的程式碼就先 remark 掉,換上一段新的:
//var newbutton = new Ext.Button('newbutton', {text: '按鈕'});
Ext.get('form2').un("submit", fm2.onSubmit, fm2);
var newbutton = new Ext.Button('newbutton', {
  text: '按鈕', 
  handler: function(){
    if (fm2.isValid()) {
      Ext.Msg.show({
       title:'再確認一下',
       msg: '按下 OK 就把資料送出囉,你確定嗎?',
       buttons: Ext.Msg.OKCANCEL,
       fn:  function(btn, text){
            if (btn == 'ok'){
                fm2.el.dom.submit();
            } else if (btn == 'cancel') {
                Ext.Msg.alert('告訴你', '你按了取消,所以不會送出!');
            }
        },
       animEl: 'newbutton'
    });
    } else {
      Ext.Msg.alert('訊息', '請填寫完成後再送出!');
    }
  }
});
上面這一段先用了 Ext.get('form2').un("submit", fm2.onSubmit, fm2) 把這個 form 的 submit listener 給取消掉,接著新增 button 並指定處理的事件。fm2.isValid() 是判斷這個 form 裡面的欄位驗證是否通過,嘿嘿,不過我們還沒把驗證的功能加入到欄位中,等會兒會再看到。另外還用到了 Ext.Msg.show() 和 Ext.Msg.alert() 來顯示訊息,詳細的參數就不多解釋了,看一下訊息的畫面好了:




第四步:基本驗證功能

對於表單比較實用的功能應該就是表單的驗證了,最基本的就是欄位是否有輸入值,我們可以透過參數來設定。在產生欄位的同時可以傳入很多樣的參數,例如:
fm2.add(new Ext.form.TextField({allowBlank: false}).applyTo(Ext.get('text2')));

var textAreaSettings = {
  grow: true, 
  allowBlank: false
};
fm2.add(new Ext.form.TextArea(textAreaSettings).applyTo(Ext.get('ta2')));
產生 TextField 的同時傳入了 allowBlank: false,這就是代表這個欄位不能有空白。另外在產生 TextArea 的同時傳入了多個參數,包括高度自動增加及不能有空白,自動增高的功能聽起來相當不錯是吧,應該是非常適合 TextArea 這種欄位的,不過 Ext JS 的這個功能似乎有點小小的 bug,因為增高的幅度似乎會越來越大,目前還不算很實用。詳細的參數大家可以參考 API 文件(在下載的壓縮檔的 docs 目錄下就可以看到了),有相當多的設定是可以參數化調整的。

加入了以上兩個欄位的基本驗證後,當我們按下按鈕要送出時,就會先出現警告訊息,而且相關的欄位也會有變化如下:




第五步:再裝飾一下

完成了以上的步驟之後,其實已經達到了我們的目標了,但是下面這個功能不介紹一下的話實在對不起大家,因為只要加入短短的一行程式碼就立即有效,而且還蠻實用的喔。只要在 Ext.onReady() 裡面加入一行:
Ext.QuickTips.init();
直接來看看成果吧:



當滑鼠游標停留在那些未完成的欄位時,都會出現一個小小的浮動區塊提示相關訊息,你是不是在想說那些怎麼都是英文的啊?嘿嘿,當然都是可以透過參數去修改的,這些就留給大家去練習練習囉。

以上完整範例可以在此直接測試或查詢原始碼:
http://jsgears.com/_demo/index.php
To infinity and beyond!

請教如何做出連動的下拉選單???
另外此套件除了美化表單
可以做出Autocomplete的功能嗎???

TOP

你需要用 ExtJS 來完成這些功能嗎? 因為 ExtJS 的特色是在於有多樣且完整的 widget 可以讓你用來開發一個類似 windows 下的軟體,有比較豐富的 UI 表現而且都是以 AJAX 來完成和 server 端的溝通。要用來做連動的下拉選單和 AutoComplete 並不是不行,而是沒有現成的套件可以很方便的套用。關於 ExtJS 的詳細資料,你可以透過 ExtJS 的官方網站看到很棒的一些 Demo: http://extjs.com/,或是看看這個用 ExtJS 完成的網站

如果單純的是需要連動的下拉選單和 AutoComplete,建議可以去一些收集 JavaScript/AJAX Library 的網站搜尋,這一篇有提到兩個,很容易可以找到一些可用的程式喔。不過因為連動選單和 AutoComplete 的實作通常都是差異很大,說不定現成的程式並不符合自己的需求,這時你可能需要一些比較基礎的 Library 像是 prototypejQuery 來自己寫一個。
To infinity and beyond!

TOP

請問我照著步驟做....
為何此行 fm2.add(new Ext.form.DateField().applyTo('dp2'));
會錯誤(物件不支援此屬性或方法)??

TOP

不好意思,這一篇已經有點過時了,那時候用的 ExtJS 版本是 v1.1,你現在用的版本可能是 v2.2 的,所以語法上會有一些差異,你可以參考 ExtJS 的 API 文件 來查看最新的語法。

我看了一下你說的那一段,語法要修改一下才能用喔:
Ext.onReady(function(){
  var fm2 = new Ext.form.BasicForm('form2');
  fm2.add(new Ext.form.TextField({applyTo: 'text2'}));
  fm2.add(new Ext.form.ComboBox({transform:'st2'}));
  fm2.add(new Ext.form.DateField({applyTo: 'dp2'}));
  fm2.add(new Ext.form.TextArea({applyTo: 'ta2'}));
});
有看出差異了嗎?
To infinity and beyond!

TOP

成功了!謝謝!

TOP

請問我要新增button,但中文字按紐為何顯示不出來?
var newbutton = new Ext.Button('newbutton', {text: '按紐'});
.
.
.
<td><div id="newbutton"></div></td>  
如果要驗證表單某些欄位的值,一定要使用Ext的語法嗎?
document.form名稱.欄位名稱.value
就沒辦法使用是嗎?

TOP

大陸錄製的中文視頻教學
http://www.dojochina.com/index.php?q=node/889

TOP

本帖最後由 kenber 於 2010-6-18 11:23 編輯

回覆: 請問我要新增button,但中文字按紐為何顯示不出來?
包含驗證的內容, 改貼這一段就可以囉! ^_^

<script>
        Ext.onReady(function(){   
  var fm2 = new Ext.form.BasicForm('form2');   
  fm2.add(new Ext.form.TextField({applyTo: 'text2'}));   
  fm2.add(new Ext.form.ComboBox({transform:'st2'}));   
  fm2.add(new Ext.form.DateField({applyTo: 'dp2'}));   
  fm2.add(new Ext.form.TextArea({applyTo: 'ta2'}));  
  
  Ext.get('form2').un("submit", fm2.onSubmit, fm2);   
        var newbutton = new Ext.Button({   
  renderTo:'newbutton',
  text: '按鈕',   
  handler: function(){   
   
    if (fm2.isValid()) {   

      Ext.Msg.show({   
       title:'再確認一下',   
       msg: '按下 OK 就把資料送出囉,你確定嗎?',   
       buttons: Ext.Msg.OKCANCEL,   
       fn:  function(btn, text){   
            if (btn == 'ok'){   
                fm2.el.dom.submit();   
            } else if (btn == 'cancel') {   
                Ext.Msg.alert('告訴你', '你按了取消,所以不會送出!');   
            }   
        },   
       animEl: 'newbutton'  
    });   
    } else {   
      Ext.Msg.alert('訊息', '請填寫完成後再送出!');   
    }   
  }   
});  
                fm2.add(new Ext.form.TextField({
                        applyTo:'text2',
                        allowBlank: false
                })
               
                );   
                var textAreaSettings = {
                        applyTo:'ta2',
                  grow: true,   
                  allowBlank: false  
                };   
                fm2.add(new Ext.form.TextArea(textAreaSettings));  
});  

</script>

TOP

請問一下,下拉式選單如何可以重復的使用??

就是 按照範列作出來的下拉式選單,只能選取值一次,就不能改變了~(選完後,再選只出現該值可以選)

能不能像html裡的下拉式選單一樣,可以改變要選的值~謝謝
50 字節以內
不支持自定義 Discuz! 代碼

TOP

返回列表 回復 發帖