WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

CalendarExtender の利用例

by WebSurfer 7. May 2022 14:04

Ajax Control Toolkit の CalendarExtender を、下の画像のようにテキストボックスなし(実際は非表示)で、img 要素(普通のボタンでも可)をクリックして表示し、ユーザーがカレンダー上で選択した日付をサーバー側に送信する方法を書きます。

CalendarExtender

今時 CalendarExtender を使うことはあまりなさそうで、しかもこの記事に書いてあるような特殊な使い方をすることはまずなさそうですが、せっかく考えたので備忘録として書いておくことにしました。

CalendarExtender の基本的な使い方については、DevExpress のデモページ「Calendar Demonstration」と、@IT の記事「Calendarコントロールで日付入力ボックスを定義するには?」が参考になると思いますので一読されることをお勧めします。

カレンダーを img 要素(または普通のボタン)をクリックして表示する方法ですが、DevExpress のデモページの「Calendar with an associated button」と @IT の記事の「補助カレンダーを任意のボタンから起動する」を見てください。

この記事では、DevExpress のデモページと同じ画像を img 要素を使って表示し、CalendarExtender の PopupButtonID プロパティに img 要素の id を設定して、その img 要素をクリックしてカレンダーを表示します。img 要素に代えて <button type="button"> も使えます。ただし、クリックするとポストバックが起こる Button コントロールなどを使う場合は、ポストバックが起こらないように処置する必要があるので注意してください。

CalendarExtender の対象となるテキストボックスを指定する TargetControlID の設定は必須です。なので必ずテキストボックスをページに配置する必要があります。非表示にしたい場合は CSS で display: none; を設定してください。TextBox.Visible プロパティを false に設定するのはダメです。

カレンダーの表示位置はデフォルトでは自動的にテキストボックス直下になります。テキストボックスを非表示にする場合は自力で JavaScript を書いてカレンダーの表示位置を設定する必要があります。

その方法は Code Project の記事 Ajax CalendarExtender pop up position の Solution 1 を参考にさせてもらいました。

最後に、ユーザーが選択した日付をサーバーに送信する方法ですが、選択した時点で日付はテキストボックスに自動的に入力されますので、何らかの手段でポストバックをかければサーバー側で Text プロパティから取得できます。

CalendarExtender の OnClientDateSelectionChanged プロパティに JavaScript のリスナを設定してそこで取得し、Ajax を使ってサーバーに送信することもできます。

以上を実装したサンプルコードを下に載せておきます。この記事の上の画像を表示したものです。

CalendarExtender.aspx.cs

using System.Web.UI;

namespace WebForms1
{
    public partial class CalendarExtender : System.Web.UI.Page
    {
        protected void Page_Init(object sender, EventArgs e)
        {
            // マスターページに配置した ScriptManager のプロパティ
            // EnableScriptGlobalization を true に設定する
            ScriptManager sm = ScriptManager.GetCurrent(this.Page);
            sm.EnableScriptGlobalization = true;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // ユーザーが選択した日付を取得・表示
            Label1.Text = TextBox1.Text;
        }
    }
}

CalendarExtender.aspx.cs

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"    
    AutoEventWireup="true" CodeBehind="CalendarExtender.aspx.cs" 
    Inherits="WebForms1.CalendarExtender" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeaderContent" runat="server">

    <script type="text/javascript">
        // Calendar の表示位置を img 要素直下に調整する
        function onCalendarShown(sender, args) {
            var img = $get('image1');

            sender._popupDiv.parentElement.style.top =
                img.offsetTop + img.height + 'px';
            sender._popupDiv.parentElement.style.left =
                img.offsetLeft + 'px';
        }

        // ユーザーが日付を選択すると発生するイベントのリスナ
        function sendResult(sender) {
            // 選択した日付は以下のようにして取得できる
            var selectedDate = sender.get_selectedDate();

            // ポストバックすればサーバー側では TextBox1.Text 
            // プロパティから選択した日付を取得できる
            var btn = $get('<%=Button1.ClientID %>');
            btn.click();
        }
    </script>

    <style type="text/css">
        /* TextBox1 を非表示にする */
        .style1 {
            display: none;
        }
    </style>

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h3>Ajax Control Toolkit CalendarExtender</h3>    
   
    <asp:TextBox ID="TextBox1" runat="server" CssClass="style1">
    </asp:TextBox>

    <%--PopupButtonID に設定するのはサーバーコントロールでなくても可--%>
    <img src="images/Calendar_scheduleHS.png" id="image1" alt="" />

    <ajaxToolkit:CalendarExtender ID="CalendarExtender1" 
        runat="server" 
        PopupButtonID="image1"
        TargetControlID="TextBox1" 
        DaysModeTitleFormat="yyyy年M月"
        TodaysDateFormat="yyyy年M月d日"
        Format="yyyy/MM/dd"
        OnClientDateSelectionChanged="sendResult" 
        OnClientShown="onCalendarShown" />

    <br />
    <%--ポストバックするための Button コントロール--%>
    <asp:Button ID="Button1" runat="server" Text="PostBack" />

    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</asp:Content>

