FineUI小技巧(2)將表單內全部欄位禁用、只讀、設定無效標識

三生石上(FineUI控制元件)發表於2014-06-23

需求描述

對錶單內的所有欄位進行操作也是常見需求,這些操作有:

  1. 禁用:表單欄位變灰,不響應使用者動作。
  2. 只讀:表單欄位不變灰,但不接受使用者輸入(實際上是設定DOM節點的readonly屬性),有觸發器的要隱藏起來
  3. 設定無效標識:一般用在伺服器端驗證失敗的提示資訊

介面效果

  1. 預設狀態
  2. 禁用狀態
  3. 只讀狀態
  4. 設定無效標識狀態

前臺程式碼

 前臺程式碼非常直觀,只是一個Form控制元件外加幾個Button控制元件,按鈕的響應事件在後臺完成:

 1 <f:PageManager ID="PageManager1" runat="server" />
 2 <f:Form Width="600px" LabelWidth="100px" OffsetRight="10px" LabelSeparator=":"
 3     BodyPadding="5px" EnableCollapse="true" ID="Form1" runat="server" Title="表單">
 4     <Rows>
 5         <f:FormRow>
 6             <Items>
 7                 <f:Label ID="Label3" Label="電話" Text="0551-1234567" runat="server" />
 8                 <f:Label ID="Label16" runat="server" Label="申請人" Text="admin">
 9                 </f:Label>
10             </Items>
11         </f:FormRow>
12         <f:FormRow>
13             <Items>
14                 <f:Label ID="Label4" Label="編號" Text="200804170006" runat="server" />
15                 <f:TextBox ID="TextBox2" Required="true" ShowRedStar="true" Label="電子郵箱" RegexPattern="EMAIL"
16                     RegexMessage="請輸入有效的郵箱地址!" runat="server">
17                 </f:TextBox>
18             </Items>
19         </f:FormRow>
20         <f:FormRow>
21             <Items>
22                 <f:DropDownList ID="DropDownList3" Label="審批人" runat="server" ForceSelection="false" Required="true" ShowRedStar="True">
23                     <f:ListItem Text="老大甲" Value="0"></f:ListItem>
24                     <f:ListItem Text="老大乙" Value="1"></f:ListItem>
25                     <f:ListItem Text="老大丙" Value="2"></f:ListItem>
26                 </f:DropDownList>
27                 <f:NumberBox ID="NumberBox1" Label="申請數量" MaxValue="1000" Required="true" runat="server"
28                     ShowRedStar="True" />
29             </Items>
30         </f:FormRow>
31         <f:FormRow>
32             <Items>
33                 <f:DatePicker runat="server" Required="true" Label="日期" EmptyText="請選擇日期"
34                     ID="DatePicker1" SelectedDate="2014-07-10" ShowRedStar="True">
35                 </f:DatePicker>
36                 <f:TimePicker ID="TimePicker1" ShowRedStar="True" Label="時間" Increment="30"
37                     Required="true" Text="08:30" EmptyText="請選擇時間" runat="server">
38                 </f:TimePicker>
39             </Items>
40         </f:FormRow>
41 
42         <f:FormRow>
43             <Items>
44                 <f:FileUpload runat="server" ID="filePhoto" EmptyText="請選擇一張照片" Label="個人頭像" Required="true"
45                     ShowRedStar="true">
46                 </f:FileUpload>
47             </Items>
48         </f:FormRow>
49         <f:FormRow>
50             <Items>
51                 <f:TextArea ID="TextArea1" runat="server" Label="描述" ShowRedStar="True" Required="True">
52                 </f:TextArea>
53             </Items>
54         </f:FormRow>
55         <f:FormRow>
56             <Items>
57                 <f:CheckBoxList ID="CheckBoxList1" Label="核取方塊列表" ColumnNumber="3" runat="server">
58                     <f:CheckItem Text="可選項 1" Value="value1" />
59                     <f:CheckItem Text="可選項 2" Value="value2" Selected="true" />
60                     <f:CheckItem Text="可選項 3" Value="value3" Selected="true" />
61                     <f:CheckItem Text="可選項 4" Value="value4" Selected="true" />
62                     <f:CheckItem Text="可選項 5" Value="value5" Selected="true" />
63                 </f:CheckBoxList>
64             </Items>
65         </f:FormRow>
66         <f:FormRow>
67             <Items>
68                 <f:RadioButtonList ID="RadioButtonList2" Label="單選框列表" ColumnNumber="3" runat="server">
69                     <f:RadioItem Text="可選項 1" Value="value1" />
70                     <f:RadioItem Text="可選項 2" Value="value2" />
71                     <f:RadioItem Text="可選項 3" Value="value3" Selected="true" />
72                     <f:RadioItem Text="可選項 4" Value="value4" />
73                     <f:RadioItem Text="可選項 5" Value="value5" />
74                 </f:RadioButtonList>
75             </Items>
76         </f:FormRow>
77     </Rows>
78 </f:Form>
79 <br />
80 <f:Button ID="btnDisableAll" Text="全部禁用" CssClass="marginr" runat="server" OnClick="btnDisableAll_Click">
81 </f:Button>
82 <f:Button ID="btnEnableAll" Text="全部啟用" CssClass="marginr" runat="server" OnClick="btnEnableAll_Click">
83 </f:Button>
84 <f:Button ID="btnReadOnlyAll" Text="全部只讀" CssClass="marginr" runat="server" OnClick="btnReadOnlyAll_Click">
85 </f:Button>
86 <f:Button ID="btnCancelReadOnlyAll" Text="取消只讀" CssClass="marginr" runat="server" OnClick="btnCancelReadOnlyAll_Click">
87 </f:Button>
88 <br />
89 <br />
90 <f:Button ID="btnMarkInvalid" Text="設定無效標識" CssClass="marginr" runat="server" OnClick="btnMarkInvalid_Click">
91 </f:Button>
92 <f:Button ID="btnClearInvalid" Text="取消無效標識" CssClass="marginr" runat="server" OnClick="btnClearInvalid_Click">
93 </f:Button>
View Code

