Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

jQuery対応グリッドをASP.NET MVCで利用し、リッチな表現を簡単に実現する

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

 Webアプリケーション開発におけるJavaScriptライブラリのデファクトスタンダードとも呼べるjQueryは軽量かつ高機能なライブラリです。本記事ではこの利点を活かしたjQuery対応コンポーネント集であるNetAdvantage for jQueryを利用しリッチなグリッド表示を簡単に実現します。

 また、このコンポーネント集ではMicrosoft社のASP.NET MVCに対応したラッパークラスを提供しているため、ASP.NET MVC 3のRazor記法に慣れている場合はこのラッパーを利用しコントロールを利用できます。

対象読者

 jQueryに興味のある人。ASP.NET MVCに興味のある人。

必要環境

 「jQueryを利用した軽量・高機能なクライアントサイド実装!」において紹介されているようにjQueryコンポーネントを単体で利用する場合には下記のソフトウェアのみで利用できます。

 本記事ではASP.NET MVC3を利用するため、さらに次のソフトウェアが必要になります。

 サンプルはVisual Studio 2010 SP1 Ultimate+ASP.NET MVC 3で作成しています。また、Windows 7 Ultimate 64bit版において動作を検証しています。

サンプル実行時の注意環境

 サンプルには必要なCSSスクリプトファイルが組み込まれていません。「jQueryを利用した軽量・高機能なクライアントサイド実装!」記事の「NetAdvantage for jQuery の利用方法」項や本記事の「プロジェクトに必要なファイルを追加」項を参考に必要ファイルを組み込んでください。また、アイコンファイルについてもNetAdvantage ICONS各製品のサンプルアイコンを利用しているため、含まれていません。製品ページよりサンプルアイコンをダウンロードしてください。

コンポーネントのインストール

 はじめてNetAdvantage for jQueryを使用する場合は、事前にソフトウェアをインストールする必要があります。インフラジスティックス社のWebページからインストーラーをダウンロードしてください。この製品は有償ですが、20日間すべての機能を試用できる無償トライアル版としても利用が可能です。

サンプルのシナリオ

 今回作成するサンプルではとある地域の複合商業施設一覧を表示するグリッド部分の実装を行います。完成版のスクリーンショットは下記のとおりとなります。

図1 今回のサンプル(完成版)
図1 今回のサンプル(完成版)

ASP.NET MVCプロジェクトの作成

 まず、Visual Studioを開き、新しいASP.NET MVC 3アプリケーションを作成します。プロジェクト名は"InfraShoppingMall"とします。プロジェクトテンプレートではインターネットアプリケーションを選択し、ビューエンジンはRazorを選択します。詳細については「ASP.NET MVC 3Tools UpdateとView周りの改良点」を参考にしてください。

プロジェクトに必要なファイルを追加

 作成されたプロジェクトのScript、ContentフォルダーにそれぞれIGという名前のフォルダーを作成し、次のファイルをNetAdvantage for jQueryのインストールフォルダーからコピーします。

  • Content/IGフォルダー
    • themes\minフォルダー内のフォルダー、ファイル
  • Scripsts/IGフォルダー
    • ig.ui.min.js

 ここまでのフォルダー構造は次のようになっています。

図2 必要ファイルの組み込み
図2 必要ファイルの組み込み

 次に、追加したこれらのCSS, スクリプトファイルを画面側で参照する必要があります。Sharedフォルダーの_Layout.cshtmlファイルで参照するとすべてのビューに反映されます。

_Layout.cshtml
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/IG/ig.ui.min.js")" type="text/javascript"></script>
<link href="@Url.Content("~/Content/IG/base/ig.ui.grid.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/IG/ig/jquery.ui.custom.min.css")" rel="stylesheet" type="text/css" />

 さらに、ASP.NET MVC 3用に用意されているラッパークラスアセンブリInfragistics.Web.MVC.dllへの参照を追加し、ビュー編集画面においてラッパーを利用するためにアセンブリのプロパティ画面でローカルコピーをTrueと設定します。

