表示・非表示で入力系ユーザコントロールの検証コントロールを有効にするか決める方法(ASP.net) |
----
・複数画面で使用するテキストボックスなど
入力コントロールはユーザコントロールにする。
・ユーザコントロールに検証コントロールを含め、
単項目チェックはユーザコントロール内でクローズさせる。
(日付の範囲指定など複数の項目にまたがる検証は画面側で行う)
・入力値の検証はサーバ側で行う。
クライアントでの検証は行わない。
・画面もしくはメッセージ表示用ユーザコントロール内に
ValidationSummaryを配置し、エラーメッセージを一括表示する。
----
ある画面ではラジオボタンで追加入力エリアの表示・非表示を行っており
表示されている場合のみ、入力値の検証を行うという要件があります。
(ラジオボタンにあわせて、ポストバックせずに追加入力エリアが
表示、または非表示になります)
その場合の実装を考えてみました。
1.ユーザコントロールに書き込み専用パブリックプロパティ「CheckValid」を作成。
プロパティの処理で検証コントロールのEnabledを設定する。
2.画面(Webページ)のページロードで
ラジオボタンコントロールの値※によって
パネルをshow/hideするjavascriptを仕込む。
(今回もjQueryを使用)
また、表示・非表示するユーザコントロールのプロパティ「CheckValid」を
ラジオボタンコントロールの値※を設定する。
※表示ラジオボタンの値を参照させ、Trueの場合は表示(入力値の検証)する処理を
行うよう設定。
実装したイメージはこんな感じです。
【初期表示】

【表示時での入力エラー】

【非表示時での入力エラー】

では、実装です。
【入力用ユーザコントロール(ucInput.acx)】
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="ucInput.ascx.vb" Inherits="ucInput" %>
<asp:Panel ID="Panel1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="CustomValidator" ControlToValidate="TextBox1"
EnableClientScript="False" Display="None"
ValidateEmptyText="True">
</asp:CustomValidator>
</asp:Panel>
【入力用ユーザコントロール(ucInput.acx.vb)】
Partial Class ucInput
Inherits System.Web.UI.UserControl
''' <summary>
''' 非表示時の検証未実施設定
''' </summary>
''' <value>True:検証を行う、False:検証しない</value>
''' <remarks>非表示に検証エラーを行わないためのプロパティ</remarks>
Public WriteOnly Property CheckValid() As Boolean
Set(ByVal value As Boolean)
CustomValidator1.Enabled = value
End Set
End Property
''' <summary>
''' サーバ側の検証処理
''' </summary>
''' <param name="source"></param>
''' <param name="args"></param>
''' <remarks></remarks>
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
'未入力チェック
If String.Empty.Equals(args.Value) Then
CustomValidator1.ErrorMessage = "入力されていません。"
Me.TextBox1.CssClass = "input_error"
args.IsValid = False
Return
End If
'その他、DBチェックなど・・・
End Sub
''' <summary>
''' ページロード
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks>入力コントロールのスタイルシートを初期化</remarks>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.TextBox1.CssClass = ""
End Sub
End Class
【Webページ(Default.aspx)】
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register src="ucInput.ascx" tagname="ucInput" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
.input_error{
background-color:Aqua;
}
</style>
<script type="text/javascript">
//パネルの表示・非表示処理
function setShowHidePanel(panelID, showRadioID) {
if ($(showRadioID).attr("checked") == true) {
$(panelID).show();
}
else {
$(panelID).hide();
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/jquery.js" />
</Scripts>
</asp:ScriptManager>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
EnableClientScript="False" HeaderText="入力エラー!!" />
<div>
こちらは常時表示<br />
<uc1:ucInput ID="ucInput1" runat="server" />
</div>
<asp:RadioButton ID="rdoShow" runat="server" Checked="True"
GroupName="ShowHide" Text="表示" />
<asp:RadioButton ID="rdoHide" runat="server"
GroupName="ShowHide" Text="非表示" />
<asp:Panel ID="pnlShowHide" runat="server" Height="77px" BorderStyle="Inset">
表示切替パネル内<br />
<uc1:ucInput ID="ucInput2" runat="server" />
<uc1:ucInput ID="ucInput3" runat="server" />
<br />
<br />
<br />
</asp:Panel>
<br />
<asp:Button ID="Button1" runat="server" Text="ポストバックボタン" />
</form>
</body>
</html>
【Webページ(Default.aspx.vb)】
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strScript As String = String.Empty
strScript &= "setShowHidePanel("
strScript &= "'#" & Me.pnlShowHide.ClientID & "'"
strScript &= ",'#" & Me.rdoShow.ClientID & "'"
strScript &= ");"
'ラジオボタンの値によって、
'パネルの表示・非表示をクライアントで行う処理を組み込む
Me.rdoShow.InputAttributes.Add("onclick", strScript)
Me.rdoHide.InputAttributes.Add("onclick", strScript)
'さらにクライアントのページロード後に
'パネルの表示・非表示をクライアントで行う処理を実行する
Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), _
"setShowHidePanel", _
"<script type='text/javascript'>" & _
strScript & _
"</script>")
'表示・非表示パネル内に設置されている
'ユーザコントロール側の検証実施フラグを設定
Me.ucInput2.CheckValid = rdoShow.Checked
Me.ucInput3.CheckValid = rdoShow.Checked
End Sub
End Class
ユーザコントロールにHiddenFieldを仕込ませて
jQueryのパネルの表示・非表示時の処理でその値を設定、
サーバの検証処理でHiddenFieldを参照し、
検証を行うか判定する処理を考えていたのですが、
今回の要件では今回の方法のほうがスマートですね。
参考になれば幸いです。
よかったらクリックしてください。


にほんブログ村