SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

「Dojo道場」~実用アプリ構築のためのベストプラクティス

Dojo道場 ~ 第6回「Dijitウィジェットを利用したアプリケーション作成の基礎」

「Dojo道場」~実用アプリ構築のためのベストプラクティス

  • X ポスト
  • このエントリーをはてなブックマークに追加

サンプル・アプリケーションの作成

  これまでに紹介したDijitウィジェットに加え、レイアウト用ウィジェット利用してサンプル・アプリケーションを作ってみましょう。 作成するサンプル・アプリケーションはオンライン・ブックストアです。 このオンライン・ブックストアでは、商品選択画面と、カート画面があり、それぞれをタブで切り替えることができます。 各画面の概要は以下のとおりです。

商品選択画面:

 画面左にある商品カテゴリーを利用して商品を選択します。選択された商品のイメージを右上部に、詳細情報を右下部に表示します。 購入予定数を入力して、「カートに追加」ボタンをクリックすると、選択されている商品をカートに追加します。

カート画面:

 商品選択画面で選択した商品リストと合計金額を確認できます。  「会計」ボタンをクリックすると、カートの中の商品の会計処理を行います。  「クリア」ボタンをクリックすると、カート内の商品一覧をクリアすることができます。

注2

 このサンプル・アプリケーションでは、画面の構成の定義はwidgetPrimer-bookstore.htmlに、イベント・ハンドラーはwidgetPrimer-bookstore.jsに記述されています。以降の説明で登場するHTMLフラグメントはwidgetPrimer-bookstore.htmlを、JavaScriptはwidgetPrimer-bookstore.jsを参照してください。

画面のレイアウト

 レイアウト用ウィジェットはdijit.layoutパッケージ内にあります。このサンプルアプリケーションでは、dijit.layout.TabContainerとdijit.layout.BorderContainerを使用します。 詳細情報やその他のウィジェットについては、dijit.layoutのAPIを参照してください。

 まずは、dijit.layout.TabContainerを使用して、商品選択画面とカート画面を配置します。dijit.layout.TabContainerの子要素として、 商品選択画面(dijit.layout.BorderContainer)と画面(dijit.layout.ContentPane)を記述します。

リスト8. dijit.layout.TabContainerを使ったレイアウト
<div dojoType="dijit.layout.TabContainer">
  <div dojoType="dijit.BorderContainer" title="商品選択画面">
    <!-- 商品選択画面 -->
    ...
  </div>
  <div dojoType="dijit.layout.ContentPane" title="カート">
    <!-- カート画面 -->
    ...
  </div>
</div>

  dijit.layout.TabContainerは複数の子ウィジェットを持つことができます。 各子ウィジェットのtitle属性はタブページのタイトルとして表示されます。 上記のようにHTMLで宣言的に記述してタブページの構成を定義することもできますが、 プログラムで動的にページを追加することもできます。詳細については dijit.layout.TabContainerのAPIを確認してください。

 次に商品選択画面のレイアウトを行います。商品選択画面は3つの部分で構成します。3つのペインのそれぞれは、商品カテゴリー画面(左側)、商品イメージ(右上部)、商品詳細画面(右下部)です。 dijit.layout.BorderContainerを使用してこれらのレイアウトを行うには以下のように記述します。

リスト9. dijit.layout.BorderContainerを使ったレイアウト
<!-- 商品選択画面 -->
<div dojoType="dijit.layout.BorderContainer" design="sidebar">
	<!-- 商品カテゴリー -->
	<div dojoType="dijit.Tree" region="left" splitter="true">
	</div>
	<!-- 商品イメージ -->
	<div dojoType="dijit.layout.ContentPane" region="top" splitter="true">
	</div>
	<!-- 商品詳細 -->
	<div dojoType="dijit.layout.ContentPane" region="center">
	</div>
</div>

 BorderContainerウィジェットの各子要素にはregion属性を付加し、各子ウィジェットをBorderContainerのどこに配置するかを指定します。 全ての子ウィジェットでregion属性値を指定する必要があります。

 BorderContainerのdesign属性には"headline"または"sidebar"を指定できます。design属性のデフォルト値は"headline"です。 "headline"は上下のペインが左右のペインの外側に表示されます。 商品カテゴリー画面を商品イメージ/詳細画面の左側に配置したいので"sidebar"スタイルを使用しています。

 子ウィジェットのsplitter属性の値をtrueにすると、ペインのサイズを変更するリサイズハンドラーを付加することができます。 splitter属性はregion="center"以外の子ウィジェットに指定することができます。

イベント・ハンドラー

 それでは、「カートに追加」ボタンにonClick属性を使ってイベント・ハンドラーを追加してみましょう。 「カートに追加」ボタンのイベント・ハンドラーは以下のように記述します。