図3 MVCラッパーへのアセンブリ参照
図3 MVCラッパーへのアセンブリ参照
図4 Trueと設定することでBinフォルダーにアセンブリがコピーされる
図4 Trueと設定することでBinフォルダーにアセンブリがコピーされる

DBの構造

 このサンプルのApp_DataにはShoppingMall.mdfという名前のDBが存在し、Mallテーブルで各ショッピングモールの情報を保持しています。テーブルのスキーマは以下のとおりとなっています。

列名 データ型 Nullを許容
ID(主キー) Int No
Name nvarchar(50) No
OpenTime time(7) No
CloseTime time(7) No
ShoppingCart Bit No
PhotoStudio Bit No
MedicalRoom Bit No
ChildService Bit No
ShippingService Bit No
PrintingService Bit No

 このデータを取得するためにEntity Frameworkを利用します。

ADO.NET Entity Data Modelを作成

 Modelsフォルダーに新しくADO.NET Entity Data Modelを作成します。モデル名はShoppingMallDataModelと名付けます。

図5 Entity Data Modelの作成
図5 Entity Data Modelの作成

 ウィザードにおいてデータベースからモデルを作成していきます。

図6 データベースからモデルを生成
図6 データベースからモデルを生成
図7 App_DataフォルダーのDBファイルへの接続を設定
図7 App_DataフォルダーのDBファイルへの接続を設定
図8 モデルに追加するテーブルを選択
図8 モデルに追加するテーブルを選択

 これでEntity Data Modelの作成が完了しました。

DBからリスト項目を取得

 ModelsフォルダーでMallModelクラスを作成し、先ほど作成したEntityDataModelを用いてDBからリスト項目を取得するStaticメソッドを実装します。この際、メソッドの戻り値の型はIQueryable<>を指定します。

MallModel.cs
public class MallModel
{
    public static IQueryable<Mall> GetMallList()
    {
        ShoppingMallEntities entities = 
                new ShoppingMallEntities();
        // Mall 一覧を返す
        return entities.Mall.AsQueryable<Mall>();
    }
}

Controllerを実装

 Controllerでは先ほどのMallModelクラスのGetMallList()メソッドを使用し、View側に項目一覧を渡します。この際、GridDataSourceActionと指定することで、View側のjQueryグリッドにグリッドデータ取得アクションであることを明示します。

HomeController.cs
[Infragistics.Web.Mvc.GridDataSourceAction]
public ActionResult GetMallList()
{
    // ビューにモール情報の一覧を渡します。
    return View(Models.MallModel.GetMallList());
}

Viewを実装

 ビュー側では先ほど追加したInfragistics.Web.MVC.dllで実装されているラッパークラスを用いてjQueryグリッドの設定を行うことが可能です。

 まずは、名前空間のインポートを行います。

Index.cshtml
@using Infragistics.Web.Mvc;

 次にHtmlヘルパーを利用し、グリッドの宣言を行います。データ表示を行うための次のプロパティを設定します。

  • DataSourceまたはDataSourceUrl
  • Columns

 その後、DataBind()メソッドを呼び出しデータのバインディングを、Render()メソッドを実行し、スクリプトの出力を行います。

@(Html.Infragistics().Grid<InfraShoppingMall.Models.Mall>()
    .ID("igGrid1")
    .DataSourceUrl(Url.Action("GetMallList"))
    .Columns(columns =>
        {
            columns.For(x => x.ID).HeaderText("ID");
            columns.For(x => x.Name).HeaderText("モール名");
            columns.For(x => x.OpenTime).HeaderText("営業開始時刻");
            columns.For(x => x.CloseTime).HeaderText("営業終了時刻");
            columns.For(x => x.ShoppingCart).HeaderText("大型店舗");
            columns.For(x => x.PhotoStudio).HeaderText("写真館");
            columns.For(x => x.MedicalRoom).HeaderText("クリニック");
            columns.For(x => x.PrintingService).HeaderText("印刷サービス");
            columns.For(x => x.ShippingService).HeaderText("発送サービス");
        })
    .DataBind()
    .Render()
    )

 出力されたスクリプトと、描画されたグリッドは次のようになります。スクリプトの内容をこちらの記事と比べてみてください。「jQueryを利用した軽量・高機能なクライアントサイド実装!

