トップ回答者
カレンダーコントロールから詳細ページを表示について

質問
-
カレンダーコントロールの日付をクリックしたらその日付の詳細な予定を別ページに表示させると言うことをしたいと思っています。
詳細な予定はデータベースに入っており、そのデータの日付とカレンダーの日付が関連づけられています。
本やネットのサイトを参考にして、カレンダーの日付のセルにデータベースの指定したフィールドを表示してそこをリンクしたら詳細が表示されるというところはできたのですが、カレンダーの日付の方をクリックして、同じ日に入っている複数の予定が別ページに表示されるにはどのようにすればいいのでしょうか?
別ページのほうはDetailsViewを使って表示できるようにはしてあるのですが、日付をクリックしてそのページを表示することができないのです。
わかりづらい質問で申し訳ありませんが、ご不明な点はお聞きください。
よろしくお願いいたします。
回答
-
はなはなはなさんも書かれていますが、クエリ文字(GET)で渡してあげれば良いと思います。
(参考)
第16回 ASP.NETにおけるページの遷移
http://www.atmarkit.co.jp/fdotnet/aspnet/aspnet16/aspnet16_04.html -
SqlDataSource1.SelectCommandType = SqlDataSourceCommandType.Text;
SqlDataSource1.SelectCommand = "select testid, test1 from test where testid = @id";
SqlDataSource1.SelectParameters.Clear();
SqlDataSource1.SelectParameters.Add("id", TypeCode.Int32, TextBox1.Text);のようにSQL文中にパラメータを含むものをパラメタライズドクエリと呼びます。上の例では@idです。
このようにパラメータを通すことにより、サニタイズと言って悪意を持つコードをパラメータに指定できなくなり、SQLインジェクションを防ぐことができるます。詳しくはSQLインジェクションを調べてみて下さい。
上記のコードはSQL Serverの例です。ODBCで接続している場合には、
SqlDataSource1.SelectCommand = "select testid, test1 from test where testid = ?";
というようにパラメータは?になります。この場合、パラメータを追加する順序によってどのパラメータかを判断しますので、パラメータを追加する順序が重要になります。つまり、SelectParameters.Addを実行する順序が重要です。SQL Serverの例の場合は名前付きパラメータであり、名前によってパラメータを識別できますので、パラメータを追加する順序は問題になりません。
-
ソルピー さんからの引用
ということですが、DetailsViewのSqlDataSourceに下記のような部分があるのですが、ここに設定すればいいと言うことでしょうか?
<aspqlDataSource ID="sds" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>"
OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT * FROM [Schedule] WHERE (([nonyubi] = @nonyubi))" >.aspxの方でSQL文を定義されていますが、@nonyubiに対するパラメータオブジェクトを定義されているかどうかわかりませんので、もし定義されていなければ、私が前回示したようにコードでパラメータオブジェクトを生成する必要があります。
sds.SelectParameters.Clear();
sds.SelectParameters.Add("nonyubi", タイプ, クエリ文字列で得られた日付);もし、以下のように.aspxでパラメータオブジェクトまで定義されているのであれば、
例
Code Snippet<asp:SqlDataSource ID="sds" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>"
OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT * FROM [Schedule] WHERE (([nonyubi] = @nonyubi))" >
<SelectParameters>
<asp:Parameter Name="nonyubi" Type="DateTime" />
</SelectParameters>
</asp:SqlDataSource>sds.SelectParameters["nonyubi"].DefaultValueにクエリ文字列で得られた日付をセットすればOKです。
ソルピー さんからの引用
ここの@nonyubiの部分がパラメタライズドクエリでよろしいんですよね?
よいです。
-
ソルピー さんからの引用
ということですが、このようなことでよろしいのでしょうか?<SelectParameters>
<asp:QueryStringParameter DefaultValue="nonyubi" Name="nonyubi" QueryStringField="nonyubi" type="DateTime" />
</SelectParameters>
クエリー文字列からパラメータに与える値をセットするように定義してありますので、これでOKです。今回のケースではDefaultValueは重要ではありません。無くても良いでしょう。DefaultValueを指定するとしても値は日付形式でなければなりません。DefaultValueはこのような形式で指定するため、型は全てString型になります。
例えば、DefaultValue="2008/06/04"などです。
ソルピー さんからの引用
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim qnonyubi As Date = Request.QueryString("nonyubi")End Sub
これは必要ありません。 <SelectParameters>の定義により、Request.QueryString("nonyubi")で値を読み取って、nonyubiパラメータにその値を渡すのと同じ動作を行います。
ソルピー さんからの引用 >sds.SelectParameters.Clear();
>sds.SelectParameters.Add("nonyubi", タイプ, クエリ文字列で得られた日付);というのは、どこに設置すればいいのでしょうか?
これも必要ありません。上で書いたように<SelectParameters>が定義されていますので。
-
ソルピー さんからの引用
こうなって↓e.NewValues("製品名") = ((DropDownList)((DetailsView)sender).FindControl("DropDownList1")).SelectedValue
製品名 にはテーブルの製品名が入っている項目名
OKです。ソルピー さんからの引用
DropDownList には選択する製品名が入っているDropDownListのID(?)
いえ、DropDownListへキャストしていますので、DropDownListのままです。
ソルピー さんからの引用
DetailsView にはDetailsViewのID
いえ、DetailsViewへキャストしているので、DetailsViewのままです。
ソルピー さんからの引用
DropDownList1 にも選択する製品名が入っているDropDownListのID(?)
OKです。
ちなみにVBだと、以下のような感じになるはずです。
e.NewValues("製品名") = CType(CType(sender, DetailsView).FindControl("DropDownList1"), DropDownList).SelectedValue
また、うまくいかなかったとは、どのようにうまくいかなかったのでしょうか?
-
ソルピー さんからの引用 教えて頂いたように、設定したら、エラーも出ず、プログラムも動くのですが、今度は、その製品を選ぶ項目でテンプレート化してDropDownListを設定して、製品を別のテーブルから選ぶようにし、プログラムを動かしてDetailsViewを編集モードにして修正して更新、とすると修正部分が反映されません。。。(表示を更新しても修正前の状態になります。)
e.NewValues("項目名")の項目名が違っていないか、また、RowUpdatingイベントがきちんと発動されているかを確認してみて下さい。
ソルピー さんからの引用 その製品部分のテンプレート化をEditItemテンプレートでDropDownListを設定したのですが、ここに設定するものではないのでしょうか?
いえ、EditItemテンプレートにDropDownListを設定します。
ソルピー さんからの引用 それとも、他の項目(ItemTemplateやInsertItemtemplateなど)にも何か設定しないといけないのでしょうか?
いえ、設定する必要はありません。
すべての返信
-
はなはなはなさん、trapemiyaさん、お返事ありがとうございました。
はなはなはなさん
ページ間の変数の受け渡し方法というわけではなく、データベースと連携したDetailsViewを表示してあるページを開くやりかたなんです。。。
それをカレンダーの日付と連携してそのデータがあるDetailsViewを表示したかったのですが、私の説明がわかりづらくてすみません。
trapemiyaさん
教えていただいたとおりにJavascriptを使って表示することができました。
ただ、その日付と関連するところがちょっとうまくいかず、また質問させて頂くかと思いますが、よろしくお願いいたします。
-
はなはなはなさんも書かれていますが、クエリ文字(GET)で渡してあげれば良いと思います。
(参考)
第16回 ASP.NETにおけるページの遷移
http://www.atmarkit.co.jp/fdotnet/aspnet/aspnet16/aspnet16_04.html -
SqlDataSource1.SelectCommandType = SqlDataSourceCommandType.Text;
SqlDataSource1.SelectCommand = "select testid, test1 from test where testid = @id";
SqlDataSource1.SelectParameters.Clear();
SqlDataSource1.SelectParameters.Add("id", TypeCode.Int32, TextBox1.Text);のようにSQL文中にパラメータを含むものをパラメタライズドクエリと呼びます。上の例では@idです。
このようにパラメータを通すことにより、サニタイズと言って悪意を持つコードをパラメータに指定できなくなり、SQLインジェクションを防ぐことができるます。詳しくはSQLインジェクションを調べてみて下さい。
上記のコードはSQL Serverの例です。ODBCで接続している場合には、
SqlDataSource1.SelectCommand = "select testid, test1 from test where testid = ?";
というようにパラメータは?になります。この場合、パラメータを追加する順序によってどのパラメータかを判断しますので、パラメータを追加する順序が重要になります。つまり、SelectParameters.Addを実行する順序が重要です。SQL Serverの例の場合は名前付きパラメータであり、名前によってパラメータを識別できますので、パラメータを追加する順序は問題になりません。
-
trapemiyaさん
ありがとうございました。
パラメタライズドクエリにつきましては理解できました。
お返事遅くなってすみません。
自分でやっていてどうもよくわからず、また教えてください。
>SqlDataSourceを使用されているのであれば、そのSelectCommandにSQL文を動的に与えてあげればOKです
ということですが、DetailsViewのSqlDataSourceに下記のような部分があるのですが、ここに設定すればいいと言うことでしょうか?
<asp
qlDataSource ID="sds" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>"
OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT * FROM [Schedule] WHERE (([nonyubi] = @nonyubi))" >ここの@nonyubiの部分がパラメタライズドクエリでよろしいんですよね?
で、それを動的に追加するのは、ただ変数をいれてもうまくいかなくて、どのように設定すればいいのでしょうか?
よろしくお願いいたします。
-
ソルピー さんからの引用
ということですが、DetailsViewのSqlDataSourceに下記のような部分があるのですが、ここに設定すればいいと言うことでしょうか?
<aspqlDataSource ID="sds" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>"
OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT * FROM [Schedule] WHERE (([nonyubi] = @nonyubi))" >.aspxの方でSQL文を定義されていますが、@nonyubiに対するパラメータオブジェクトを定義されているかどうかわかりませんので、もし定義されていなければ、私が前回示したようにコードでパラメータオブジェクトを生成する必要があります。
sds.SelectParameters.Clear();
sds.SelectParameters.Add("nonyubi", タイプ, クエリ文字列で得られた日付);もし、以下のように.aspxでパラメータオブジェクトまで定義されているのであれば、
例
Code Snippet<asp:SqlDataSource ID="sds" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>"
OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT * FROM [Schedule] WHERE (([nonyubi] = @nonyubi))" >
<SelectParameters>
<asp:Parameter Name="nonyubi" Type="DateTime" />
</SelectParameters>
</asp:SqlDataSource>sds.SelectParameters["nonyubi"].DefaultValueにクエリ文字列で得られた日付をセットすればOKです。
ソルピー さんからの引用
ここの@nonyubiの部分がパラメタライズドクエリでよろしいんですよね?
よいです。
-
trapemiyaさん
ありがとうございました。
>@nonyubiに対するパラメータオブジェクトを定義されているかどうか・・・
ということですが、このようなことでよろしいのでしょうか?
<SelectParameters>
<asp:QueryStringParameter DefaultValue="nonyubi" Name="nonyubi" QueryStringField="nonyubi" type="DateTime" />
</SelectParameters>Detailsviewを設置してあるページで、
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim qnonyubi As Date = Request.QueryString("nonyubi")End Sub
このようにしてqnonyubi としてカレンダーで選択した日付を取得できているのですが、教えて頂いた
>sds.SelectParameters.Clear();
>sds.SelectParameters.Add("nonyubi", タイプ, クエリ文字列で得られた日付);というのは、どこに設置すればいいのでしょうか?
Protected Sub Page_Loadの中なのでしょうか?それともパラメータオブジェクトの中に組み込むのでしょうか?
わからないことばかりで申し訳ありません。
よろしくお願いいたします。
-
ソルピー さんからの引用
ということですが、このようなことでよろしいのでしょうか?<SelectParameters>
<asp:QueryStringParameter DefaultValue="nonyubi" Name="nonyubi" QueryStringField="nonyubi" type="DateTime" />
</SelectParameters>
クエリー文字列からパラメータに与える値をセットするように定義してありますので、これでOKです。今回のケースではDefaultValueは重要ではありません。無くても良いでしょう。DefaultValueを指定するとしても値は日付形式でなければなりません。DefaultValueはこのような形式で指定するため、型は全てString型になります。
例えば、DefaultValue="2008/06/04"などです。
ソルピー さんからの引用
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim qnonyubi As Date = Request.QueryString("nonyubi")End Sub
これは必要ありません。 <SelectParameters>の定義により、Request.QueryString("nonyubi")で値を読み取って、nonyubiパラメータにその値を渡すのと同じ動作を行います。
ソルピー さんからの引用 >sds.SelectParameters.Clear();
>sds.SelectParameters.Add("nonyubi", タイプ, クエリ文字列で得られた日付);というのは、どこに設置すればいいのでしょうか?
これも必要ありません。上で書いたように<SelectParameters>が定義されていますので。
-
早速つまづいてしまいました。。
また教えてください。
DetailsViewに、あるテーブルのデータを表示しているのですが、そのいくつかの項目を他のテーブルからデータを選択して、その選択したデータを表示する。ということをしたいのです。
例えば、テーブルAには名前、場所、製品名や、作成日、更新日、などが入っていて、一つのテーブルになっています。
その中の製品名をテーブルBにあるデータから選択してテーブルAに表示したいのです。
DetailsViewにはテンプレートを使って、その製品名のところのEdititemtemplateのところでDropDownListを使って、テーブルBのデータを表示することができました。
DetailsViewを編集モードにするとDropDownListで製品名が選択できるようになっています。
ただ、ここで選択した値をテーブルAに反映させるにはどうやってやればいいのでしょうか?
どうぞよろしくお願い致します。
-
trapemiyaさん
ありがとうございます。
早速プログラムに追加してみたのですが、うまくいかず、教えてください。
VB.netですと、この場合、これが↓
e.NewValues["製品名"] = ((DropDownList)((DetailsView)sender).FindControl("DropDownList1")).SelectedValue;
こうなって↓
e.NewValues("製品名") = ((DropDownList)((DetailsView)sender).FindControl("DropDownList1")).SelectedValue
製品名 にはテーブルの製品名が入っている項目名
DropDownList には選択する製品名が入っているDropDownListのID(?)
DetailsView にはDetailsViewのID
DropDownList1 にも選択する製品名が入っているDropDownListのID(?)
を設定してみたのですが、これがうまくいかなかったので、違うと思うのですが、
DropDownList と、 DropDownList1 の部分には何が入るのでしょうか?
FindControl ってあるので、DropDownList1の部分には使っているDropDownListのIDでいいような気がするのですが、、、、
あっていますでしょうか??
どうぞよろしくお願い致します。
-
ソルピー さんからの引用
こうなって↓e.NewValues("製品名") = ((DropDownList)((DetailsView)sender).FindControl("DropDownList1")).SelectedValue
製品名 にはテーブルの製品名が入っている項目名
OKです。ソルピー さんからの引用
DropDownList には選択する製品名が入っているDropDownListのID(?)
いえ、DropDownListへキャストしていますので、DropDownListのままです。
ソルピー さんからの引用
DetailsView にはDetailsViewのID
いえ、DetailsViewへキャストしているので、DetailsViewのままです。
ソルピー さんからの引用
DropDownList1 にも選択する製品名が入っているDropDownListのID(?)
OKです。
ちなみにVBだと、以下のような感じになるはずです。
e.NewValues("製品名") = CType(CType(sender, DetailsView).FindControl("DropDownList1"), DropDownList).SelectedValue
また、うまくいかなかったとは、どのようにうまくいかなかったのでしょうか?
-
trapemiyaさん
ありがとうございました。
うまくいかなかったというのは、文法エラーが出てしまって(たぶん、当然なのだと思うのですが。。笑)、色々値を変えてやってみたのですが、うまくいかず、質問させて頂きました。
教えて頂いたように、設定したら、エラーも出ず、プログラムも動くのですが、今度は、その製品を選ぶ項目でテンプレート化してDropDownListを設定して、製品を別のテーブルから選ぶようにし、プログラムを動かしてDetailsViewを編集モードにして修正して更新、とすると修正部分が反映されません。。。(表示を更新しても修正前の状態になります。)
その製品を選択する部分のテンプレートを外して、プログラムを動かしてDetailsViewを編集モードにして修正して更新すると、ちゃんと修正されます。
その製品部分のテンプレート化をEditItemテンプレートでDropDownListを設定したのですが、ここに設定するものではないのでしょうか?
それとも、他の項目(ItemTemplateやInsertItemtemplateなど)にも何か設定しないといけないのでしょうか?
申し訳ありませんが、また教えてください。
よろしくお願い致します。
-
ソルピー さんからの引用 教えて頂いたように、設定したら、エラーも出ず、プログラムも動くのですが、今度は、その製品を選ぶ項目でテンプレート化してDropDownListを設定して、製品を別のテーブルから選ぶようにし、プログラムを動かしてDetailsViewを編集モードにして修正して更新、とすると修正部分が反映されません。。。(表示を更新しても修正前の状態になります。)
e.NewValues("項目名")の項目名が違っていないか、また、RowUpdatingイベントがきちんと発動されているかを確認してみて下さい。
ソルピー さんからの引用 その製品部分のテンプレート化をEditItemテンプレートでDropDownListを設定したのですが、ここに設定するものではないのでしょうか?
いえ、EditItemテンプレートにDropDownListを設定します。
ソルピー さんからの引用 それとも、他の項目(ItemTemplateやInsertItemtemplateなど)にも何か設定しないといけないのでしょうか?
いえ、設定する必要はありません。
-
trapemiyaさん
ありがとうございました。
>e.NewValues("項目名")の項目名が違っていないか、また、RowUpdatingイベントがきちんと発動されているかを確認してみて下さい。
大丈夫です。
CType(CType(sender, DetailsView).FindControl("DropDownList1"), DropDownList).SelectedValue
この部分で値を調べたら、選択した製品名が代入されていました。
>いえ、EditItemテンプレートにDropDownListを設定します。
すみません、何か変な書き方をしていました。(笑)
DetailsViewの製品名の項目をTemplatefieldにし、Templateの編集で、製品名のEdititemTemplateに製品名が入っているテーブルのSqldatasourceを設定し、それに関連づけたDropDownlistを設定しました。
解決できないので、新しくスレッドをたてます。
ありがとうございました。
-
こんにちは、フォーラムオペレータ大久保です。
ソルビーさん、ひとまず当初の問題は解決したとのことですので、アドバイスをくださった皆様の投稿に「回答済み」チェックをつけさせていただきました。
厳密なルールというわけではありませんが、フォーラムは、基本的に1スレッド1テーマという流れでご利用いただいています。
ひとつのスレッドにたくさんの情報が詰まっているのは、それはそれで有益ですが、スレッドが大きくなりすぎると検索性が落ちるという問題もでてきます。
ですので、別のテーマの質問をしたい場合は、今回のように別のスレッドをたてていただけるとありがたいです。
アドバイスをくださった皆様、ありがとうございました!
今後とも MSDN フォーラムをよろしくお願いします。