RequiredFieldValidator や RegularExpressionValidator の検証結果が無効の場合、対象の TextBox の BackgroundColor を赤などの目立つ色にしてユーザーの注意をひくというサンプルです。
ヒントは Change Background Color of Invalid Controls (ASP.NET Validator) というページに紹介されていたコードですが、これは TextBox に対し、Validator が一つだけならうまくいきますが、二つあるとうまくいきません。
例えば RequiredFieldValidator と RegularExpressionValidator を組み合わせて使った場合、何も入力しない場合は後者の isvalid は true になって ctrl.style.backgroundColor ="" で上書きされてしまい、TextBox の背景は赤くなりません。
以下に、その問題に対処したサンプルをアップしておきます。
ただし、自分は JavaScript 使いでも jQuery 使いでもないので(と言って、C# 使いでもないですが(汗))、スクリプトの書き方が変かもしれません。でも、一応期待通りに動くことは検証しました。
以下のコードは、実際に動かして試せるよう 実験室 にアップしましたので、興味のある方は試してみてください。この記事の下の方の「2011/7/20 追記」に書いた ErrorMessage と同期を取るためのコードは追加済みです。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
String csname = "OnSubmitScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsOnSubmitStatementRegistered(cstype, csname))
{
String cstext = "ChangeBackgroundColor();";
cs.RegisterOnSubmitStatement(cstype, csname, cstext);
}
}
protected void CustomValidator1_ServerValidate(
object source, ServerValidateEventArgs args)
{
string membership = args.Value.ToLower();
if (membership == "gold" || membership == "silver")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function CustomValidator1_ClientValidate(sender, args) {
var membership = args.Value.toLowerCase();
if (membership === "gold" || membership === "silver") {
args.IsValid = true;
} else {
args.IsValid = false;
}
}
function ChangeBackgroundColor() {
var color = "#FFAAAA"
var valid =
$(Page_Validators).
filter(function () { return this.isvalid == true; });
var invalid =
$(Page_Validators).
filter(function () { return this.isvalid == false; });
valid.each(function () {
$("#" + $(this).get()[0].controltovalidate).
css("backgroundColor", "");
});
invalid.each(function () {
$("#" + $(this).get()[0].controltovalidate).
css("backgroundColor", color);
});
}
//]]>
</script>
</head>
<body>
<form id="form1" runat="server">
<table>
<tr>
<td>
User Name
</td>
<td>
<asp:TextBox ID="username" runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator1"
runat="server"
ErrorMessage="ユーザー名は必須入力です。"
ControlToValidate="username"
ForeColor="Red"
Display="Dynamic">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator
ID="RegularExpressionValidator1"
runat="server"
ErrorMessage=
"半角アルファベットで 40 文字以内にしてください。"
ControlToValidate="username"
ForeColor="Red"
ValidationExpression="^[a-zA-Z''-'\s]{1,40}$"
Display="Dynamic">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
Email
</td>
<td>
<asp:TextBox ID="email" runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator2"
runat="server"
ErrorMessage="メールアドレスは必須入力です。"
ControlToValidate="email"
ForeColor="Red"
Display="Dynamic">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator
ID="RegularExpressionValidator2"
runat="server"
ErrorMessage=
"メールアドレスの形式が正しくありません。"
ControlToValidate="email"
ForeColor="Red"
ValidationExpression=
"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
Display="Dynamic">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
Membership
</td>
<td>
<asp:TextBox ID="membership" runat="server">
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator
ID="RequiredFieldValidator3"
runat="server"
ErrorMessage="メンバーシップは必須入力です。"
ControlToValidate="membership"
ForeColor="Red"
Display="Dynamic">
</asp:RequiredFieldValidator>
<asp:CustomValidator
ID="CustomValidator1"
runat="server"
ErrorMessage=
"Gold または Silver でなければなりません。"
ControlToValidate="membership"
ForeColor="Red"
OnServerValidate=
"CustomValidator1_ServerValidate"
Display="Dynamic"
ClientValidationFunction=
"CustomValidator1_ClientValidate" >
</asp:CustomValidator>
</td>
</tr>
</table>
<asp:Button ID="Button1" runat="server" Text="送信" />
</form>
</body>
</html>
------------ 2011/7/20 追記 ------------
クライアント側での検証は、form が submit された時だけでなく、TextBox からフォーカスが外れた時も自動的にかかるようで、上記のコードでは ErrorMessage が消えても TextBox の背景は赤いままになってしまいます。
Validator の ErrorMessage と TextBox の背景の同期を取るには、TextBox の onblur 属性にも ChangeBackgroundColor() を設定します。Page_Load ハンドラで以下のようなコードを追加してやるとうまくいきます。
username.Attributes.Add("onblur",
"javascript:ChangeBackgroundColor()");
email.Attributes.Add("onblur",
"javascript:ChangeBackgroundColor()");
membership.Attributes.Add("onblur",
"javascript:ChangeBackgroundColor()");
------------ 2011/7/21 追記 ------------
IE の場合、フォーカスを外しても自動的に検証がかからないケースがあります。Firefox と Chrome でも試しましたが、こちらは期待通り検証がかかります。
具体的には以下のようなケースです。
最初に、空白または無効な文字列を TextBox に入力し、Tab キーでフォーカスを外すとクライアント側で検証がかかって ErrorMessage が表示され、onblur イベントが発生して ChangeBackgroundColor() メソッドが働き TextBox の背景色が赤になります。
次に、再度その TextBox に入力する際、オートコンプリートの一覧からマウスもしくはキー操作で文字列を選んで TextBox に表示し、その状態から Tab キーでフォーカスを外すと、今度は検証はかかりません。従い、有効な文字列なのにエラーとなったままになります。onblur イベントは発生して ChangeBackgroundColor() メソッドが働きますが、検証がかかってないので(即ち、検証結果が NG のままなので)TextBox の背景色は赤のままとなります。
ちなみに、オートコンプリートは一切使わず、有効な文字列を手打ちで TextBox に入力した場合は、フォーカスを外すと期待通り検証がかかります。従い、ErrorMessage は消えて TextBox の背景色も元に戻ります。
動作としては気に入らないですが、どうも IE のバグ仕様(?)らしいということで未対応です。
後で調べて分かったことですが、MSDN ライブラリの Walkthrough: Validating User Input in a Web Forms Page の Note に以下の文がありました。
"If you are using the auto-complete option in Internet Explorer, selecting a value from the auto-complete list will fill a value into the text box, but the client-side validator will not run."