WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

ModalPopup のドラッグ可能範囲

by WebSurfer 5. April 2014 15:47

Ajax Control Toolkit の ModalPopupExtender をドラッグできない(正確には、ドラッグはできるが元の位置に戻ってしまう)ケースがあります。その理由と対処法を書きます。

ModalPopup のドラッグ可能範囲

検証用に、上の画像のような Button コントロールを一つだけ配置したような aspx ページを作ったとします。

Button クリックで ModalPopup が現れ、デフォルトではウィンドウの中央に表示されるはずです。

これをマウスでクリックして任意の位置にドラッグすることができますが、離すと元の位置に戻ってしまいます。

その理由は、ModalPopup のドラッグが有効なのは body の中だけなので、ボタン一つだけというように body のサイズが極端に小さくなる場合、ドラッグしても元の位置に戻ってしまうということになります。

通常はボタン一つだけというようなページを作ることはないので、このような問題に遭遇することはないかもしれませんが、もし body のサイズが極端に小さくなる場合があれば、CSS で body のサイズを指定してやることで問題を回避できます。

上の画像のサンプルは、実際に動かして試すことができるよう 実験室 にアップしましたが、これは body に height: 300px; width: 600px; というスタイルを適用しています。

height: 300px; width: 600px; の範囲(赤い線で囲った部分)内だけでドラッグして移動できる(範囲外にドラッグした場合は元の位置に戻ってしまう)ことが分かりますので、興味のある方は試してみてください。

サンプルのコードは以下の通りです。

<%@ Page Language="C#" %>
<%@ Register Assembly="AjaxControlToolkit" 
  Namespace="AjaxControlToolkit" TagPrefix="asp" %>

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

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>WebSurfer's Page - 実験室</title>
  <style type="text/css">       
    .modalBackground {
      background-color: Gray;
      filter: alpha(opacity=70);
      opacity: 0.7;
    }

    .modalPopup {
      height: 150px;
      width: 400px;
      background-color: White;
    }

    .modalDraggableArea {
      cursor: move; 
      background-color: #DDDDDD; 
      border: solid 1px Gray;
    }

    body {
      height: 300px;
      width: 600px;
      border: 1px solid red;
    }
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <asp:ToolkitScriptManager ID="Manager1" runat="server">
  </asp:ToolkitScriptManager>
  <asp:ModalPopupExtender ID="ModalPopupExtender1" 
    runat="server"
    TargetControlID="Button1" 
    PopupControlID="Panel1" 
    PopupDragHandleControlID="Panel2"
    BackgroundCssClass="modalBackground"
    OkControlID="Button2"
    CancelControlID="Button3">
  </asp:ModalPopupExtender>

  <asp:Button ID="Button1" 
    runat="server" Text="ModalPopup 表示" />
    
  <asp:Panel ID="Panel1" 
    runat="server" 
    CssClass="modalPopup">
    <asp:Panel ID="Panel2" 
      runat="server" 
      CssClass="modalDraggableArea">
      <p style="text-align: center;">
        ********* ここをつかんでドラッグ *********
      </p>                      
    </asp:Panel>
    <p style="text-align: center;">ModalPopup</p>
    <p style="text-align: center;">
      <asp:Button ID="Button2" runat="server" Text="OK" />
      <asp:Button ID="Button3" runat="server" Text="Cancel" />
    </p>
  </asp:Panel>

  </form>
</body>
</html>

Tags: ,

AJAX

CalendarExtender の日付の表示

by WebSurfer 26. July 2013 11:48

Ajax Control Toolkit の CalendarExtender で日本語形式の日付を表示するにはどうすればよいかという話です。

まず、ToolkitScriptManager と CalendarExtender の設定がデフォルト状態(Visual Studio でドラッグ&ドロップしただけの状態)の場合は下の画像のような表示になります。

デフォルトでのカレンダーの表示

