在設計管理介面時,一定會做「刪除」功能,我想很多人都會在「刪除」按鈕加上一個 JavaScript 確認的程式,以確保使用者沒有誤觸刪除按鈕而導致資料直接被刪除。
對一個普通的按鈕來說,要加上「刪除確認」的程式是很容易的,只要在 Button 控制項的 OnClientClick 屬性加上 confirm() 函數就可以做倒刪除確認的功能:
<asp:Button ID="mDelete_Button" runat="server" Text="刪除"
OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;" />
而對於最常用需要用到刪除功能的地方不外乎是 GridView、DetailsView 或 FormView 控制項中,如果你要在這些控制項裡增加「刪除」功能是很容易的,一般來說會有兩種作法:
第一種:新增一個 CommandField 宣告,就可以新增一個刪除的按鈕:
<asp:CommandField ButtonType="Button" ShowDeleteButton="true"
DeleteText="刪除" HeaderText="刪除" />
但是第一種作法很不容易加上 OnClientClick 屬性,以 GridView 控制項為例,真的要替 CommandField 的刪除按鈕加上 onclick 屬性必須實做 RowDataBound 事件,並在事件中找到這個 Button 控制項 ( 如果你 CommandField 中的 ButtonType 屬性設定為 Button 的話 ),再手動加入 onclick 屬性(Attribute),這真是太麻煩了。
第二種:新增一個 TemplateField 宣告,並自己新增 Button 控制項進去,有經驗的人就知道只要將 CommandName 設定成 Delete 就可以讓這個按鈕跟使用 CommandField 的刪除功能一模一樣,其實 CommandField 輸出的控制項就是將 CommandName 設定為 Delete。如果要加上刪除確認功能,這時就不需要再寫 Code Behind 的程式了,直接在 *.aspx 頁面的刪除按鈕加上 OnClientClick 屬性就好了,就如同本篇文章最上面的那個範例一樣。
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="mDelete_Button" runat="server" CommandName="Delete"
Text="刪除" OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;" />
</ItemTemplate>
</asp:TemplateField>
不過,我今天要講的技巧更厲害,是透過 ASP.NET 2.0 的 Control Adapter 機制,直接設定「全站」所有的 Button 控制項只要遇到 CommandName 為 Delete 的,就自動加上 OnClickClick 屬性進行刪除確認的功能。
首先,你必須在你的網站專案加上 App_Browsers 目錄,並新增一個 ControlAdapters.browser 檔案 (檔名可以改,副檔名不能改),並輸入以下內容:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.Button" adapterType="ButtonAdapter" />
<adapter controlType="System.Web.UI.WebControls.LinkButton" adapterType="ButtonAdapter" />
<adapter controlType="System.Web.UI.WebControls.ImageButton" adapterType="ButtonAdapter" />
</controlAdapters>
</browser>
</browsers>
這裡我定義了 3 個不同的按鈕控制項配置器(Control Adapter),並且都指定到 ButtonAdapter 類別。
然後再到 App_Code 目錄下新增一個 ButtonAdapter.cs 類別檔,程式也很短,如下:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class ButtonAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter {
protected override void OnPreRender(EventArgs e)
{
IButtonControl btn = Control as IButtonControl;
// mDelete 是我自訂的 CommandName 名稱,你也可以改成你自己的名稱
if (btn.CommandName == "Delete" || btn.CommandName == "mDelete") {
Control.Attributes["onclick"] = "if(!confirm('你確定要刪除嗎?')) return false;";
}
base.OnPreRender(e);
}
}
這樣就做完了!
整個網站完全不需要再特別定義 OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;" 指令,只要你的 CommandName 設定成 Delete 或 mDelete 都會自動加上 onclick 屬性,是不是一勞永逸呢!^_^
ASP.NET 2.0 的 Control Adapter 架構是我非常喜歡的一個架構,他可以針對不同的 Browser 以及針對不同的控制項進行客製化的修正,也可以用在像我今天講的這個開發技巧上,真的可以將程式碼的量降低,也降低專案的複雜度。
如果有興趣瞭解 Control Adapter 架構的人可以下載 ASP.NET 2.0 CSS Friendly Control Adapters 1.0 範例回來好好研究一下,相信會有更多的創意出現,記得回來跟我分享喔。:-)
相關連結