後臺程式碼

因為幾個按鈕的邏輯類似,這裡我們定義一個代理(delegate),把相同的邏輯放在一個函式中完成,如下所示:

 1 private delegate void ProcessFormField(Field field);
 2 
 3 private void ResolveFormField(ProcessFormField process)
 4 {
 5     foreach (FormRow row in Form1.Rows)
 6     {
 7         foreach (Field field in row.Items)
 8         {
 9             if (field != null)
10             {
11                 process(field);
12             }
13         }
14     }
15 }

幾個按鈕的只需要呼叫剛剛定義的ResolveFormField函式,並傳入自己的代理實現即可:

 1 protected void btnDisableAll_Click(object sender, EventArgs e)
 2 {
 3     ResolveFormField(delegate(Field field)
 4     {
 5         field.Enabled = false;
 6     });
 7 }
 8 
 9 protected void btnEnableAll_Click(object sender, EventArgs e)
10 {
11     ResolveFormField(delegate(Field field)
12     {
13         field.Enabled = true;
14     });
15 }
16 
17 protected void btnReadOnlyAll_Click(object sender, EventArgs e)
18 {
19     ResolveFormField(delegate(Field field)
20     {
21         if (!(field is Label))
22         {
23             field.Readonly = true;
24         }
25     });
26 }
27 
28 protected void btnCancelReadOnlyAll_Click(object sender, EventArgs e)
29 {
30     ResolveFormField(delegate(Field field)
31     {
32         if (!(field is Label))
33         {
34             field.Readonly = false;
35         }
36     });
37 }
38 
39 protected void btnMarkInvalid_Click(object sender, EventArgs e)
40 {
41     ResolveFormField(delegate(Field field)
42     {
43         if (!(field is Label))
44         {
45             field.MarkInvalid("這個欄位出錯了!");
46         }
47     });
48 }
49 
50 protected void btnClearInvalid_Click(object sender, EventArgs e)
51 {
52     ResolveFormField(delegate(Field field)
53     {
54         if (!(field is Label))
55         {
56             field.ClearInvalid();
57         }
58     });
59 }
View Code

本章小結

本篇文章介紹瞭如何對錶單內全部欄位進行批次操作,要注意禁用和只讀的區別,雖然兩種情況下表單欄位都不響應使用者動作,但還是有一些細微的差別,首先是顏色的變化不同,其次只讀時會隱藏TriggerBox右側的觸發按鈕。

後臺的程式碼實現用到了C#代理(delegate),從JavaScript的角度看其實就是個回撥函式,只不過C#的強型別限制,必須把這個回撥函式抽象成一個型別而已。

專業版截圖

FineUI(專業版)是由三生石上全新打造的基於 jQuery 的專業 ASP.NET 控制元件庫,計劃在七月下旬正式釋出。

選擇FineUI(專業版)的四大理由:
1. 簡單:專業版和開源版相容(v4.x),您現在就可以使用開源版進行開發,等正式版釋出時只需替換 DLL 即可。
2. 極速:專業版基於 jQuery 庫重寫,使得 JS 和 CSS 體積大幅減少,頁面載入速度將是開源版的 2 倍以上。
3. 多彩:專業版內建 24 種 jQueryUI 皮膚,使用者還可以使用 jQueryUI ThemeRoller 建立專屬自己的皮膚。
4. 便宜:專業版不限開發者數量和永久免費升級,使得典型授權案例的費用減少為開源版的 1/3 左右。

宣告:

    1. FineUI(專業版)授權協議是商業授權,需購買使用。
    2. FineUI(開源版)授權協議是Apache License v2.0,免費下載使用,並且會繼續維護和開發,個人使用者推薦使用開源版。



原始碼與線上示例

本系列所有文章的原始碼均可自行下載:http://fineui.codeplex.com/

線上示例(暫時不可用):http://fineui.com/demo/#/demo/form/form_disabled.aspx

這個示例會新增到下個版本的FineUI(開源版)中,因此線上示例還不可見,需要的同學請自行下載全部原始碼,自己執行。 

 

如果本文對你有所啟發或者幫助,請猛擊“好文要頂”,支援原創,支援三石!

 

 

《FineUI小技巧》系列文章目錄

 

相關文章