リスト10. onClickイベント・ハンドラー
<div dojoType="dijit.form.Button"
  onClick="sampleApp.product.onClickAddToCartButton">
   カートに追加</div>

 上記のようにonClick属性を指定することで、dijit.form.ButtonのonClickメソッドが呼ばれると、sampleApp.product.onClickTreeNodeが呼ばれます。

  次はTreeウィジェットでの使用例です。Treeウィジェットのアイテムが選択されると、onClickメソッドが呼ばれます。 このonClickメソッドにイベント・ハンドラーを追加し、商品画面および商品詳細情報を更新するようにします。 「カートに追加」ボタンの例と同様の方法で、onClick属性にイベント・ハンドラー、sampleApp.product.onClickTreeNodeを指定しています。

リスト11. onClickTreeNodeイベント・ハンドラー
<div dojoType="dijit.Tree" model="model" region="left"
	splitter="true" style="width: 25%;"
	onClick="sampleApp.product.onClickTreeNode">
</div>

 次に確認ダイアログのOKボタンの例を見てみましょう。確認ダイアログのOKボタンでは、<script>を使用してイベント・ハンドラーを定義しています。 dijit.form.ButtonのonClickメソッドにコネクトするにはリスト12のように、type属性に"dojo/connect"、event属性にonClickを指定します。 そして<script>タグ内にイベント・ハンドラーを記述します。処理内容が単純であれば、処理内容を直接記述できるので便利です。

リスト12. scriptタグを使ったonClickイベント・ハンドラー
<div dojoType="dijit.form.Button">OK
  <script type="dojo/connect" event="onClick">
    dijit.byId("confirmDlg").onCancel();
  </script>
</div>

Pub/Sub

 サンプルアプリケーションでは、Pub/Subの機能を使ってカートへの追加処理とカート内のリストの更新を行っています。

 まずはトピックを発行する側の実装方法を見てみましょう。「カートに追加」ボタンをクリックすると、sampleApp.product.onClickAddToCartButtonが呼ばれます。

リスト13. トピックの発行
  onClickAddToCartButton: function(e) {
    var numOfProduct = dijit.byId("numOfProduct").get("value");
    var msg = {
      id: sampleApp.product.currentProductId,
      num: numOfProduct
    };
    dojo.publish("/sampleApp/addToCart", [msg]);
  }

 このイベント・ハンドラーでは、"/sampleApp/addToCart"というトピックで、商品のIDと購入数を含むメッセージを発行しています。このトピック"/sampleApp/addToCart"のメッセージを購読するには以下のように記述します。

リスト14. トピックの購読
  init: function() {
    var cartPane = dijit.byId("cartPane");
    cartPane.subscribe("/sampleApp/addToCart",
      sampleApp.cart.addProductToCart);
  }

 上記のように記述することで、メッセージが発行されると、イベント・ハンドラーsampleApp.cart.addProductToCartが呼ばれます。 sampleApp.cart.addProductToCartの実装は以下のようです。

リスト15. addProductToCartイベント・ハンドラー
  addProductToCart: function(args) {
    var num = args.num;
    store.fetchItemByIdentity({
      identity: args.id,
      onItem: function(item) {
        var label = store.getValue(item, "label");
        var price = store.getValue(item, "price");
        cartStore.newItem({name: label, price: price, num: num});
        
        // WidgetのsetメソッドでWidgetのプロパティをセットします。
        dijit.byId("clearListButton").set("disabled", false);
        dijit.byId("purchaseButton").set("disabled", false);
        
        cartStore.fetch({
          onComplete: function(items) {
            var total = 0;
            dojo.forEach(items, function(item) {
              var num = cartStore.getValue(item, "num");
              var price = cartStore.getValue(item, "price");
              total += num * price;
            });
            dojo.byId("total").innerHTML = total;
          }
        });
        sampleApp.showSimpleDlg("カートに追加しました。", "確認");
      }
    });
  },

 sampleApp.cart.addProductToCartでは、メッセージ内の商品IDと購入数から必要な情報を取り出し、カート内の商品一覧を更新します。 購入予定商品のリストはdojo.data.ItemFileWriteStoreで管理しDataGridで表示しています。 dojo.data.ItemFileWriteStoreおよびdojox.grid.DataGridに関する詳しい説明については、本連載の第2回および第3回で紹介していますのではここでは割愛します。

次のページ
まとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
「Dojo道場」~実用アプリ構築のためのベストプラクティス連載記事一覧

もっと読む

この記事の著者

仁田 圭祐(ニッタ ケイスケ)

日本アイ・ビー・エム株式会社ソフトウェア開発研究所にて日々Webアプリケーションに関わる製品開発をしています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

三浦 圭司(ミウラ ケイジ)

日本アイ・ビー・エム株式会社ソフトウェア開発研究所に勤務。現在は、エンタープライズ向け製品のWebアプリケーションのユーザー・インターフェース開発に従事。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5835 2011/04/06 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング