none
DataGridのテンプレート使用時における入力チェックについて RRS feed

  • 質問

  • 使用環境はVisualStadio2002です。

    DataGridのテンプレート使用時に入力チェックを行いたいのですが

    ValidationコントロールのCustomValidatorを使いたいと思っています。

    テンプレート以外の場所では使用できたのですが、テンプレートに組み込むと、サーバ内でのチェックができませんでした。イベントが発生しない状態です。

    Javascriptなら動きそうですが、サーバチェックはできないのでしょうか?

    また、Javascriptで動かす場合、関数を定義するところまでは実装しているのですが、引数からのValue値の取得方法がわかりません。

    宜しくお願い致します。

    2008年5月17日 12:50

すべての返信

  •  Becky2008 さんからの引用

    テンプレート以外の場所では使用できたのですが、テンプレートに組み込むと、サーバ内でのチェックができませんでした。イベントが発生しない状態です。

     

    テンプレート内のCustomValidatorにイベントハンドラを割り当てなければなりません。素直に行うのであればItemCreatedイベントでしょう。その時、ListItemType.EditItemの場合にのみ割り当てるようにして下さい。

    もしくはUpdateCommandイベントの冒頭で割り当て、Validateメソッドを実行しても可能だと思います。

    2008年5月17日 17:19
    モデレータ
  •  trapemiya さんからの引用

    テンプレート内のCustomValidatorにイベントハンドラを割り当てなければなりません。素直に行うのであればItemCreatedイベントでしょう。その時、ListItemType.EditItemの場合にのみ割り当てるようにして下さい。

     

    ItemCreated イベントのハンドラ内に、プログラマが

     

    CustomValidator1.ServerValidate += ServerValidateEventHandler(cv_ServerValidate);

     

    というようなコードを書くということでしょうか?

     

    それをしなくても、以下のように普通(?)にやって特に問題はないと思いますが、いかがで

    しょうか?

     

    (注) CustomValidator の条件は簡単に "abc" としています。また、全部の TextBox が

    空白のときは ServerValidate イベントは発生しないので(ひょっとして、質問者の方がイベ

    ントが発生しないといっているのはそれが原因かも) RequiredFieldValidator を入れています。

     

    Code Snippet

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">
        ICollection CreateDataSource()
        {
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
            dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double)));
            for (int i = 0; i < 3; i++)
            {
                dr = dt.NewRow();
                dr[0] = i;
                dr[1] = "Item " + i.ToString();
                dr[2] = 1.23 * (i + 1);
                dt.Rows.Add(dr);
            }
            DataView dv = new DataView(dt);
            return dv;
        }

        void Page_Load(Object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ItemsGrid.DataSource = CreateDataSource();
                ItemsGrid.DataBind();
            }
            CustomValidator cv = new CustomValidator();
        }

        protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (args.Value != "abc")
            {
                args.IsValid = false;
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if (Page.IsValid == false)
            {
                Label1.Text = String.Empty;
                return;
            }
            Label1.Text = "Validated!";
        }
       
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>DataGrid 上での CustomValidator</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:DataGrid id="ItemsGrid"
                runat="server"
                AutoGenerateColumns="False">
                <Columns>
                    <asp:BoundColumn
                        HeaderText="Number"
                        DataField="IntegerValue"/>
                    <asp:BoundColumn
                        HeaderText="Item"
                        DataField="StringValue"/>
                    <asp:BoundColumn
                        HeaderText="Price"
                        DataField="CurrencyValue" />
                    <asp:TemplateColumn HeaderText="Input">
                        <ItemTemplate>
                            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
                                ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1"
                                Display="Dynamic">*</asp:RequiredFieldValidator>
                            <asp:CustomValidator ID="CustomValidator1" runat="server"
                                ErrorMessage="CustomValidator" ControlToValidate="TextBox1"
                                Display="Dynamic" onservervalidate="CustomValidator1_ServerValidate">*
                            </asp:CustomValidator>
                        </ItemTemplate>
                    </asp:TemplateColumn>
                </Columns>
            </asp:DataGrid>
            <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <asp:Label ID="Label1" runat="server"></asp:Label>
            <asp:ValidationSummary ID="ValidationSummary1" runat="server"
                HeaderText="ヘッダーテキスト" />
        </div>
        </form>
    </body>
    </html>

     

     

     

    2008年5月18日 4:01
  • すみません、余計なコードが混じっていました。

     

    CustomValidator cv = new CustomValidator();

     

    は消し忘れです。

    2008年5月18日 4:09
  •  Becky2008 さんからの引用

    また、Javascriptで動かす場合、関数を定義するところまでは実装しているのですが、引数からのValue値の取得方法がわかりません。

     

    ClientID から Value が取得できると思います。例えば、先のコードに TextBox の Value を

    取得するコードを追加すると、下記のようになります。

     

    #なぜ CustomControl を使用しなければならないのか分かりませんが、RequiredFieldValidator,

    RegularExpressionValidator, CompareValidator, RangeValidator が使用できるのであれば、

    それらはクライアント側のスクリプトも自動生成してくれますので、そのほうが面倒がないと思いま

    すが。

     

    Code Snippet

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">
        ICollection CreateDataSource()
        {
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
            dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double)));
            for (int i = 0; i < 3; i++)
            {
                dr = dt.NewRow();
                dr[0] = i;
                dr[1] = "Item " + i.ToString();
                dr[2] = 1.23 * (i + 1);
                dt.Rows.Add(dr);
            }
            DataView dv = new DataView(dt);
            return dv;
        }

        void Page_Load(Object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ItemsGrid.DataSource = CreateDataSource();
                ItemsGrid.DataBind();
            }
        }

        protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (args.Value != "abc")
            {
                args.IsValid = false;
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if (Page.IsValid == false)
            {
                Label1.Text = String.Empty;
                return;
            }
            Label1.Text = "Validated!";
        }

        protected void ItemsGrid_ItemDataBound(object sender, DataGridItemEventArgs e)
        {
            ListItemType itemType = (ListItemType)e.Item.ItemType;

            if ((itemType != ListItemType.Header) &&
               (itemType != ListItemType.Footer) &&
                (itemType != ListItemType.Separator))
            {
                Button btn = (Button)e.Item.Cells[3].FindControl("Button2");
                TextBox tb = (TextBox)e.Item.Cells[3].FindControl("TextBox1");
                string script = String.Format("BLOCKED SCRIPTButton2Click('{0}');", tb.ClientID);
                btn.Attributes.Add("onclick", script);
            }
        }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>DataGrid 上での CustomValidator</title>
        <script type="text/javascript">
        <!--
            function Button2Click(textBoxID)
            {
                alert(document.getElementById(textBoxID).value);
            }
        //-->
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:DataGrid id="ItemsGrid"
                runat="server"
                AutoGenerateColumns="False" onitemdatabound="ItemsGrid_ItemDataBound">
                <Columns>
                    <asp:BoundColumn
                        HeaderText="Number"
                        DataField="IntegerValue"/>
                    <asp:BoundColumn
                        HeaderText="Item"
                        DataField="StringValue"/>
                    <asp:BoundColumn
                        HeaderText="Price"
                        DataField="CurrencyValue" />
                    <asp:TemplateColumn HeaderText="Input">
                        <ItemTemplate>
                            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
                                ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1"
                                Display="Dynamic">*</asp:RequiredFieldValidator>
                            <asp:CustomValidator ID="CustomValidator1" runat="server"
                                ErrorMessage="CustomValidator" ControlToValidate="TextBox1"
                                Display="Dynamic" onservervalidate="CustomValidator1_ServerValidate">*
                            </asp:CustomValidator>
                            <asp:Button ID="Button2" runat="server" Text="Button" />
                        </ItemTemplate>
                    </asp:TemplateColumn>
                </Columns>
            </asp:DataGrid>
            <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <asp:Label ID="Label1" runat="server"></asp:Label>
            <asp:ValidationSummary ID="ValidationSummary1" runat="server"
                HeaderText="ヘッダーテキスト" />
        </div>
        </form>
    </body>
    </html>

     

     

     

    2008年5月18日 9:23
  • 上記のコードで BLOCKED SCRIPT はジャワスクリプト: の英小文字です。

     

    セキュリティ対策で勝手に変換されてしまうようです。何とかしてもらいたいと思うのでが・・・

    2008年5月18日 9:53
  •  

    テキストBOXに日付データを入力して、それをチェックする機能をつけようと思っています。

    正規表現、必須等であれば、RegularExpressionValidator, CompareValidator, RangeValidator

    でチェックできると思うのですが、日付かどうかをチェックするには実データを調べる処理を入れるしかないという感じです。

    Server内部チェックならServerValidateで引数拾ってチェックができます。

    ただし、テンプレートだとできませんでした。

    テンプレート時のイベントが走らない理由はわかりませんが、VisualStadio2008でためしたところイベントが走りました。

     

    Javascirptに関しては、CustomValidatorのプロパティにて、ClientValidationFunctionに、関数を定義してます。

     

    MSDNに書いてある物を参考にしました。

    http://msdn.microsoft.com/ja-jp/library/system.web.ui.webcontrols.customvalidator.clientvalidationfunction(VS.80).aspx

     

    <script type="text/javascript">
       function ClientValidate(source, clientside_arguments)
       {        
          if (clientside_arguments.Value % 2 == 0 )
          {
             clientside_arguments.IsValid=true;
          }
          else {clientside_arguments.IsValid=false};
       }
    </script>

    上記でうまく動きました。

    回答いただいた、やりかたも試してみます。

    ありがとうございました。

     

     

    2008年5月18日 14:38
  •  SurferOnWww さんからの引用

    ItemCreated イベントのハンドラ内に、プログラマが

     

    CustomValidator1.ServerValidate += ServerValidateEventHandler(cv_ServerValidate);

     

    というようなコードを書くということでしょうか?

     

    その通りです。

     

     SurferOnWww さんからの引用

    それをしなくても、以下のように普通(?)にやって特に問題はないと思いますが、いかがで

    しょうか?

     

    インラインコードであればそれでも問題ないと思います。

    確かにコードビハインドとは書いてありませんでしたね。うかつでした。

    ご指摘ありがとうございました。

    2008年5月18日 16:58
    モデレータ
  •  Becky2008 さんからの引用

    Javascirptに関しては、CustomValidatorのプロパティにて、ClientValidationFunctionに、関数を定義してます。

     

    そのような便利な機能があるとは知りませんでした。おかげさまで、また一つ利口になり

    ました。解決策を連絡いただき有難うございました。

     

    実は、value を取得して、そこから判定のためのコード、判定結果の表示(赤い "*" 印や

    ValidationSummary でのエラーメッセージの表示など)のコード、判定結果 NG のとき

    ポストバックをかけないためのコードを JavaScript で書くにはどうすればよいのか悩んで

    いました。(汗)

     

    2008年5月19日 1:28
  •  trapemiya さんからの引用

    インラインコードであればそれでも問題ないと思います。

    確かにコードビハインドとは書いてありませんでしたね。

     

    自分の環境は Windows XP, VWD 2008 Express Edition, ローカル試験環境(IIS ローカルではな

    い)ですが、コードビハインドでも問題なかったです。質問者の方は、VWD 2008 にして問題がなくな

    ったそうですので、環境の違いが影響しているのかもしれませんね。

     

    ちょっとくどいようですが、自分が試験したコードを載せておきますので、よろしければ試してみてくだ

    さい。まとめて Code Snippet の中に書いていますが、実際はコードビハインドとしています。

     

    クライアント側で検証 OK となると(TextBox 全部に abc と入力してボタンクリック)、ポストバッ

    クがかかって、サーバー側でも検証される(CustomValidator1_ServerValidate ハンドラに制御が飛

    ぶ)はずです。

     

    Code Snippet

    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;

    public partial class MsdnForumTest9 : System.Web.UI.Page
    {
        ICollection CreateDataSource()
        {
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
            dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double)));
            for (int i = 0; i < 3; i++)
            {
                dr = dt.NewRow();
                dr[0] = i;
                dr[1] = "Item " + i.ToString();
                dr[2] = 1.23 * (i + 1);
                dt.Rows.Add(dr);
            }
            DataView dv = new DataView(dt);
            return dv;
        }

        void Page_Load(Object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ItemsGrid.DataSource = CreateDataSource();
                ItemsGrid.DataBind();
            }
        }

        protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (args.Value != "abc")
            {
                args.IsValid = false;
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if (Page.IsValid == false)
            {
                Label1.Text = String.Empty;
                return;
            }
            Label1.Text = "Validated!";
        }
    }

     

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="MsdnForumTest9.aspx.cs" Inherits="MsdnForumTest9" %>

    <!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>DataGrid 上での CustomValidator(コードビハインド)</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:DataGrid id="ItemsGrid"
                runat="server"
                AutoGenerateColumns="False">
                <Columns>
                    <asp:BoundColumn
                        HeaderText="Number"
                        DataField="IntegerValue"/>
                    <asp:BoundColumn
                        HeaderText="Item"
                        DataField="StringValue"/>
                    <asp:BoundColumn
                        HeaderText="Price"
                        DataField="CurrencyValue" />
                    <asp:TemplateColumn HeaderText="Input">
                        <ItemTemplate>
                            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
                                ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1"
                                Display="Dynamic">*</asp:RequiredFieldValidator>
                            <asp:CustomValidator ID="CustomValidator1" runat="server"
                                ErrorMessage="CustomValidator" ControlToValidate="TextBox1"
                                Display="Dynamic" onservervalidate="CustomValidator1_ServerValidate"
                                ClientValidationFunction="ClientValidate">*
                            </asp:CustomValidator>
                        </ItemTemplate>
                    </asp:TemplateColumn>
                </Columns>
            </asp:DataGrid>
            <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
            <asp:Label ID="Label1" runat="server"></asp:Label>
            <asp:ValidationSummary ID="ValidationSummary1" runat="server"
                HeaderText="ヘッダーテキスト" />   
        </div>
        </form>
    </body>
    </html>
    <script type="text/javascript">
        <!--
        function ClientValidate(source, clientside_arguments)
        {
            if (clientside_arguments.Value == "abc")
            {
                clientside_arguments.IsValid = true;
            }
            else
            {
                clientside_arguments.IsValid = false;
            }
        }
        //-->
    </script>

     

     

    2008年5月19日 1:43
  •  SurferOnWww さんからの引用

    ちょっとくどいようですが、自分が試験したコードを載せておきますので、よろしければ試してみてくだ

    さい。まとめて Code Snippet の中に書いていますが、実際はコードビハインドとしています。

     

    あれ~、すみません。実は家のPCでテストしたところ、OnServerValidateに書いたメソッドが定義されていませんというコンパイルエラーになったんです。それで、コードでイベントハンドラを付加するようにしたんですが、今、会社のPCで試したらOnServerValidateに書いたメソッドが解決され、コンパイルエラーになることなく正しく動きました。

    環境はVS2003です。Partial ClassではないのでVS2003ではコンパイルエラーになるのかと早合点してしまったようです。でも、どうして家のPCではコンパイルエラーになったんだろう? 家で書いたソースをそのまま会社のPCで動かしたので環境の違いでしかありません。なんか、過去にそんなことがあったような気がするんですが思い出せません・・・。たぶん、家の環境がおかしんだと思います。

     

    いずれにしても私が間違っておりました。SurferOnWwwさん、ありがとうございました。

    2008年5月19日 3:38
    モデレータ
  • チェックしていただいて有難うございました。> trapemiya さん

     

    環境によってなダメなケースもあることをおぼえておきます。

    2008年5月19日 4:07