カルチャは ja-JP と認識されていますが、(1) TextBox に入力される日付の形式が M/d/yyyy(米国式)、(2) カレンダーの曜日が英語、(3) カレンダーのタイトルと今日の日付の表示が米国式になってしまいます。

特に問題になるのが「(1) TextBox に入力される日付の形式が M/d/yyyy」です。M/d/yyyy 形式では、CompareValidator による検証や、サーバー側での DateTime 型への変換の際などにパースがうまくいかず、期待した結果にならないということがあります。

カルチャが ja-JP の時に TextBox に入力される日付が yyyy/MM/dd 形式となるようにするには、ToolkitScriptManager の EnableScriptGlobalization プロパティを true に設定してやります。その結果が下の画像です。

EnableScriptGlobalization を true に設定

MSDN ライブラリによると、"EnableScriptGlobalization プロパティを true に設定すると、グローバル化された JavaScript 関数がカルチャ固有の情報を表示します" とのことです。

カルチャは、ブラウザ、サーバーコード、または Web サイトの構成ファイルで設定できます。例えば、@ Page ディレクティブで Culture, UICulture を "auto" に設定した場合、ASP.NET がリクエスト情報に含まれる Accept-Language ヘッダの内容から判断して、自動的にカルチャを特定してくれます。

なので、EnableScriptGlobalization プロパティが true に設定してあると、「(1) TextBox に入力される日付の形式」は、カルチャが ja-JP の場合は yyyy/MM/dd 形式、en-US の場合は M/d/yyyy となります。

「(2) カレンダーの曜日」も、カルチャが ja-JP の場合は日本語、en-US の場合は英語で表示されます。下の画像はカルチャが en-US の場合のものです。カルチャが ja-JP の場合のもの(上の画像)と比較してみてください。

カルチャが en-US の場合

なお、TextBox に入力される日付の形式は、CalendarExtender コントロールの Format プロパティで明示的に設定できます。当然、EnableScriptGlobalization プロパティの設定より、こちらの方が優先されます。なので、カルチャに依存させないで固定的に日付の形式を設定したい場合は Format="yyyy/MM/dd" のようにすることができます。

以上の対応で、上記の問題の (1) と (2) は解決できます。しかし、「(3) カレンダーのタイトルと今日の日付の表示」は依然として米国形式のままです。これを解決するには、CalendarExtender コントロールの DaysModeTitleFormat, TodaysDateFormat プロパティで書式を指定してやります。

下の画像は、DaysModeTitleFormat="yyyy年M月" TodaysDateFormat="yyyy年M月d日" とした時のものです。

タイトルと今日の日付を日本語形��に

ただし、Format, DaysModeTitleFormat, TodaysDateFormat プロパティで書式を指定してしまうのは、グローバル化と逆行することになる(他のカルチャに対応できなくなる)ので、そうすることが良いのかどうかはよく考えた方がよさそうです。

参考に、上の画像のカレンダーを表示したコードを載せておきます。

<%@ Page Language="C#" Culture="auto" UICulture="auto" %>
<%@ Import Namespace="System.Threading" %>

<%@ Register Assembly="AjaxControlToolkit" 
  Namespace="AjaxControlToolkit" 
  TagPrefix="asp" %>