なお、本題とは関係ないことですが、カレンダー上の日付の表示はデフォルトではなく、先の記事「CalendarExtender の日付の表示」に書いたように日本語形式にしています。

Tags: ,

AJAX

Ajax Control Toolkit スクリプト バンドル

by WebSurfer 10. June 2018 22:31

Ajax Control Toolkit は v7.x 以前では、使用する複数のスクリプトファイルをバンドルするために ToolkitScriptManager を使っていました。(ScriptManager ではなくて)

v15.1 以降では、DevExpress の記事 How to use Bundling and CDN にありますように、ScriptManager を使ってのバンドリングが可能となっています。(ちなみに、v15.1 以降 ToolkitScriptManager は提供されていません)

以下の画像の赤枠で囲った部分を見てください。これが Ajax Control Toolkit 用の複数のスクリプトファイルがバンドルされた結果です。

バンドルされたスクリプト

ASP.NET 4.5 以降で、Visual Studio Commnunity 2015 の[Web フォーム]のテンプレートを利用して作った ASP.NET Web Forms プロジェクトに、Ajax Control Toolkit を追加し、必要なスクリプトファイルを ScriptManager で統合できるようにしてみましたので、その方法や結果から分かったことを備忘録として書いておきます。

先の記事「ASP.NET 4.5 ScriptManage」に書きましたように、Microsoft Ajax、jQuery 等のスクリプトファイルが ScriptManager で統合できるようになり、[Web フォーム]のテンプレートを利用して作ったプロジェクトでは、それらが設定済みとなっています。

なので、そのプロジェクトに Ajax Control Toolkit 用のバンドル機能を追加すると、重複などの問題で修正が必要かも知れないと思っていましたが、自分が試した限りはそういうことはなかったです。

まず、NuGet で AjaxControlToolkit のパッケージをインストールします。それだけでも基本的なコントロールは動くようになりますが、ScriptManager を利用したバンドリングを可能にするためには、StaticResources パッケージも追加でインストールする必要があります。

NuGet パッケージの追加

バージョンは Ajax Control Toolkit 本体と合わせた方がよさそうです。ここでは、先にインストールした既存の Ajax Control Toolkit 本体が v17.1.1 なので、StaticResources のバージョンもそれに合わせて v17.1.1 にしました。

なお、Visual Studio で[空]のテンプレートを選択してプロジェクトを作った場合は StaticResources パッケージだけでは不足です。追加で Antlr, WebGrease などの NuGet パッケージもインストールする必要がありますが、StaticResources をインストールする際それらも自動的に追加されるはずです。

StaticResources のインストールが完了すると、以下の画像の赤枠で示したフォルダが生成され、その中に CSS ファイル、イメージ、スクリプトファイルが格納されます。

追加された CSS とスクリプト

Content/AjaxControlToolkit フォルダ下の Images フォルダには .gif, .jpg, .png などの画像ファイルが、Styles フォルダには minify してない .css ファイルと minify した .min.css ファイルの両方が格納されます。

Scripts/AjaxControlToolkit フォルダ下の Debug フォルダには minify してない .debug.js ファイルが、Release フォルダには minify した .js ファイルが格納されます。

さらに、web.config にはデフォルトで以下の設定が追加されます。

<ajaxControlToolkit 
    useStaticResources="true" 
    renderStyleLinks="false" />

DevExpress の記事 How to use Bundling and CDN の説明によるとバンドル機能をコントロールするもののようです。

あとは、DevExpress の記事 "Manual changes required" のセクションを参考に、ScriptManager に ScriptReference を追加してやればスクリプトは一番上の画像に示したようにバンドルされます。

具体的には以下の画像の赤枠で示したコードを追加してやります。

ScriptReference の追加

赤枠部分以外の ScriptManager のコードは、Visual Studio の[Web フォーム]のテンプレートを利用して作った ASP.NET Web Forms アプリのマスタページ Site.master に自動生成されたものです。

.css ファイルについても、DevExpress の記事に従って Styles.Render をページの適当な場所に追加してやれば、.css ファイルを参照する link 要素がレンダリングされます。

ただし、.css ファイルは web.config の compilation 要素で debug="false" とするか、Global.asax の Application_Start メソッドで BundleTable.EnableOptimizations を true に設定しないとバンドルされませんので注意してください。(スクリプトファイルと異なります。理由不明)

BundleTable.EnableOptimizations を true に設定する意味については Microsoft の文書 Bundling and Minification を見てください。抜粋すると "The following code (true に設定すること) enables bundling and minification and overrides any setting in the Web.config file." ということだそうです。

