カスタム サーバー コントロールを作成して、Web フォーム アプリケーション用の特定のマークアップと JavaScript ハンドラーを備えたボタン要素を生成しています。もちろん、それらはポストバックを引き起こす可能性があるので、フォーム検証用の ASP の検証コントロール、特にクライアント側フレームワークで機能することを望みます。
このボタン サーバー コントロールは、提供されたコードを使用してボタン タグOnClientClick
の属性を発行するプロパティをサポートしonclick
ます (主に、ユーザーがリスト ビューなどの削除ボタンをクリックしたときの単純な確認の再プロンプトに使用されます) asp:Button
。 onclick 属性としての検証スクリプトはほとんど効果がありません。実際のところ、標準OnClientClick
で とValidationGroup
属性の両方を指定すると、結果asp:Button
はかなり悪くなります。これがそのままでは機能しない理由を痛烈に明白に示す例を次に示します。
ページのマークアップ
<asp:Button ID="btnSaveAsp" ValidationGroup="vgMyValidationGroup" OnClientClick="return true;" runat="server" />
レンダリングされたマークアップ
<input type="submit" name="ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp" value="Save" id="cphBodyContent_lvUsers_btnSaveAsp_0"
onclick='return true; WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$cphBodyContent$lvMyList$ctrl0$btnSaveAsp", "", true, "vgMyValidationGroup", "", false, false))'>
これは、検証を使用してコントロールを接続するための既存の非動作コードです。onclick
同様の属性を発行する以外の方法でこれを達成するための最善の方法に関する多くのドキュメントを見つけることができませんでした。Page.ClientSCript.RegisterForEventValidation
オーバーライドされたメソッドでを呼び出すとAddAttributesToRender
、クライアント側の検証が接続されると思いましたが、想定どおりに機能していないようです。必要に応じて、追加の処理をボタンのクリック イベントにバインドするために jQuery を使用できます。
カスタム サーバー ボタン コントロール
<ToolboxData("<{0}:Button runat=server></{0}:Button>")> _
<ParseChildren(False)> _
<PersistChildren(True)> _
Public Class Button
Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackDataHandler
Public Sub New()
MyBase.New(HtmlTextWriterTag.Button)
End Sub
<Category("Behavior")> _
<DefaultValue("")> _
Public Overridable Property PostBackUrl As String
Get
Return If(ViewState("PostBackUrl"), String.Empty)
End Get
Set(value As String)
ViewState("PostBackUrl") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue(True)> _
Public Overridable Property CausesValidation As Boolean
Get
Return If(ViewState("CausesValidation"), True)
End Get
Set(value As Boolean)
ViewState("CausesValidation") = value
End Set
End Property
<Category("Validation")> _
<DefaultValue("")> _
Public Overridable Property ValidationGroup As String
Get
Return If(ViewState("ValidationGroup"), String.Empty)
End Get
Set(value As String)
ViewState("ValidationGroup") = value
End Set
End Property
<Category("Behavior")> _
<DefaultValue("")> _
<Description("Client-side script to be run when the button is clicked.")> _
Public Property OnClientClick As String
Get
Return If(ViewState("OnClientClick"), String.Empty)
End Get
Set(value As String)
ViewState("OnClientClick") = value
End Set
End Property
Protected Overrides Sub AddAttributesToRender(writer As HtmlTextWriter)
MyBase.AddAttributesToRender(writer)
If Not String.IsNullOrEmpty(OnClientClick) Then
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, OnClientClick)
End If
Dim postBackOptions = GetPostBackOptions()
If postBackOptions.TargetControl Is Me Then
writer.AddAttribute(HtmlTextWriterAttribute.Name, ClientID)
End If
If Page IsNot Nothing Then
Page.ClientScript.RegisterForEventValidation(postBackOptions)
End If
End Sub
Protected Overridable Function GetPostBackOptions() As PostBackOptions
Dim options As New PostBackOptions(Me) With {
.ClientSubmit = False
}
If Page IsNot Nothing Then
If CausesValidation AndAlso (Page.GetValidators(ValidationGroup).Count > 0) Then
options.PerformValidation = True
options.ValidationGroup = ValidationGroup
End If
If Not String.IsNullOrEmpty(PostBackUrl) Then
options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl))
End If
End If
Return options
End Function
End Class
asp:CompareValidator
現在、このコードはin the sameでは機能せずValidationGroup
、サーバーにポストバックする前に 2 つのパスワード リセット フィールドが等しいかどうかを判断したり、要求がサーバー側に到達した後に検証を行ったりしません。