撰寫自用 Confirm 方法
前言
上一篇「讓 ASP.NET 也可以使用 MsgBox 方法」文章中提到如何封裝 JavaScript 的 alert 方法,另一個常使用在用戶端處理「詢問訊息」的就是 JavaScript 的 confirm 方法,在此篇文章我們將撰寫自用的 Confirm 方法,使頁面的程式碼儘量不要直接去撰寫 JavaScript 程式碼,以增加系統的維護性。
程式實作
我們將使用「撰寫自用的 ScriptManager 來管理用戶端指令碼」文中提及的 TBScriptManager 類別為基礎,在 TBScriptManager 類別新增處理「詢問訊息」會使用到相關方法。我們在 TBScriptManager 類別新增二個 GetConfirmScript 多載方法,用以取得詢問訊息相關的 JavaScript 程式碼;另新增 Confirm 方法來直接註冊詢問訊息的用戶端指令碼,以下將以實例說明這三個方法的使用時機及方式。
''' <summary>
''' 用戶端指令碼管理。
''' </summary>
Public Class TBScriptManager
''' <summary>
''' 處理訊息文字的跳脫字元。
''' </summary>
''' <param name="Message">訊息文字。</param>
Private Function ParserMessage(ByVal Message As String) As String
Dim sMessage As String
sMessage = Strings.Replace(Message, "'", "\'") '處理單引號
sMessage = Strings.Replace(sMessage, vbNewLine, "\n") '處理換行
Return sMessage
End Function
''' <summary>
''' 取得訊問視窗的用戶端指令碼。
''' </summary>
''' <param name="Message">訊息文字。</param>
Public Overloads Function GetConfirmScript(ByVal Message As String) As String
Dim sMessage As String
Dim sScript As String
sMessage = ParserMessage(Message)
sScript = String.Format("if (confirm('{0}')==false) {{return false;}}", sMessage)
Return sScript
End Function
''' <summary>
''' 取得訊問視窗的用戶端指令碼。
''' </summary>
''' <param name="Message">訊息文字。</param>
''' <param name="TrueScript">回應 true 時要執行的用戶端指令碼。</param>
''' <param name="FalseScript">回應 false 時要執行的用戶端指令碼。</param>
Public Overloads Function GetConfirmScript(ByVal Message As String, _
ByVal TrueScript As String, ByVal FalseScript As String) As String
Dim sMessage As String
Dim sScript As String
sMessage = ParserMessage(Message)
sScript = String.Format("if (confirm('{0}')){{ {1} }} else {{ {2} }}", sMessage, TrueScript, FalseScript)
Return sScript
End Function
''' <summary>
''' 詢問視窗。
''' </summary>
''' <param name="Message">訊息文字。</param>
''' <param name="TrueScript">回應 true 時要執行的用戶端指令碼。</param>
''' <param name="FalseScript">回應 false 時要執行的用戶端指令碼。</param>
Public Sub Confirm(ByVal Message As String, ByVal TrueScript As String, ByVal FalseScript As String)
Dim sScript As String
sScript = GetConfirmScript(Message, TrueScript, FalseScript)
Me.RegisterStartupScript("Confirm", sScript)
End Sub
End Class
案例一:按鈕加上詢問訊息,按「確定」才會引發按鈕的 Click 事件
按鈕加上詢息訊息是常使用到的案例,例如按下刪除鈕時,先詢問用戶是否確定刪除資料,當按「確定」時才會真正去執行刪除動作。我們可以在 Page Load 事件中,去設定 Button.OnClientClick 屬性,加入詢問訊息的用戶端指令碼。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Button1.OnClientClick = Me.BeeScript.GetConfirmScript("確定刪除此筆資料嗎?")
End Sub
案例二:純用戶端的詢問訊息
詢問訊息只是在用戶端執行,並不會產生 PostBack。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sScript As String
sScript = Me.BeeScript.GetConfirmScript("純用戶端的詢問訊息?", "alert('按了確定')", "alert('按了取消')")
HyperLink1.Attributes("onclick") = sScript
End Sub
案例三:先執行伺服端程式再彈出詢問訊息,依用戶端回應再接續執行
例如有登打請假單儲存時,執行儲存完畢要彈出一個是否送審詢問訊息。在 WinForm 撰寫這個程式碼非常單純,只要在儲存後彈出詢問訊息,等待用戶回應接續執行後面的程式碼即可。可是在 WebForm 要撰寫相同的功能就有點麻煩了,因為整個程式的流程是在伺服端及用戶端交互運作。
請假單儲存(伺服端) -> 彈出詢問訊息(用戶端) -> 取得用戶端回應決定是否送審(伺服端)
在 WebForm 要處理這類問題,要分為二個階段處理,第一個階段處理「請假單儲存(伺服端) -> 彈出詢問訊息(用戶端) 」,在下面的程式碼中,訊問訊息的回應結果無論是「確定」或「取消」都會產生 PostBack 動作傳不同的參數。
Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
Dim sTrueScript As String
Dim sFalseScript As String
'執行請假單儲存的程式碼
'儲存完成彈出詢問訊息,__EVENTTARGET 設為 "SaveConfirm"
sTrueScript = "__doPostBack('SaveConfirm','True')"
sFalseScript = "__doPostBack('SaveConfirm','False')"
Me.BeeScript.Confirm("假單要送審嗎?", sTrueScript, sFalseScript)
End Sub
第二階段在 Page Load 事件處理用戶端詢問訊息的回應「取得用戶端回應決定是否送審(伺服端)」
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'處理詢問訊息的回應
Dim sEventTarget As String = Me.Request.Form("__EVENTTARGET")
Dim sEventArgument As String = Me.Request.Form("__EVENTARGUMENT")
If String.Equals("SaveConfirm", sEventTarget, StringComparison.CurrentCultureIgnoreCase) Then
If String.Equals(sEventArgument, "True", StringComparison.CurrentCultureIgnoreCase) Then
'按了確定要執行的程式碼
End If
If String.Equals(sEventArgument, "False", StringComparison.CurrentCultureIgnoreCase) Then
'按了取消要執行的程式碼
End If
End If
End Sub