Layout Manager: Layout inside a resizable Panel
実は(わざわざもったいぶって言うことでもないのだが)、このLayout Panelというのは個人的には好きではない。
これは、かつて(随分前だけど)、dojoでひどい目にあったことがある。
簡単そうで、(その中をごちゃごちゃやろうとすると)意外と面倒くさいというイメージ。
ここで紹介されているサンプルは、ResizableなPanelに4ペイン(ヘッダー、フッターと真ん中2つ)のLayoutで、真ん中の仕切りは引っ張れるようになっている。(下)
外側の枠はYAHOO.widget.Panelになっていて、Resizableの修飾を加えるのは、以前の「Container Family: Creating a Resizable Panel」と同じ。
この間(Panelがrenderingされる前)に、YAHOO.widget.Layoutをつかって仕切りを作る。
YAHOO.widget.LayoutのAPIドキュメントを見ると、仕切りはLayoutUnitオブジェクトになるらしい。
こまごました事はソースに記したが、resizeのイベントにあわせて、Layoutをresizeする必要がある。
このタイミングで、centerユニットの文言を変えてみた。LayoutUnitはYAHOO.widget.Elementを祖先にもつので、DOM的に扱うのが正当なのだろうが、body属性をsetメソッドで変更したのが以下である。
(とても窮屈なコードなので、良いサンプルとはいえないなぁ)
以下に、Javascriptを含むHTML全文を示す。
コードはモジュール・パターンに書き直した。
<HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <TITLE>Ajax_Sampling</TITLE> <style type="text/css"> body { margin:0; padding:0; } </style> <link rel="stylesheet" type="text/css" href="scripts/yui/reset-fonts-grids/reset-fonts-grids.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/container/assets/skins/sam/container.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/resize/assets/skins/sam/resize.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/layout/assets/skins/sam/layout.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/button/assets/skins/sam/button.css" /> <script type="text/javascript" src="scripts/yui/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="scripts/yui/event/event-min.js"></script> <script type="text/javascript" src="scripts/yui/dom/dom-min.js"></script> <script type="text/javascript" src="scripts/yui/element/element-beta-min.js"></script> <script type="text/javascript" src="scripts/yui/dragdrop/dragdrop-min.js"></script> <script type="text/javascript" src="scripts/yui/container/container-min.js"></script> <script type="text/javascript" src="scripts/yui/resize/resize-min.js"></script> <script type="text/javascript" src="scripts/yui/animation/animation-min.js"></script> <script type="text/javascript" src="scripts/yui/layout/layout-min.js"></script> <style type="text/css" id="defaultstyle"> /* #container { margin: 2px; padding: 3px; width: 400px; height: auto; border:1px dashed #999999; } */ #demo .yui-resize-handle-br { height: 11px; width: 11px; background-position: -20px -60px; background-color: transparent; } </style> <script type="text/javascript"> YAHOO.namespace("EGP"); YAHOO.EGP.LayoutResizable = function() { var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, layout = null, resize = null; return{ init: function() { // Panel(大枠)の作成 var panel = new YAHOO.widget.Panel('demo', { draggable: true, close: false, autofillheight: "body", // default value, specified here to highlight its use in the example underlay: 'none', width: '500px', xy: [100, 100] }); panel.setHeader('Test Panel'); // bodyに大枠を分割してLayoutするためのElementをセットする。 panel.setBody('<div id="layout"></div>'); // 大枠のPanelがレンダリングされる前のイベントとして、レイアウト構築を仕込む。 panel.beforeRenderEvent.subscribe(function() { // 上で追加したlayoutエレメントが利用可能になるまで待つ Event.onAvailable('layout', function() { layout = new YAHOO.widget.Layout('layout', { height: 400, // 大枠の幅は500pixなので、padding:20pxと同じことになる(※) width: 480, // Yahoo.widget.LayoutUnitになる。 units: [ // Topのレイアウト。 gutter(溝)は周囲2pix { position: 'top', height: 25, resize: false, body: 'Top', gutter: '2' }, // Leftのレイアウト { position: 'left', width: 150, // resize可能 resize: true, body: 'Left', // gutter の指定は 't r b l'。rは引っ張るので大きめ。 gutter: '0 5 0 2', // resizeする際の制限値 minWidth: 150, maxWidth: 300 }, // Bottomのレイアウト { position: 'bottom', height: 25, body: 'Bottom', gutter: '2' }, // Centerのレイアウト { position: 'center', body: 'Center Unit', gutter: '0 2 0 0' } ] }); // まず、レイアウトをレンダリングする。 layout.render(); }); }); // Layoutの次にPanelをレンダリングする。 panel.render(); // Resizeで修飾する。 resize = new YAHOO.util.Resize('demo', { handles: ['br'], autoRatio: true, status: false, minWidth: 380, minHeight: 400 }); // resizeのresizeイベントのタイミングでレイアウトを変更する。 resize.on('resize', function(args) { var panelHeight = args.height, // 上※ padding = 20; //Hack to trick IE into behaving Dom.setStyle('layout', 'display', 'none'); // this は Panel this.cfg.setProperty("height", panelHeight + 'px'); // おまじない。 layout.set('height', this.body.offsetHeight - padding); layout.set('width', this.body.offsetWidth - padding); // 遊び var wkLu = layout.getUnitByPosition('center'); wkLu.set('body','Resizeされました。'); //Hack to trick IE into behaving Dom.setStyle('layout', 'display', 'block'); // Layoutをresizeする。 layout.resize(); }, panel, true); } }; }(); //DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.LayoutResizable.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.LayoutResizable, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </HEAD> <BODY class="yui-skin-sam"> <div id="demo"></div> </BODY> </HTML>