<table id="igGrid1"></table>
<script type="text/javascript">
    $(function(){$('#igGrid1').igGrid({ 
        dataSource: '/Home/GetMallList',autoGenerateColumns: false,
        responseDataKey: 'Records', generateCompactJSONResponse: false,
        columns: [ 
            { key: 'ID', dataType: 'number', headerText: 'ID' }, 
            { key: 'Name', dataType: 'string', headerText: 'モール名' }, 
            { key: 'OpenTime', dataType: 'string', headerText: '営業開始時刻' }, 
            { key: 'CloseTime', dataType: 'string', headerText: '営業終了時刻' }, 
            { key: 'ShoppingCart', dataType: 'bool', headerText: '大型店舗' }, 
            { key: 'PhotoStudio', dataType: 'bool', headerText: '写真館' }, 
            { key: 'MedicalRoom', dataType: 'bool', headerText: 'クリニック' }, 
            { key: 'PrintingService', dataType: 'bool', headerText: '印刷サービス' }, 
            { key: 'ShippingService', dataType: 'bool', headerText: '発送サービス' } ], 
        localSchemaTransform: false });});
</script>
図9 グリッドにデータが表示された
図9 グリッドにデータが表示された

jQueryテンプレートを利用し、表示をカスタマイズ

 このようにASP.NET MVCラッパーを使用しjQueryグリッドを生成することができましたが、データを単純に表示するだけではユーザーが情報を正しく理解することが難しくなります。このigGridではjQueryで提供されているテンプレート機能を利用し、それぞれのセルの表現をカスタマイズできます。jQueryテンプレートについは次の記事・サイトを参考にしてください。

 igGridでjQueryテンプレートを利用する場合は次のプロパティを設定する必要があります。

  • JQueryTemplate
  • RowTemplate

 テンプレートの実装を行う前に、今回の目標を設定します。

  1. 営業開始時刻、営業終了時刻を1列にまとめ、営業時間列とし、正しい情報を表示する
  2. 設備・サービス情報についても1列にまとめ、さらにユーザーが分かりやすいような表記とする

テンプレートプラグインの組み込みと列定義の変更

 まずはjQueryテンプレートプラグインを_Layout.cshtmlに組み込みます。本記事執筆時点はベータ版という扱いとなっていることに注意してください。

_Layout.cshtml
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>

 列の定義に関しては複数の列データをまとめるため、現在の列数は必要ありません。今回は4列を残し削除しました。また併せてヘッダーテキスト、幅を設定します。

Index.cshtml
.Columns(columns =>
{
    columns.For(x => x.ID).HeaderText("ID") .Width("100px");
    columns.For(x => x.Name).HeaderText("モール名") .Width("200px");
    columns.For(x => x.OpenTime).HeaderText("営業時間") .Width("200px");
    columns.For(x => x.ShoppingCart).HeaderText("設備・サービス") .Width("400px");
})

テンプレートの有効化と定義

 igGridでテンプレートを利用するため、JQueryTemplate, RowTemplateプロパティを設定します。RowTemplateプロパティでは各行に適用されるテンプレートを定義することになります。サンプルとしてそれぞれの列に固定値を割り当てるテンプレート定義は下記のとおりとなります。

.JQueryTemplating(true)
//テンプレートの定義
.RowTemplate("<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>")

 この場合の実行結果は下記のようにそれぞれのセルに対して固定の値が設定されました。

図10 jQueryテンプレートサンプル
図10 jQueryテンプレートサンプル

 上記の定義ではテンプレートの定義部分を文字列として定義していますが、複雑なテンプレートを生成する場合、可読性が落ちてしまいます。このような場合にはテンプレート部分を外だしで定義できます。