web.config の compilation 要素の debug 属性の true / false でどう異なるかですが、自分が検証した限りでは、

  • .css ファイル: true で minify &バンドルあり、false で minify なしでバンドルもなし。
  • スクリプトファイル: true / false の設定にかかわらず minify &バンドルあり。

・・・となりました。

スクリプトファイルの結果がちょっと解せないです。そのままでは、debug="true" にしてもスクリプトのデバッグができません。

.debug.js 版をダウンロードさせてデバッグ可能なようにするには、上の ScriptManager の設定のところで ScriptReference をコメントアウトする他なさそうです。

あと、minify&バンドルされたスクリプトファイルのサイズですが、何と 1,248,841 バイトもありました。Ajax Control Toolkit は使わないのにスクリプトをダウンロードするように設定するというのは避けた方がよさそうです。

ちなみに、.CSS ファイルの方は minify&バンドル後で 56,240 バイトでした。

最後にもう一つ、HtmlEditorEntender には AjaxControlToolkit.HtmlEditor.Sanitizer, HtmlAgilityPack が必要です。

それなしでは先の記事「Ajax Control Toolkit デモ」で述べたような意味不明のエラーが出てハマるかもしれませんのでご注意ください。

Tags: , ,

AJAX

Ajax Control Toolkit デモ

by WebSurfer 16. December 2017 20:25

Ajax Control Toolkit の最新版(この記事を書いた時点では v17.1.1.0)のデモを自分の開発環境で動くようにする手順を備忘録として書いておきます。

Ajax Control Toolkit デモ

DevExpress のサイト ASP.NET AJAX Control Toolkit Demos にデモは公開されていますが、自分の開発環境に同じものをインストールし、ソースコードを見たりデバッグ実行したいということがあると思います。

そのためには、まず、GitHub のサイト DevExpress/AjaxControlToolkit から AjaxControlToolkit-master.zip をダウンロードします。

ダウンロードしたファイル AjaxControlToolkit-master.zip の中に AjaxControlToolkit.SampleSite というフォルダがあるので、それを丸ごと解凍して適当な場所にコピーします。

v7.x までは、それを Visual Studio で開いて[デバッグ(D)]⇒[デバッグなしで開始(H)]で実行すれば動いたのですが、v17.1.1.0 では AjaxControlToolkit が見つからないというエラーになります。

基本的には NuGet で必要なパッケージをインストールして web.config を一部修正すれば動くようになるのですが、かなり多くのパッケージをインストールしなければならず、エラーメッセージも意味不明なものがあり、動くようになるまで 2 日ほどハマってしまいました。(笑)

NuGet

自分が NuGet からインストールしたパッケージおよびそのバージョンは以下の通りです。

  1. AjaxControlToolkit v17.1.1
  2. Microsoft.AspNet.Web.Optimization v1.1.3
  3. Microsoft.AspNet.Web.Optimization.WebForms v1.1.3
  4. AjaxControlToolkit.StaticResources v17.1.1
  5. WebGrease v1.6.0
  6. AjaxControlToolkit.HtmlEditor.Sanitizer v17.1.1
  7. HtmlAgilityPack v1.6.7
  8. Antlr v3.5.0.2
  9. Newtonsoft.Json v10.0.3
  10. Microsoft.Web.Infrastructure v1.0.0

web.config の修正箇所は以下の通りです。

  1. <trust level="Medium" /> を削除(理由不明ですが Visual Studio 2015 で IIS Express 64-bt で動かした場合はこれがあるとダメ)
  2. siteMap / providers 要素に <remove name="MySqlSiteMapProvider" /> を追加(これは MySQL の Connector/NET をインストールした自分の環境固有の問題)

上に書いた NuGet でのパッケージのインストールが完了するとアプリケーションの bin フォルダは以下のようになるはずです。

bin フォルダ

以下に自分的に注意すべきと思う点を書いておきます。

WebGrease, HtmlAgilityPack など[ソリューションの NuGet パッケージの管理]ではインストール済みと表示されるものがあります。その場合、新しいバージョンがリリースされていたら更新することでインストールできます。

Microsoft.Web.Infrastructure は新しいバージョンがない(1.0.0 しかない)ので[ソリューションの NuGet パッケージの管理]ではインストールできません。その場合は[パッケージマネージャーコンソール(O)]で以下のようにしてインストールできます。

Update-Package -reinstall Microsoft.Web.Infrastructure

HtmlEditorEntender には AjaxControlToolkit.HtmlEditor.Sanitizer が必要です。これなしで起動しようとすると以下のように "値を Null にすることはできません。パラメータ名:Type" という意味不明なエラーになります。これの原因が分からなくてハマりました。(汗)

エラーメッセージ

加えて、HtmlAgilityPack も必要です。もういい加減にカンベンしてって感じだったのですが、一応ここまででとりあえず動くようにはなりました。(笑)

Tags: ,

AJAX

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

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

View posts in large calendar