<!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)
  {
    Label1.Text = "CurrentCulture: " +
        Thread.CurrentThread.CurrentCulture.ToString();
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <asp:ToolkitScriptManager ID="ToolkitScriptManager1" 
    runat="server" 
    EnableScriptGlobalization="True">
  </asp:ToolkitScriptManager>
  <div>
    <asp:Label ID="Label1" runat="server">
    </asp:Label>
    <br />
    <asp:TextBox ID="TextBox1" runat="server">
    </asp:TextBox>
    <asp:CalendarExtender ID="TextBox1_CalendarExtender" 
      runat="server" 
      Enabled="True" 
      TargetControlID="TextBox1"            
      DaysModeTitleFormat="yyyy年M月" 
      TodaysDateFormat="yyyy年M月d日"
      Format="yyyy/MM/dd" >
    </asp:CalendarExtender>
  </div>
  </form>
</body>
</html>

Tags: ,

AJAX

ModalPopup を別ページから非表示

by WebSurfer 27. January 2013 16:52

Ajax Control Toolkit の ModalPopup 内の iframe に別ページを表示し、その別ページに配置されているボタンをクリックして ModalPopup を非表示にする方法の紹介です。

ModalPopup はクライアントスクリプトで非表示にできます。それには、Modalpopup をページに配置するとダウンロードされるクライアントスクリプトに定義されている hide メソッドを使います。

従って、iframe に表示するページの適当な DOM に click イベントのリスナーを仕掛けて、それで hide メソッドを起動すれば ModalPopup を非表示にできます。

ただし、iframe に表示するページは親ページと同じドメインのものでないと DOM が取得できないので注意してください(クロスサイトスクリプト対策だそうです)。

そのサンプルコードを以下に書いておきます。また、実際に動かして試すことができるよう 実験室 にアップしました。興味のある方は試してみてください。

親ページ

<%@ Page Language="C#" %>
<%@ Register Assembly="AjaxControlToolkit" 
    Namespace="AjaxControlToolkit" 
    TagPrefix="asp" %>

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

<script runat="server">
 
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
    //<![CDATA[

        // iframe 内の document オブジェクトを取得。
        // contentWindow は IE 用。
        // contentDocument は Firefox 用。
        function iframeRef(frameRef) {
            return frameRef.contentWindow ?
                frameRef.contentWindow.document : 
                    frameRef.contentDocument;
        }

        function hideModalPopup() {
            var modalPopup = 
                $find('programmaticModalPopupBehavior');
            modalPopup.hide();
        }

        function showModalPopup() {
            var ifm = iframeRef($get('iframe1'));
            var btn = ifm.getElementById('hideButton');
            // hide するとリスナーも解除されてしまうので、
            // (btn.click が null になることで確認できる)
            // ModalPopup を表示するたびリスナーをアタッチ
            // する必要がある。
            if (btn.onclick == null) {
                if (window.addEventListener) {
                    btn.addEventListener('click',
                                         hideModalPopup, 
                                         false);
                } else if (window.attachEvent) {
                    btn.attachEvent('onclick', 
                                    hideModalPopup);
                }
            }

            var modalPopup = 
                $find('programmaticModalPopupBehavior');
            modalPopup.show();
        }
    //]]>
    </script>

    <style type="text/css">
        /*Modal Popup*/
        .modalBackground
        {
            background-color: Gray;
            filter: alpha(opacity=70);
            opacity: 0.7;
        }
        .popup
        {
            background-color: White;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ToolkitScriptManager 
        ID="ToolkitScriptManager1" 
        runat="server">
    </asp:ToolkitScriptManager>  

    <h1>ModalPopup Test</h1>

    <asp:Button ID="DummyButton" 
        runat="server"
        style="display: none;" />

    <input type="button" 
        value="Show ModalPopup" 
        onclick="showModalPopup();" />

    <asp:Panel 
        ID="Panel1" 
        runat="server" 
        CssClass="popup">
        <iframe 
            id="iframe1" 
            src="190-PageIniframe.aspx">
        </iframe>
    </asp:Panel>

    <asp:ModalPopupExtender 
        ID="ModalPopupExtender1" 
        runat="server"
        TargetControlID="DummyButton" 
        BehaviorID="programmaticModalPopupBehavior" 
        BackgroundCssClass="modalBackground" 
        PopupControlID="Panel1">
    </asp:ModalPopupExtender>
    </form>
</body>
</html>

iframe に表示するページ

<%@ 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">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Page in iframe</h1>
        <input type="button" 
            id="hideButton" 
            value="Hide ModalPopup" />
    </div>
    </form>
</body>
</html>

Tags: ,

AJAX

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  November 2019  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar