- PR -

【ASP.NET2.0(C#)】サーバ側で動的に生成したボタンごとのURLを別Windowに渡して開かせる方法

1
投稿者投稿内容
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2008-02-07 10:48
いつもお世話になっております、

案2で、下記『やりたいこと』を実装したいのですが、
何かいい方法はありますでしょうか?
ご存知の方いらっしゃいましたらよろしくお願いします。

●やりたいこと
 メインのページ上にある動的に作成したボタンをクリックすると、
 その押されたボタンに対応するURL(ボタンに対応した値をQueryString
 に格納したURL)を動的に作成して、別Windowで画面を開くこと。

 ※要するに、ボタンごとにURL(厳密にはQueryString部分)は違うんだけど、
  ButtonClickのイベントハンドラは一つにして、かつ結果として表示するWindowは
  別Windowにする方法を教えていただきたいわけです。
  (できればスマートな方法、定石的な方法を勉強したいのです。)

●調査したこと
 案1:PageLoad時にボタンに対応する値を取得できるので、
    クライアント側にページを戻す段階で各ボタンにQueryString込みのURLを
    生成し、ボタンクリックにJavascriptでWindow.Openを設定する。

     Button.Attributes["onclick"] =
        "window.open('NewWindow.aspx?GYO=行番号', '', '' )";

    欠点は、HTML上にボタンクリックのスクリプトがボタンの数分現われ
    スマートとはいえない。(実装できることは確認済みです。)

 案2:下記のように考えたのですがダメでした。
    ダメな理由は、PostBackするのでButtonClick以外でも、PageLoadが常に呼ば
    れてしまうため、無関係なページ更新操作(例えば、IEの更新ボタン)でも
    子Windowを開いてしまうため

     @ユーザ操作でボタンクリック
     AButtonClickメソッド内でsenderを使用して、ボタン情報を取得してURL
      を合成する。
     BClientScriptManager.RegisterClientScriptBlockでURLをスクリプト
      登録する
     Cクライアントで元のページをロード中に、別Windowが開く。
     
     ※PageLoadのトリガが、ボタンクリックであるかなどの情報を取れれば
      スクリプトを入れる入れないということを分岐できると思うのですが、
      実装法が不明です。これは技術的に可能でしょうか?
      Request.Form["コントロールID"]とかで取れないものでしょうか?

 案3:JavaScriptで、押されたボタンに対応する情報を取得してURLを決定し、
    Window.Openする
    (これはクライアント側での処理になります。JavaScript勉強中のため、
     可能なのか不明です。)
    不明点1:JavaScript内で押されたボタンを取得できるのか?
    不明点2:JavaScript内で押されたボタンに対応する隠しFLDの値を取得
         できるのか?

以上、お忙しいとは思いますが、よろしくお願いいたします。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-02-07 11:49
引用:

Makotoさんの書き込み (2008-02-07 10:48) より:

 案3:JavaScriptで、押されたボタンに対応する情報を取得してURLを決定し、
    Window.Openする
    (これはクライアント側での処理になります。JavaScript勉強中のため、
     可能なのか不明です。)
    不明点1:JavaScript内で押されたボタンを取得できるのか?
    不明点2:JavaScript内で押されたボタンに対応する隠しFLDの値を取得
         できるのか?



functionへbutton自身を渡すことでいけると思います。
こんな感じでしょうか。

コード:
<head runat="server">
    <title>無題のページ</title>

    <script type="text/javascript">
    function openwindow(button)
    {
        window.open(button.url)
    }
    </script>

</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input id="Button1" url="a" onclick="openwindow(this)" type="button" value="button" />
            <input id="Button2" url="b" onclick="openwindow(this)" type="button" value="button" />
            <input id="Button3" url="c" onclick="openwindow(this)" type="button" value="button" />
        </div>
    </form>
</body>
</html>

RapidExpress
常連さん
会議室デビュー日: 2007/11/11
投稿数: 42
お住まい・勤務地: おおさか
投稿日時: 2008-02-07 13:19
引用:

     @ユーザ操作でボタンクリック
     AButtonClickメソッド内でsenderを使用して、ボタン情報を取得してURL
      を合成する。
     BClientScriptManager.RegisterClientScriptBlockでURLをスクリプト
      登録する
     Cクライアントで元のページをロード中に、別Windowが開く。


ClientScriptManager.RegisterClientScriptBlockをButtonClickでやってしまえば
いけると思うんですが、何か不都合な部分はありますか?
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2008-02-07 14:44
ASP.netの動作について間違っていたらご指摘をお願いします。

早速の回答を頂いたのに、コンパイルを通すのと動作確認に時間
がかかってしまい、返信遅れてすみません。

To:rainさん

JavaScriptの使い方なんとなく分ってきました。
おそらく『案3』での私のやりたいことは、
『動的に作成したボタンに対応するURLをJavaScriptで合成すること』
ということで、ご提示いただいた感じでやれそうな感じがしてきました。

ソースも提供していただき、ありがとうございました。

To:RapidExpressさん

お名前どおりの急速な回答ありがとうございます。

ClientScriptManager.RegisterClientScriptBlock メソッドは、
サーバサイドで要求された情報を元にして『動的なJavaScript句』を生成して
クライアント側に返すHTMLに登録しておくものとの認識ですがよろしいでしょうか?
また、Bobyタグに入れると、クライアント側でBodyタグ解析途中のその部分で
JavaScriptが呼ばれる。

(これらを踏まえると、
 @PageLoad時にClientScriptManager.RegisterClientScriptBlock メソッド
  を使用してJavaScriptを用意しておく。
 (しかもボタンクリック以外でもPageLoadするとよばれてしまう)
  Page表示状態では、既にURLは決定している必要がある。
  決定していないと、クライアントサイドでWindow.OpenでURLを渡せないので困る。
 AButtonクリックで発生するPostBackでPageLoad、ButtonClickの順で呼ばれる。
  (どのボタンがクリックされたかは、ButtonClickメソッドでは取れるが、
   PageLoadではとれない。)

 ※@で既にJavaScriptが決まってしまっているので、
  Aのボタンクリック時に対応するボタンを見分けても意味がないと考えています。
  しかもサーバ側でです。

ButtonClickメソッドで、ClientScriptManager.RegisterClientScriptBlock
メソッドをいれても、ButtonClickメソッドで対応するJavaScriptは
呼ばれないのでは?と考えています。

何か仕様認識ややり方がおかしいでしょうか?

以上、よろしくお願い致します。
RapidExpress
常連さん
会議室デビュー日: 2007/11/11
投稿数: 42
お住まい・勤務地: おおさか
投稿日時: 2008-02-07 15:07
引用:

ClientScriptManager.RegisterClientScriptBlock メソッドは、
サーバサイドで要求された情報を元にして『動的なJavaScript句』を生成して
クライアント側に返すHTMLに登録しておくものとの認識ですがよろしいでしょうか?
また、Bobyタグに入れると、クライアント側でBodyタグ解析途中のその部分で
JavaScriptが呼ばれる。


スクリプトをPage_Loadのときに確定させる必要はありません。動的とはいえ、
クライアントに処理が帰る(HTML解析)のはサーバ側での各イベントの処理が
終わった後になりますので、Clickイベントのメソッド内で登録することは可能です。

以下に例を示します。(コードがVBで恐縮なんですが。。。)

コード:
  '生成されたボタンのClickイベントに関連付けられているメソッド
    Protected Sub buttonClick(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim btn As Web.UI.WebControls.Button
        btn = CType(sender, Web.UI.WebControls.Button)
        Select Case btn.ID
            Case "Button1"
                ClientScript.RegisterClientScriptBlock(Me.GetType, "WINOPEN", "window.open('Default2.aspx');", True)
            Case "Button2"
                ClientScript.RegisterClientScriptBlock(Me.GetType, "WINOPEN", "window.open('Default3.aspx');", True)
            Case "Button3"
                ClientScript.RegisterClientScriptBlock(Me.GetType, "WINOPEN", "window.open('Default4.aspx');", True)
            Case Else

        End Select
    End Sub



#ちなみに私はRegisterClientScriptBlockよりRegisterStartupScriptをよく使います。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-02-07 15:20
RegisterClientScriptBlockとRegisterStartupScriptの違いについては、こちらが参考になると思います。
ページにJavaScriptを埋め込むには?


今回の用途に使えるかどうかわかりませんが、Button.OnClientClickプロパティというのもあります。
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2008-02-07 17:17

参考サイト確認させて頂きました。

それを踏まえてなのですが、

●確認@RapidExpressさんのbuttonClickでClientScript.RegisterClientScriptBlock
を追加する方法は、初回のPageLoadではbuttonClickは押すことができていない
ので、初回にPageを表示した場合のButtonClickではwindow.openされないので
はないでしょうか?と思っていました。

    がそうではなく、
1回目のボタンクリック時には、クライアントにはscriptが組み込まれていな
いが、サーバサイドには要求が来る。そこで登録して、『新しいHTML』に
RegisterClientScriptBlockでscriptを組み込む。
    ページはPostbackされているので『新しいHTML』が戻った場合に、
スクリプトが実行される。

    ※buttonClick以外でPageLoadしていなければRegisterClientScriptBlockで
script登録しないのでscriptは存在しないので動作的な問題はない。

    ※他の動的Buttonに対してのscriptもscript登録していないので問題はない。
    
    ※クリックされていない他のButtonのonclickにスクリプトを登録しているわけ
でもないので関係ない

    『そもそもButtonClickで動作させるScriptではないよ』、
Bodyに書いているscriptだよ!ということですね。

    どうもonClickにscript登録しなければできないものだと思い込んでいたよう
です。
    非常に勉強になりました。

下記のようなことが、シーケンシャルに実行できるということですよね?

 @Pageを表示
 AButtonクリック操作で、自ページにPostback。
  このときscriptを動的にbodyに入れる。
 B自ページがブラウザに戻る
  ここでsciptが実行されて子Windowが開き、こちらはこちらでPostbackする。
 C自ページの表示が完了する+子Windowの表示が完了する。

まさにやりたかったことはこれです。

Javascript、HTMLタグ、ASP.netのライブラリといろいろ勉強になりました。
お二人とも、ありがとうございました。

あとはCSSです、また何かありました際には質問させていただきますので
よろしくお願いいたします。
1

スキルアップ/キャリアアップ(JOB@IT)