Index.cshtml
@*テンプレート*@
<script id="GridRowTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
    </tr>
</script>

@(Html.Infragistics().Grid<InfraShoppingMall.Models.Mall>()
    .ID("igGrid1")
    .DataSourceUrl(Url.Action("GetMallList"))
    .Columns(columns =>
    {
        columns.For(x => x.ID).HeaderText("ID") .Width("100px");
        columns.For(x => x.Name).HeaderText("モール名") .Width("200px");
        columns.For(x => x.OpenTime).HeaderText("営業時間") .Width("200px");
        columns.For(x => x.ShoppingCart).HeaderText("設備・サービス") .Width("400px");
    })
    .JQueryTemplating(true)
    // テンプレート呼び出し
    .RowTemplate("{{tmpl '#GridRowTemplate'}}")
    .DataBind()
    .Render()
    )

テンプレートの設定

 Index.cshtmlにおいてテンプレートのID, 名前列ではそのまま生のデータを表示するように設定します。

<td>${ID}</td>
<td>${Name}</td>

 営業時間のデータはOpenTime, CloseTimeから生成するため、別関数を呼び出すよう設定します。

<td>${ConvertToOpenHours(OpenTime, CloseTime)}</td>

 このConvertToOpenHours関数は開始時刻、終了時刻から営業時間の文字列を返すように定義します。

@*スクリプト*@
<script type="text/javascript">
    function ConvertToOpenHours(oTime, cTime) {
        return AddZeros(String(oTime.Hours), 2) + ":"
        + AddZeros(String(oTime.Minutes), 2) + ":"
        + AddZeros(String(oTime.Seconds), 2) + " - "
        + AddZeros(String(cTime.Hours), 2) + ":"
        + AddZeros(String(cTime.Minutes), 2) + ":"
        + AddZeros(String(cTime.Seconds), 2);
    }

    function AddZeros(str, num) {
        for (var i = 0; i < num - str.length; i++) {
            str = "0" + str;
        }
        return str;
    }
</script>

 最後に設備・サービスが提供されている施設ではアイコンを表示するという表現を行い、ユーザーが情報を把握しやすいように設定します。Imagesフォルダーを作成し、NetAdvantage ICONSのサンプルアイコンをいくつか追加しました。

図11 NetAdvantage ICONSのサンプルファイルを追加
図11 NetAdvantage ICONSのサンプルファイルを追加

 テンプレートでは条件判定を行う{{if}} {{/if}}を利用し、それぞれの項目の値がtrueの場合、画像を表示するように設定します。

<td>
    {{if ShoppingCart == true}}
        <img src='/Images/ShoppingCart64.png' title='大型施設'></img>
    {{/if}}
    {{if PhotoStudio == true}}
        <img src='/Images/CameraDigital64.png' title='写真館'></img>
    {{/if}}
    {{if MedicalRoom == true}}
        <img src='/Images/MedicalBag64.png' title='クリニック'></img>
    {{/if}}
    {{if ShippingService == true}}
        <img src='/Images/FactoryAutomationEquipment64.png' title='発送サービス'></img>
    {{/if}}
    {{if PrintingService == true}}
        <img src='/Images/ReportWithChart64.png' title='印刷サービス'></img>
    {{/if}}            
</td>

 これですべての設定が完了しました。実行結果は下記のとおりとなります。

図12 リッチなグリッドが実現された
図12 リッチなグリッドが実現された

まとめ

 今回はASP.NET MVC 3とEntity Framework、さらにNetAdvantage for jQueryで提供されているASP.NET MVCラッパーを利用しデータを表示しました。また、igGridでサポートしている、jQueryテンプレートという強力なテンプレートエンジンを利用しリッチなグリッド表示を迅速に実現しました。この igGridをはじめとしたNetAdvantage for jQueryの関連情報についてはこちらでも提供されていますのでぜひご覧ください。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5