実際にBorderContainerを利用してアプリケーション画面を作る
それでは、実際にBorderContainerを利用して、前回の例で出てきた「記事閲覧アプリケーション」の画面を作ってみましょう。
<div dojoType="dijit.layout.BorderContainer" style="width: 100%; height: 100%;"> <div dojoType="dijit.layout.ContentPane" region="top" style="height: 50px;">記事一覧</div> <div dojoType="examples.widget.ArticleSearch" region="leading" splitter="true" style="width: 300px;"></div> <div dojoType="examples.widget.ArticleList" region="center"></div> <div dojoType="examples.widget.CommentForm1" region="right" splitter="true" style="width: 300px;"></div> <div>
まずは大元のページです。BorderContainerを使ってウィジェットを3つとヘッダを配置しています。幅、高さともに100%を指定して、画面いっぱいに広がるようにしています。
ArticleSearchは単純なコンポジット・ウィジェットで、テンプレートを利用してウィジェットを並べています。ArticleListウィジェットはBorderContainerを継承し、動的にウィジェットを生成して自分の子ウィジェットとして配置しています。そしてCommentForm1は、前回のサンプルのウィジェットをそのまま利用しています。
dojo.require("dojox.grid.DataGrid"); dojo.require("dijit.form.Button"); dojo.require("dijit.Toolbar"); dojo.require("dojo.data.ItemFileReadStore"); dojo.declare("examples.widget.ArticleList", dijit.layout.BorderContainer, { gutters: false, _filePath: dojo.moduleUrl("examples.widget", "_data/articles.json"), buildRendering: function() { this.inherited(arguments); // ツールバーとGridを作成 this.toolbar = new dijit.Toolbar({region: "top"}); this.grid = new dojox.grid.DataGrid({region: "center"}); this.addChild(this.toolbar); this.addChild(this.grid); // ツールバーにボタン配置 this.toolbar.addChild(new dijit.form.Button({label: "読む"})); this.toolbar.addChild(new dijit.form.Button({label: "後で読む"})); this.toolbar.addChild(new dijit.ToolbarSeparator()); this.toolbar.addChild(new dijit.form.Button({label: "ダウンロード"})); this.toolbar.addChild(new dijit.form.Button({label: "印刷"})); }, startup: function() { this.inherited(arguments); // データ読み込み var store = new dojo.data.ItemFileReadStore({url: this._filePath}); var structure = [ {field: "title", name: "タイトル", width: "30%"}, {field: "date", name: "作成日時", width: "30%"}, {field: "author", name: "著者", width: "40%"} ]; this.grid.set("structure", structure); this.grid.setStore(store); } });
resizeメソッドについて
BorderContainerがウィジェットを配置する際、各ウィジェットにresizeメソッドが実装されている場合、それが呼ばれます(実装されていない場合は、ウィジェットのDOMノードのサイズを変更するだけにとどまります)。例えば、CommentForm1にはresizeメソッドがなく、レイアウト・ウィジェットも利用していないので、上のアプリケーションでCommentForm1のサイズを変更しても、中のフォーム・ウィジェットのサイズは変わりません。これにresizeメソッドを実装してウィジェットのサイズ変更と同時に、フォーム・ウィジェットのサイズが変わるようにしてみましょう。 ここで、resizeの引数に値が渡される場合と、渡されない場合があります。今回のように、親がBorderContainerの場合には、指定したサイズに変更するように値が渡されますので、自分自身をそのサイズに変更します。 渡ってこなかった場合は、自分で適切なサイズを算出する必要があります(今回は省略します)。
resize: function(size) { if (size) { // 自分自身のサイズを変更する dojo.marginBox(this.domNode, size); } // 自分の描画領域の幅を取得 var w = dojo.contentBox(this.domNode).w; // TextAreaは幅いっぱいにし、名前入力エリアは幅の半分をセット dojo.marginBox(this._commentArea.domNode, {w: w}); dojo.marginBox(this._nameBox.domNode, {w: w/2}); }
dojo.contentBoxおよびdojo.marginBoxは、サイズの取得や変更に便利なユーティリティで、ブラウザごとに違ったりするマージンの計算などを吸収してくれます。ここではウィジェット自身の幅の取得と、フォーム・ウィジェットの幅の変更に使っています。これで幅の変更に応じて中身のサイズも変わるようになりました。
dijitのウィジェットの中には、既にresizeを実装しているものがあります(BorderContainerやContentPaneなど)。これらのウィジェットを継承したカスタム・ウィジェットで自前のresizeを実装する際には、完全に上書きしてしまうと動かなくなる可能性があるので、注意が必要です。