<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
   <channel>
      <title>mojalog labs ExtJS まとめ</title>
      <link>http://wiki.mojalog.com/extjs/</link>
      <description>
ExtJSのまとめページです
mojalog(メインブログ)
</description>
      <language>ja</language>
      <copyright>Copyright 2008</copyright>
      <lastBuildDate>Thu, 11 Dec 2008 22:45:25 +0900</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>ExtJSでAIRやってみた</title>
         <description><![CDATA[<div class="lh">
<a href="http://mojalog.com/images/ExtGridAir.png"><img class="gt" alt="ExtGridAir.png" src="http://mojalog.com/images/ExtGridAir-thumb.png" width="228" height="159" /></a>
ExtJSのエントリは<a href="http://wiki.mojalog.com/extjs/">こちら</a>にまとめてあります<br /><br />
<a href="http://extjs.com/products/extjs/download.php">ダウンロードページ</a>より、アーカイブ(Ext JS 2.2 SDK)をダウンロードして解凍してください。20081211時点のバージョンは ext-2.2 です。<br />
今日は、<a href="http://extjs.com/blog/2008/02/24/tasks2/">ExtJSのAIRアプリケーション</a>を解説してみたいと思います。<br />
最近作った<a href="http://mojalog.com/2008/11/flexsdkair.html">やる夫AIR</a>はHTML１本だけのコンテンツだったのでflexSDKのadtコマンドでパッケージを簡単に作れましたが、ExtJSはスクリプトもスタイルもイメージファイルもたくさんあるので、AIRパッケージを作るのに苦労しそうなので今回はaptanaを使っています。<br /><br />
基本的には、普通にHTMLとExtJSでアプリケーションを作っていって、AIR化するだけなのですが本家のサンプルを見るとHTMLは以下のようにほとんど書いていなかったのでこれを真似して作ってみます。<br />
<h3 class="tpc">main.html</h3>
<pre>
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;ExtGridAIR&lt;/title&gt;
	&lt;link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css" /&gt;
	&lt;link rel="stylesheet" type="text/css" href="lib/ext/air/resources/ext-air.css" /&gt;
	&lt;script type="text/javascript" src="lib/air/AIRAliases.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="lib/ext/ext-all.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="lib/ext/air/ext-air.js"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" src="main.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
見るとスタイルシートにext-air.cssを追加して、さらにスクリプトにAIRAliases.jsとext-air.jsが使われています。main.jsは以下のとおりになります。<br />
AIRアプリを作る場合は、Ext.air.NativeWindowを使ってウィンドウを構築するようです。さらにViewPortでレイアウトを組むというやり方です。たぶんmain.htmlのエレメントに直接gridやtreeなどをレンダリングしても大丈夫だと思います。が、non-application Sandboxのhtmlをiframeで組んであげる必要が出てきたりします。このsandboxの話は八角研究所の<a href="http://www.hakkaku.net/articles/20080327-178">エントリ</a>に詳しく載っています
<h3 class="tpc">main.js</h3>
<pre>
Ext.onReady( function(){
	(
		new Ext.air.NativeWindow({
			id: 'mainWindow',
			instance: window.nativeWindow,
			width : 316,
			height : 150
		})
	).show();

	new Ext.Viewport({
	    layout:'fit',
	    items: new Ext.grid.GridPanel({
	        store: new Ext.data.SimpleStore({
		        fields: [{ name: 'a' },{ name: 'b' }],
		        data:[[ 'hoge', 1 ],[ 'moge', 2 ],[ 'fuga', 3 ]]
		    }),
	        cm: new Ext.grid.ColumnModel([
		        { id : "gridid", header: "title", sortable: true, dataIndex: 'a' },
		        { header: "number", sortable: true, dataIndex: 'b' }
		    ]),
	        title:'simple-grid',
	        stripeRows:true,
	        view: new Ext.grid.GridView({
	            forceFit:true
	        })		
	    })
	});
});
</pre>
こんなかんじでViewPortをつかってあげると、デスクトップアプリケーションぽく綺麗にまとまりますね。今回はgirdを１個だけ載せているのでExt.ViewPortのlayoutを'fit'で使っていますが、absolute, accordion, anchor, border, card, column, fit, form, tableなんかで組めるようです。詳しくは<a href="http://extjs.com/deploy/dev/docs/?class=Ext.Container">Ext.Container</a>のlayoutConfigを見てください。
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;application xmlns="http://ns.adobe.com/air/application/1.5"&gt;
	&lt;id&gt;com.adobe.example.extGrid&lt;/id&gt;
	&lt;filename&gt;extGrid&lt;/filename&gt;
	&lt;name&gt;extGrid&lt;/name&gt;
	&lt;version&gt;2.0&lt;/version&gt;
	&lt;description&gt;&lt;/description&gt;
	&lt;copyright&gt;&lt;/copyright&gt;
	&lt;initialWindow&gt;
		&lt;content&gt;extGrid.html&lt;/content&gt;
		&lt;title/&gt;
		&lt;systemChrome&gt;standard&lt;/systemChrome&gt;
		&lt;transparent&gt;false&lt;/transparent&gt;
		&lt;visible&gt;false&lt;/visible&gt;
		&lt;minimizable&gt;true&lt;/minimizable&gt;
		&lt;maximizable&gt;true&lt;/maximizable&gt;
		&lt;resizable&gt;true&lt;/resizable&gt;
	&lt;/initialWindow&gt;
	&lt;icon&gt;
		&lt;image16x16&gt;icons/AIRApp_16.png&lt;/image16x16&gt;
		&lt;image32x32&gt;icons/AIRApp_32.png&lt;/image32x32&gt;
		&lt;image48x48&gt;icons/AIRApp_48.png&lt;/image48x48&gt;
		&lt;image128x128&gt;icons/AIRApp_128.png&lt;/image128x128&gt;
	&lt;/icon&gt;
		&lt;fileTypes&gt;
	&lt;/fileTypes&gt;
&lt;/application&gt;
</pre>
<h3 class="tpc">AIRパッケージ化</h3>
<a href="http://mojalog.com/images/airadt.png"><img class="gt" alt="airadt.png" src="http://mojalog.com/images/airadt-thumb.png" width="228" height="166" /></a>
export adobe air packageをクリックします。AdobeAirPackageExporterがあがるのでnextを押してウィザードに従います。<br /><br />
certificateが空の場合は、ConfigureCertificateという青地の箇所をクリックして証明書を作成します。証明書の作成は、以下のスクリーンショットのように証明書名とパスワード、パブリッシャを設定するだけで作られます。<br />
作られた証明書のパスワードをポップアップ元のDigitalSigning画面で設定してnextを押すことでパッケージに含まれるコンテンツを選べます。<br /><br />
<a href="http://mojalog.com/images/cert.png"><img class="gt" alt="cert.png" src="http://mojalog.com/images/cert-thumb.png" width="228" height="230" /></a>
選ぶコンテンツは、全部入れれば間違いはありませんが、かなり冗長なファイルも含まれます。ExtJSで利用しているスタイルや画像などを選んでfinishを押すとairパッケージが作成されます。airパッケージをインストールして試してみましょう！
</div>
]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/12/extjsair.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/12/extjsair.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">ColumnModel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">GridPanel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">GridView</category>
                  <category domain="http://www.sixapart.com/ns/types#category">NativeWindow</category>
                  <category domain="http://www.sixapart.com/ns/types#category">SimpleStore</category>
                  <category domain="http://www.sixapart.com/ns/types#category">air</category>
                  <category domain="http://www.sixapart.com/ns/types#category">data</category>
                  <category domain="http://www.sixapart.com/ns/types#category">grid</category>
        
        
         <pubDate>Thu, 11 Dec 2008 22:45:25 +0900</pubDate>
      </item>
            <item>
         <title>Ext.DomQueryの基本的な使い方#1</title>
         <description><![CDATA[<div class="lh">
<a href="http://mojalog.com/images/domQuery.PNG"><img class="gt" alt="domQuery.PNG" src="http://mojalog.com/images/domQuery-thumb.PNG" width="228" height="120" /></a>
ExtJSのDOMセレクタはExt.query()というメソッドで使えるようになっています。Ext.query()メソッドは2つのパラメータを持ち、第1パラメータに取得したい場所を書式に基づいた文字列で与えて、第2パラメータにエレメントのidを渡します。第2パラメータは省略可能ですのでこれを使わずとも、第1パラメータだけでかなり柔軟な取得ができます。また、Ext.query()メソッドはExt.DomQuery.select()のエイリアス(shorthand)ですので、どちらを使ってもいいようです。<br />
<a href="http://wiki.mojalog.com/extjs/statics/ExtPack/simple-domQuery/index.html">動作サンプル</a>
<h3 class="tpc">DomQueryで探索するサンプルHTML</h3>
<pre>
&lt;html&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id="fuga" class="piyo"&gt;
   ここはdiv#fuga.piyoです。
   &lt;span class="fuga"&gt;
    ここはspan.fugaです。div#fuga.piyoの中に配置されています。
   &lt;/span&gt;
   &lt;a href="#" class="piyo"&gt;
    ここはa.piyoです。span.fugaと同じ高さで、その直後に配置されています
   &lt;/a&gt;
  &lt;/div&gt;
  &lt;div id="piyo" class="fuga"&gt;
   ここはdiv#piyo.fugaです。
   &lt;a href="#"&gt;
    ここはaです。div#piyo.fuga直下に配置されています。
   &lt;/a&gt;
   &lt;p&gt;
    ここはpです。div#piyo.fugaの中に配置されています。
    &lt;a href="#"&gt;
     ここはaです。div#piyo.fuga内ですがその直下にはありません。
    &lt;/a&gt;
    &lt;a href="#"&gt;
     ここはaです。div#piyo.fuga内ですがその直下にはありません。
    &lt;/a&gt;
   &lt;/p&gt;
   &lt;span class="fuga"&gt;
    ここはspan.fugaです。div#piyo.fugaの中に配置されています。
   &lt;/span&gt;
   &lt;p class="piyo"&gt;
    ここはp.piyoです。span.fugaと同じ高さでその直後に配置されています
   &lt;/p&gt;
  &lt;/div&gt;
  &lt;p class="piyo"&gt;
   ここはp.piyoです。div#piyo.fugaと同じ高さでその直後に配置されています
  &lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<h3 class="tpc">Elementセレクタ</h3>
Element(要素)とは？を先に説明しておきますと
<pre>
&lt;a href="#" &gt;リンク&lt;/a&gt;
</pre>
このタグ開始～タグ終了セットをElementと呼んでいます。よくタグとエレメントがごっちゃになったりしますが、タグは開始タグも終了タグもタグですので、エレメントより分解された言い方ですね。<a href="http://www.atmarkit.co.jp/fxml/askxmlexpert/015tagelement/15tagelement.html">『タグと要素（エレメント）の違いを説明して』</a>がわかりやすいです。<br /><br />
で、ちょっと余談ですが、じゃあエレメントとノードの違いって何よ？って疑問があって、C#でパタパタ実装しているとXmlElementとXmlNodeなんてのを使うことになるんですが、XmlElementとXmlNodeというクラスの扱いだけで言うと、<a href="http://bytes.com/forum/thread172463.html">「りんご:XmlElement」と「フルーツ:XmlNode」くらいに覚えておけばいいみたい</a>です。XmlNodeのほうが抽象化されてるってか一般化されてるって言うかそういう風に腹に落としました。ふーん。<br />
で、javascriptのgetElementByIdだとエレメントが返るぞと言われてる気がするのですが、selectSingleNodeっていわれるとノードだと言われる。後者はXPathで指定するので手続きは違うとして、返って来たモノはなんだろね。呼び方の違い？まぁタイプセーフではないのでごちゃごちゃいわないことにします。（余談なげー）<br /><br />
ということでElementセレクタの説明です。
<pre>
    Ext.query( "span" ); // [ span.fuga, span.fuga ]
</pre>
このクエリは[ span.fuga, span.fuga ]という２つの要素からなる配列を返します。全ドキュメントからspanエレメントに合致するものを拾ってきます。
<pre>
    Ext.query( "span", "fuga" ); // [ span.fuga ]
</pre>
このクエリは[ span.fuga ]という1つの要素からなる配列を返します。サンプルHTMLにはspanエレメントが2つありますが、idが"fuga"からなるdiv内のspanを指定していますので、前者のほうが返ります。<br /><br />

次は書式付の第1パラメータで取得する方法です。<br />

<h3 class="tpc">id指定:"#"</h3>
idを指定してエレメントを拾いたい場合は、"#"をプレフィックスとして与えてあげます。
<pre>
    Ext.query( "#piyo" ); // [ div#piyo.fuga ]
</pre>
このクエリは、idが"piyo"でclassが"fuga"のdivが返ります。2つあるdivのうち後者のほうが返ります。<br />

<h3 class="tpc">class指定:"."</h3>
classを指定してエレメントを拾いたい場合は、"."をプレフィックスとして与えてあげます。
<pre>
    Ext.query( ".piyo" ); // [ div#fuga.piyo, a.piyo, p.piyo, p.piyo ]
</pre>
このクエリは、classが"piyo"のエレメントを返します。

<h3 class="tpc">全指定:"*"</h3>
全ての要素を拾いたい場合は"*"を指定することで拾えます。
<pre>
    Ext.query( "*" ); // [ html, head, meta, body, div#fuga.piyo, span.fuga, a.piyo, div#piyo.fuga, a, p, a, a, span.fuga, p.piyo, p.piyo ]
</pre>

<h3 class="tpc">子エレメント指定:" "(スペース)</h3>
あるエレメント内で指定した全ての子エレメントを拾う場合は、" "（スペース）を間にはさんで与えてあげます。
<pre>
    Ext.query( "div p" ); // [ p, p.piyo ]
</pre>
このクエリは親にdivエレメントを持つ p を返します。

<pre>
    Ext.query( "div span" ); // [ span.fuga, span.fuga ]
</pre>
このクエリは親にdivエレメントを持つspanエレメントを返すので、２つのspanが返ります。

<h3 class="tpc">直下の子エレメント指定:">"または"/"</h3>
あるエレメント内の直下の子エレメントを指定して拾う場合は">"または"/"を間にはさんで与えてあげます。
<pre>
    Ext.query( "div/a" ); // [ a.piyo, a ]
</pre>
div#fuga.piyo直下のa.piyoエレメントとdiv#piyo.fuga直下のaエレメントを返します。pエレメント内の２つのaエレメントは直下にないので返しません。

<h3 class="tpc">直後の同じ高さ(兄弟要素)のエレメント指定:"+"</h3>
あるエレメントと同じ高さにいるエレメントで、その直後にいるエレメントを拾う場合は"+"を間にはさんで与えてあげます。一応挙動も確認したのですが（あまり使いそうにないなーと思いながら）、ちょっと自信ないです。
<pre>
    Ext.query( ".fuga+.piyo" ); // [ a.piyo, p.piyo, p.piyo ]
</pre>
ちょっとわかりにくいですが、class="fuga"のエレメントと同じ高さにいて、その直後でclass="piyo"のエレメントを返しています。

<h3 class="tpc">後方の同じ高さ（兄弟要素）のエレメント指定:"+"</h3>
あるエレメントと同じ高さにいるエレメントで、その後方にいるエレメントを拾う場合は"~"を間にはさんで与えてあげます。
<pre>
    Ext.query( "a~span" ); // [ span.fuga ]
</pre>
これもちょっとわかりにくいですが、aと同じ高さにいるspan.fugaを拾っています。"+"と違い、拾ってきたspan.fugaはaの直後にいません。これも一応挙動も確認したのですが、かなり自信ないです。<br /><br />
ほかにもアトリビュートから指定してエレメントを取得したり出来るのですがまた次回に紹介します。<br /><br />
via : <a href="http://extjs.com/learn/Tutorial:DomQuery_v1.1_Basics">DomQueryのチュートリアル</a><br />
via : <a href="http://extjs.com/deploy/dev/docs/?class=Ext.DomQuery">APIDoc</a><br />
</div>]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/06/extdomquery1.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/06/extdomquery1.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">DomQuery</category>
        
                  <category domain="http://www.sixapart.com/ns/types#tag">query</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">select</category>
        
         <pubDate>Thu, 26 Jun 2008 19:25:34 +0900</pubDate>
      </item>
            <item>
         <title>Ext.grid.EditorGridPanelの使い方</title>
         <description><![CDATA[<div class="lh">
<a href="http://mojalog.com/images/editorgridsumple.PNG"><img class="gt" alt="editorgridsumple.PNG" src="http://mojalog.com/images/editorgridsumple-thumb.PNG" width="228" height="188" /></a>
ExtJSのエントリは<a href="http://wiki.mojalog.com/extjs/">こちら</a>にまとめてあります<br /><br />
<a href="http://extjs.com/products/extjs/download.php">ダウンロードページ</a>より、アーカイブ(Ext JS 2.1 SDK)をダウンロードして解凍してください。20080623時点のバージョンは ext-2.1 です。<br />
今日は、<a href="http://extjs.com/deploy/dev/examples/grid/edit-grid.html">ExtJSのEditor Grid Example</a>を解説してみたいと思います。<br />
ワタシが作ってみたEditorGridは、上記リンクのサンプルのようにプルダウンやチェックボックスは装備しておりません。EditorGridそのものは非常にシンプルに作った代わりに、編集されたセルを検出するボタンを追加してみました。Gridをフォームとしてどこかへポストしたいといった時に、有効かもしれません。あと、いきなりEditorGridPanelとか言われても・・と言う方には<a href="http://mojalog.com/2008/02/extjs20_1.html">ここ</a>にExtJSのチュートリアルを簡単にまとめてみました。<br />
まず、以下に今回解説するEditorGridPanelのソースを全て載せてみましたので、この実装方法とコンフィグを解説します。<br />
<a href="http://wiki.mojalog.com/extjs/statics/ExtPack/simple-editableGrid/index.html">動作サンプル</a>とサンプルソース
<pre>
Ext.onReady( function(){
    var id = 0;
    var reader = new Ext.data.ArrayReader( { id: 0 }, [
          { name: 'str', mapping: 1 },
       { name: 'num', mapping: 2 }
    ]);
    var store = new Ext.data.Store({
        reader: reader,
        data:[ 
            [ id++, 'hoge', 1 ],
            [ id++, 'moge', 2 ],
            [ id++, 'fuga', 3 ]
        ]
    });
    
    var clmnModel = new Ext.grid.ColumnModel([
        { header: "Title", width: 200, sortable: true, dataIndex: 'str', editor: new Ext.form.TextField() },
        { header: "Number", width: 100, sortable: true, dataIndex: 'num', editor: new Ext.form.NumberField() }
    ]);

    var grid = new Ext.grid.EditorGridPanel({
        store:store,
        colModel:clmnModel,
        renderTo:'renderTarget',
        title:'simple-editorgrid',
        stripeRows:true,
        height:200,
        width:320,
        frame:true,
        clicksToEdit:1,
        tbar:[
        { text: 'touch', handler:function(){
            grid.getStore().each( function( targetObj ){
                var touchField = targetObj.getChanges();
                for( name in touchField ){
                    alert(
                        "index : [ " + targetObj.id + " ]\n" + 
                        "fieldName : [ " + name + " ]\n" +
                        "value : [ " + touchField[ name ] +" ]\n" 
                    );
                }
                targetObj.commit();
            });
        }}]
    });
});
</pre>
<h3>【Ext.grid.EditorGridPanelの解説】</h3>
それではEditorGridPanelを見ていきたいと思います。普通の<a href="http://wiki.mojalog.com/extjs/2008/04/extjs_extgridgridpanel.html">GridPanel</a>の使い方はこちらを参照ください。<br />
<h3 class="tpc">EditorGridPanel</h3>
<pre>
    var grid = new Ext.grid.EditorGridPanel({
</pre>
という箇所がエディターグリッドパネルそのものになります。GridPanelと違うところはコンフィグオプションの   <pre>
     clicksToEdit:1,
</pre>
という個所と、カラムモデルにeditorというコンフィグオプションを適用しているところだけです。<br />
clicksToEditのAPIDocをみると
<pre>
The number of clicks on a cell required to display the cell's editor (defaults to 2)
</pre>
とありまして、セルが編集可能になるクリック数みたいなことが書いてありますが、なんかあんまり関係ないような気がします。（値がいくつでもダブルクリックで編集可能になった）このコンフィグオプションがなくても編集可能になりました。<br />
で、実際に編集可能にするためにはカラムモデルにeditorという設定をしなければならないようです。
<pre>
    var clmnModel = new Ext.grid.ColumnModel([{ 
        header: "title", 
        width: 200, 
        dataIndex: 'str', 
        editor: new Ext.form.TextField()  // <-コレ
    },
</pre>
ここのeditorにformパッケージのクラスでnewしてあげると、編集時にそのクラスで動くようになります。例えばComboBoxでnewしてあげるとプルダウンできるようになります。（適宜ComboBoxのコンフィグは必要になります）<br />
これでEditorGridPanelが完成しました。<br /><br />
<h3 class="tpc">編集セルの特定</h3>
冒頭で記述しましたようにEditorGridの編集個所が特定できないと、どこかのページに値をポストしようにも出来ませんので、この解説をしたいと思います。ポストの前にとりあえず、gridのデータをどこかに渡すためには、
<ol>
<li>どのレコードの、</li>
<li>どのフィールドで</li>
<li>どんな値に</li>
</ol>
変更されたのか？という情報は必要になってきます。今回はその情報を取り出すだけで、データをポストするところまで組んでいません。
<pre>
tbar:[
{ text: 'touch', handler:function(){
    grid.getStore().each( function( targetObj ){
        var touchField = targetObj.getChanges();
        for( name in touchField ){
            alert(
                "index : [ " + targetObj.id + " ]\n" + 
                "fieldName : [ " + name + " ]\n" +
                "value : [ " + touchField[ name ] +" ]\n" 
            );
        }
        targetObj.commit();
    });
}}]
</pre>
というわけで、実装の解説を進めていきますが、tbarというコンフィグオプションは前回のTreePanelのときに解説しましたツールバーです。今回はツールバーにtouchというボタンを与えてあげて、そこにハンドラとして編集セルを見るメソッドを用意しました。<br />
まず、gridが用意しているgetStore()メソッドを呼び出して、データストアを取得します。次に返ってきたstoreで持っているeachメソッドを使って、レコード単位に全てのオブジェクトを拾いあげます。<br />
<pre>
grid.getStore().each( function( targetObj ){
</pre>
パラメータのtargetObjはExt.data.Recordのオブジェクトが入ってきますので、このオブジェクトに変更があったかどうかを聞きます。
<pre>
var touchField = targetObj.getChanges();
</pre>
getChanges()メソッドはAPIDocに以下のような説明がありました。
<pre>
Gets a hash of only the fields that have been modified since this Record was created or commited.
</pre>
「レコードが作られたか、あるいは、コミットされた後に編集されたフィールドをハッシュ（オブジェクト）で返すよー」と言っているみたいです。なるほど。便利。編集されてなければ返されたオブジェクトはプロパティを持たないようです。ですので、for～inで調べてみました。これで、編集されたフィールドと値を取得することが出来ます。<br />
ちなみに、targetObjの実態はExt.data.Recordですので、idを持っていて自分がどのレコードかを知っているのですが、今回の実装はストアを作るときに明示的にidを振っています。
<pre>
    var id = 0;
    var reader = new Ext.data.ArrayReader( { id: 0 }, [
          { name: 'str', mapping: 1 },
       { name: 'num', mapping: 2 }
    ]);
    var store = new Ext.data.Store({
        reader: reader,
        data:[ 
            [ id++, 'hoge', 1 ],
            [ id++, 'moge', 2 ],
            [ id++, 'fuga', 3 ]
        ]
    });
</pre>
前回作ったGridはSimpleStoreを使って簡単にデータストアを構築しましたが、今回はレコードのidも見たかったのでちょっと構築方法が違います。<br />
ArrayReaderのコンストラクタの第1パラメータで、「レコードのidは扱うデータ（配列）の0番目ですよ」と明示的に指定しています。さらに第2引数でレコードのnameと扱うデータ（配列）の何番目かをmappingで指定しています。マッピングをずらすと、grid内にidを表示することも出来ます。idの生成やその一意性は実装依存ですが、自ら生成しなくとも勝手に割り当てられるようです。ただ、一意に割り当ててあげないとバインド出来ませんね。<br />
これでソートしてレコードの位置が変わってもidでバインドできるようになりました。ちなみにレコードが上から何番目か？ってのを知りたい場合は、
<pre>
grid.getStore().indexOf( targetObj )
</pre>
というstoreのindexOfでそのレコードが上から何番目に位置するのか聞けます。<br />
で、最後にtargetObj.commit();で編集をコミットしてあげています。<br /><br />
というわけで、EditorGridPanelの解説をしてみました。ワタシの理解を多分に含めておりますので、誤った情報である可能性がありますのでご注意ください。
</div>
]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/06/extgrideditorgridpanel.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/06/extgrideditorgridpanel.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">ArrayReader</category>
                  <category domain="http://www.sixapart.com/ns/types#category">ColumnModel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">EditorGridPanel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">Store</category>
                  <category domain="http://www.sixapart.com/ns/types#category">Toolbar</category>
                  <category domain="http://www.sixapart.com/ns/types#category">data</category>
                  <category domain="http://www.sixapart.com/ns/types#category">grid</category>
        
                  <category domain="http://www.sixapart.com/ns/types#tag">commit</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">each</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">getChanges</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">getStore</category>
        
         <pubDate>Mon, 23 Jun 2008 19:35:14 +0900</pubDate>
      </item>
            <item>
         <title>Ext.tree.TreePanelの使い方</title>
         <description><![CDATA[<div class="lh">
<a href="http://mojalog.com/images/simple-tree.PNG"><img class="gt" alt="simple-tree.PNG" src="http://mojalog.com/images/simple-tree-thumb.PNG" width="228" height="144" /></a>
<a href="http://extjs.com/products/extjs/download.php">ダウンロードページ</a>より、アーカイブ(Ext JS 2.1 SDK)をダウンロードして解凍してください。20080522時点のバージョンは ext-2.1 です。解凍したら、以下のパスのファイルを開いて見ましょう。
<pre>
【パス】
ext-2.1\examples\tree\reorder.html
</pre>
開いてみると、ツリーのルートノードが表示されているだけでクリックしても以下のノードが見えませんね。これはサーバサイトスクリプトを参照しに行っていて、その参照先がローカルのget-nodes.phpにあるためです。ですので<a href="http://extjs.com/deploy/dev/examples/tree/reorder.html">直接ExtJSのTreePanelサンプル</a>を見てみます。<br />
このウィジェットがTreePanelと呼ばれるものです。サンプルでは（ローカルパスで言う）ext-2.1\source以下のディレクトリ構造がツリーパネルで表現されていて、ディレクトリをクリックすると以下のノード一覧をロードしてずらっと表示する仕組みになっています。今日はこのTreePanelの基本的な実装を解説してみたいと思いますが、サーバサイドスクリプト抜きで静的なツリー構造をサンプルとして使いたいと思います。あと、いきなりTreePanelとか言われても・・と言う方には<a href="http://mojalog.com/2008/02/extjs20_1.html">ここ</a>にExtJSのチュートリアルを簡単にまとめてみました。<br />
まず、以下に今回解説するTreePanelのソースを全て載せてみましたので、この実装方法とコンフィグを解説します。<br />
<a href="http://wiki.mojalog.com/extjs/statics/ExtPack/simple-tree/index.html">動作サンプル</a>とサンプルソース
<pre>
Ext.onReady( function(){
    var idx = 0;
    var root  = createNode( idx++, "root", false, false ); // branch unDraggable
    var node1 = createNode( idx++, "hoge", true, true );   // leaf draggable
    var node2 = createNode( idx++, "moge", false, true );  // branch draggable
    var node3 = createNode( idx++, "piyo", true, false );  // leaf unDraggable

    root.appendChild( node1 );
    root.appendChild( node2 );
    node2.appendChild( node3 );

    var tree = new Ext.tree.TreePanel({
        title:'SimpleTree',
        width:300,
        useArrows:true,
        enableDD:true,
        root:root,
        renderTo:'renderTarget',
        tbar:[ 
            { text: 'OpenAll', handler:function(){ tree.expandAll(); } },'-',
            { text: 'CloseAll', handler:function(){ tree.collapseAll(); } },'-',
            { text: 'AddNode-Recursive', handler:function(){ 
                function recursiveNode( pNode ){
                    alert( 'this->' + this.toString() + 
                           '\ndepth:' + pNode.getDepth() + 
                           '\ntext:' + pNode.text + 
                           '\nid:' + pNode.id );
                    pNode.eachChild( recursiveNode );
                    if( !pNode.isLeaf() ){
                        var setIdx = idx++;
                        pNode.appendChild( createNode( setIdx, 'add-' + setIdx, false, true ) );
                    }
                };
                root.eachChild( recursiveNode );
                tree.expandAll();
            }}
        ]
    });
    root.expand();
//    node2はデフォルトクローズの状態
//    node2.expand();
    function createNode( id, text, isLeaf, isDrag ){
        return new Ext.tree.TreeNode({
            draggable:isDrag,
            id:id,
            text:text,
            leaf:isLeaf
        });
    }
});
</pre>
<h3>【Ext.tree.TreePanelの解説】</h3>
それではTreePanelを見ていきたいと思います。
<pre>
    var tree = new Ext.tree.TreePanel({
</pre>
という箇所がツリーパネルそのものになります。ツリーを表現する以上、ノードとなるデータがひとつ以上必要になってきて、そのデータコンテンツはTreeNodeというクラスインスタンスを使うことになります。GridPanelやDataViewで使ったデータストアとは違ってくるようです。<br />
ドキュメントには、以下のようにTreePanelがレンダリングされる前までに、コンフィグオプションのrootに有効なノードが入っていてくれとあります。コンフィグオプションのrootに直接突っ込んでもいいし、rootに対するセッターであるsetRootNode()メソッドでもよいとのことです。<br />
<pre>
A TreePanel must have a root node before it is rendered. This may either be specified using the root config option, or using the setRootNode method.
</pre>
それではツリーパネルのコンフィグオプションを見てみます。<br />
といっても、先述のとおり重要なコンフィグオプションはrootだけです。ここには次に述べるrootというTreeNodeのインスタンスを設定してあげてきます。<br />
enableDD:true,は、ノードのドラッグアンドドロップが出来るかどうかです。TreeNodeインスタンスを作成するときにノード１つ１つに対してドラッグアンドドロップの設定が出来るのですが、TreePanelでfalseにすると全てのノードに対してドラッグアンドドロップが無効になります。<br />
useArrows:true,は、表示系のコンフィグオプションで、これがfalseだとwindowsVista以前のエクスプローラのような[+]とか[-]のドリル表示になります。trueだとアロー型のドリル表示になります。<br />
<pre>
    var tree = new Ext.tree.TreePanel({
        title:'SimpleTree',
        width:300,
        useArrows:true,
        enableDD:true,
        root:root,
        renderTo:'renderTarget',
</pre>
続いてtbarというコンフィグオプションを設定していますが、この部分は最後に記述したいと思います。<br /><br />
<h3>【TreeNodeの解説】</h3>
次は、実際のデータであるTreeNodeの部分を見ていきます。
<pre>
    function createNode( id, text, isLeaf, isDrag ){
        return new Ext.tree.TreeNode({
            draggable:isDrag,
            id:id,
            text:text,
            leaf:isLeaf
        });
    }
</pre>
メソッドcreateNodeはワタシが勝手に作ったメソッドです。このメソッドはパラメータに従ってTreeNodeをnewして返すだけのものですので特に細かい解説はいらないかと思います。<br /><br />
ではTreeNodeのコンフィグオプションを見ていきます。まず、draggable:isDrag,はそのノードがドラッグアンドドロップできるかどうかを表していて、今回はパラメータに依存するつくりになっていて、trueでそのノードがドラッグアンドドロップできるようになり、falseで出来なくなります。<br />
続いてidはそのツリー構造内のidを表すものです。明示的に設定しなくても勝手に振ってくれるようですが、ツリー構造内で一意にノードを特定したりすることがあるかと思いますので実装者が設定してあげたほうがいいと思います。ちなみに一意でなくとも動くには動くようです。<br />
textは、そのままそのノードのテキスト表示部分です。このテキスト部分にはhrefというコンフィグオプションを加えることによってアンカーリンクを貼ることが出来ます。さらにhrefTargetでターゲットフレームの指定も出来ます。<br />
最後のleafは、そのノードがリーフ（末端）であるかどうかです。leaf:trueですと、そのノード以下に子ノードを与えることが出来ません。leaf:falseだとブランチ（枝）を表していて子ノードを追加することが出来ます。<br /><br />
<h3>【Toolbarの解説】</h3>
最後にTreePanelの残りのコンフィグオプション、tbarについて解説したいと思います。tbarというコンフィグオプションはExt.Panelクラスを継承しているクラスであれば使えるコンフィグオプションです。～Panelという以下のパネル一覧であれば使えます。また、tbarはパネル上部にレンダリングされ、bbarはパネルの下部にレンダリングされます。<br /><br />
＜パネル一覧＞
<pre>
EditorGridPanel Ext.grid.EditorGridPanel
FormPanel Ext.form.FormPanel
GridPanel Ext.grid.GridPanel
Panel Ext.Panel
TabPanel Ext.TabPanel
TreePanel Ext.tree.TreePanel
</pre>
このtbarやbbarの実体はExt.Toolbarなのですが、このコンストラクタが以下のように追加したいボタンオブジェクトのコンフィグを配列としてパラメータに与えることが出来るので非常に分かりやすいです。
<pre>
tbar:[ 
    { text: 'OpenAll', handler:function(){ tree.expandAll(); } },'-',
    { text: 'CloseAll', handler:function(){ tree.collapseAll(); } },'-',
    { text: 'AddNode-Recursive', handler:function(){ 
        function recursiveNode( pNode ){
            alert( 'depth:' + pNode.getDepth() + '\ntext:' + pNode.text + '\nid:' + pNode.id );
            pNode.eachChild( recursiveNode );
            if( !pNode.isLeaf() ){
                var setIdx = idx++;
                pNode.appendChild( createNode( setIdx, 'add-' + setIdx, false, true ) );
            }
        };
        root.eachChild( recursiveNode );
        tree.expandAll();
    }}
]
</pre>
もうちょっと詳しく説明すると、上記のようにオブジェクトを配列で渡した場合、その１つ１つはExt.Toolbar.Buttonオブジェクトを表しています。→<a href="http://extjs.com/deploy/dev/docs/?class=Ext.Toolbar.Button">APIドキュメント</a><br />
Ext.Toolbar.Buttonのコンフィグオプションには、上記のようにtextとhandlerをあたえれば、その表示と挙動を実装することが出来ます。コンフィグオプションにxtypeと言うものがあるのですが、これを与えないで置くと、デフォルトでtbbuttonでレンダリングされ、xtype:'tbsplit'とするとボタンの横に▼が表示されてメニュードロップの表示が出来るようになります。また、ボタンとボタンの間にセパレータ（｜←こんなの）を表示させたい場合は、配列の要素として文字列の'-'を与えます。以下にToolbarコンポーネントのxtype一覧を記します<br /><br />
＜Toolbar components：xtype一覧＞
<pre>
Toolbar components
---------------------------------------
toolbar          Ext.Toolbar
tbbutton         Ext.Toolbar.Button
tbfill           Ext.Toolbar.Fill
tbitem           Ext.Toolbar.Item
tbseparator      Ext.Toolbar.Separator
tbspacer         Ext.Toolbar.Spacer
tbsplit          Ext.Toolbar.SplitButton
tbtext           Ext.Toolbar.TextItem
</pre>
実装の解説に戻りますが、handlerの内容は、上からノードヒエラルキーの全体オープンとクローズです。tree.expandAll() / tree.collapseAll()を使っています。<br />
最後のAddNode-Recursiveと言うボタンは、ハンドラにちょこちょこ実装が入っていますが、内容はルートノードから全てのノードをアラートして、そのノードがブランチである場合、直下に１つブランチを追加していく実装となっています。
<pre>
    { text: 'AddNode-Recursive', handler:function(){ 
        function recursiveNode( pNode ){ /* ... */ };
        root.eachChild( recursiveNode );
        tree.expandAll();
    }}
</pre>
途中にrecursiveNodeというメソッドの定義がハンドラの中に入ってきていますのでちょっと分かりにくいですが、recursiveNodeを省いて見ると、このハンドラは<br />
・ルートノードが持つ子ノード毎にrecursiveNodeと言うメソッドを呼んで<br />
・最後にツリーを開くと言う処理だけです。<br />
その"ノード毎に..."というところでeachChildメソッドが出てきましたので最後にTreeNodeに戻って解説します。<br />
<pre>
eachChild( Function fn, [Object scope], [Array args] ) : void
</pre>
このメソッドはTreeNodeのメソッドなのですが、ノードが持つ子ノード分イテレートしてFunction fnを呼び出すというものです。第２引数のスコープは実際に与えるか、与えないとイテレート中のカレントのノードがFunction fnに与えられるみたいです。第３引数の"引数"も同様です。<br />
ですので、function recursiveNode( pNode )の引数pNodeにはイテレート中のカレントノードが与えられてきます。そこから引数のpNodeで、さらにeachChildを呼び出して再帰します。再帰した後、ノードがブランチであれば、さらにブランチを追加すると言う仕組みになっています。<br /><br />
<h3>【余談】</h3>
１．マウスでノードをぐりぐりとドラッグアンドドロップしてみると、ちゃんとDepthが変わってくれます。ツリー構造とデータをそのまま維持しながらどこかにポストしたいとかがあれば、（jsonやXMLに変換する必要があるかもしれませんが）それも可能のようです。<br /><br />
２．今回はノードデータを自前で実装しましたが、Tree.TreeLoaderというデータのローダがあります。とても便利です。<br /><br /><br />
というわけで、TreePanelの解説をしてみました。ワタシの理解を多分に含めておりますので、誤った情報である可能性がありますのでご注意ください。
</div>
]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/05/exttreetreepanel.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/05/exttreetreepanel.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">Toolbar</category>
                  <category domain="http://www.sixapart.com/ns/types#category">TreeNode</category>
                  <category domain="http://www.sixapart.com/ns/types#category">TreePanel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">tree</category>
        
                  <category domain="http://www.sixapart.com/ns/types#tag">Panel</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">eachChild</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">setRootNode</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">xtype</category>
        
         <pubDate>Thu, 22 May 2008 19:51:04 +0900</pubDate>
      </item>
            <item>
         <title>ExtJSをfirebugでデバッグする便利な方法</title>
         <description><![CDATA[<div class="lh">
<table class="gt"><tr><td><a href="http://mojalog.com/images/firebugonextjs01.PNG"><img alt="firebugonextjs01.PNG" src="http://mojalog.com/images/firebugonextjs01-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs02.PNG"><img alt="firebugonextjs02.PNG" src="http://mojalog.com/images/firebugonextjs02-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs03.PNG"><img alt="firebugonextjs03.PNG" src="http://mojalog.com/images/firebugonextjs03-thumb.PNG" width="228" height="159" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs04.PNG"><img alt="firebugonextjs04.PNG" src="http://mojalog.com/images/firebugonextjs04-thumb.PNG" width="228" height="159" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs05.PNG"><img alt="firebugonextjs05.PNG" src="http://mojalog.com/images/firebugonextjs05-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs06.PNG"><img alt="firebugonextjs06.PNG" src="http://mojalog.com/images/firebugonextjs06-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs07.PNG"><img alt="firebugonextjs07.PNG" src="http://mojalog.com/images/firebugonextjs07-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs08.PNG"><img alt="firebugonextjs08.PNG" src="http://mojalog.com/images/firebugonextjs08-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs09.PNG"><img alt="firebugonextjs09.PNG" src="http://mojalog.com/images/firebugonextjs09-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs10.PNG"><img alt="firebugonextjs10.PNG" src="http://mojalog.com/images/firebugonextjs10-thumb.PNG" width="228" height="153" /></a>
</td></tr><tr><td>
<a href="http://mojalog.com/images/firebugonextjs11.PNG"><img alt="firebugonextjs11.PNG" src="http://mojalog.com/images/firebugonextjs11-thumb.PNG" width="228" height="153" /></a>
</td></tr></table>
これまでにExtJSの使い方を何度かポストしていて、日本語のチュートリアルがあることもポストしましたが、チュートリアルのほとんどは英語で書かれています。ので、しっかりと読むには腰をすえなければならず、ちょこちょことtipsなんかを斜め読みしていたのですが、<a href="http://extjs.com/learn/Tutorial:Playing_With_Ext_The_Easy_Way_%28Japanese%29">このページに</a>ExtJSの作りこみやデバッグを飛躍的に向上させる方法が載っていました。<br /><br />
javascriptのデバッグというとFireFoxプラグインの<a href="https://addons.mozilla.org/ja/firefox/addon/1843">firebug</a>を思い浮かべます。そのとおり上記チュートリアルもfirebugを使ったデバッグです。もちろんこのブログで紹介しているExtJS関連のポストもfirebugを使ってデバッグしてはいますが、あまり使い込んでおらず適宜ブレークポイントを置いて変数なんかをウォッチする程度のものでした。知らなかったのはコンソールにスクリプトを直接書いて実行させることが出来るってことです。え・・・それって常識・・・とかドン引きされることかと思いますが、コンソールにスクリプトを直接書いて実行出来るらしいですよ！（同じことを２度言ってみました）（恥ずかしい子！）<br /><br />
恥ずかしい子はどうでもよいのですが、上記ページのチュートリアルを引用してキャプチャをいくつか追加しながらポストしたいと思います。<br />
ココまで読んでいる方なら以下の資材はお持ちかと思いますが一応リンクしておきます。
<ul>
<li><a href="http://www.mozilla-japan.org/products/firefox/">firefox</a><br /></li>
<li><a href="https://addons.mozilla.org/ja/firefox/addon/1843">firebug</a><br /></li>
</ul>
firefoxをインストールしてfirebugを入れたらfirefoxで<a href="http://extjs.com/deploy/dev/docs/">Ext2.1-API Dcumentation</a>を開きます。なぜこのページを開くのかと言いますと理由は単純でExtJSが全てロードされているためです。<br />
開きましたら図のようにfirebugを立ち上げます。<br />
ツール＞Firebug＞Open Firebugで開きます。<br />
次にEnable FirebugをクリックしてこのExt2.1-API Dcumentationページをデバッグできる状態にします。<br />
さらにConsoleタブをクリックして、コンソールを開きます。右ペインの複数行入力できるコンソールが開いていなければ右下のアイコンをクリックしてペインを開きます。<br />
開いたらこのコンソールに以下のコードを入力し、RunをクリックするかCTRL+ENTERを押下します。
<pre>
Ext.get(document.body).update('&lt;div id="test"&gt;&lt;/div&gt;');
</pre>
このコードはページのdocument.bodyを取得し、そのinnerHTMLをdiv id="test"で更新すると言うものです。HTMLタブをクリックしてbodyノードを開くとinnerHTMLが&lt;div id="test"&gt;&lt;/div&gt;になっていることが確認できます。同時に画面からコンテンツが消えます。コンテンツは消えますが、ExtJSのライブラリはロードされたままですので、コイツを利用してスクリプトのテストが行えるんです。<br /><br />
ためしに、
<pre>
new Ext.Panel({
    renderTo: 'test',
    width: '200px',
    title: 'My Title',
    html: 'My HTML content'
});
</pre>
をコンソールにコピペ（追記）してCTRL+ENTERを押下します。すると、Ext.Panelが表示されます！
<pre>
    renderTo: 'test',
</pre>
というコンフィグオプションでdiv id="test"をレンダリング先としていますので、１行目は消さないでください。続けて、html: 'My HTML content'というコンフィグオプションの直後に
<pre>
    ,collapsible : Boolean
</pre>
を挿入してみます。地味ですが、パネルのタイトルバー右に[▲]アイコンが表示され、パネルのボディが開いたり閉じたり出来るようになりました！ということはAPI DocumentationにあるExtクラスのメソッドや、コンフィグなどがリアルタイムにどんなものなのか確認できるようになったということですね。うわーすげー便利だ。<br ><br >
では次にrenderTo: 'test',と言う箇所を// でコメントアウトします。
<pre>
    //renderTo: 'test',
</pre>
画面からパネルが消えますので,collapsible : Booleanの直後に以下のコードを挿入します。
<pre>
    ,x: 100
    ,y: 100
    ,renderTo: Ext.getBody()
    ,floating: true
    ,frame: true
    ,height: 200
    ,draggable: {
        insertProxy: false,
        onDrag : function(e){
            var pel = this.proxy.getEl();
            this.x = pel.getLeft(true);
            this.y = pel.getTop(true);
            var s = this.panel.getEl().shadow;
            if (s) {
               s.realign(this.x, this.y, pel.getWidth(), pel.getHeight());
            }
        },
        endDrag : function(e){
            this.panel.setPosition(this.x, this.y);
        }
    }
</pre>
すると、パネルがドラッグ＆ドロップできるようになりました！<br />
というわけで、日本語チュートリアルと全然変わりありませんが知ってるのと知らないのでは大違いなのでポストしてみました。何が一番びっくりしたのかと言いますと、このコンソールの使い方が<a href="http://getfirebug.com/cl-jp.html">getfirebug.com</a>にデカデカと載っていたことです。あーびっくりした。（しらじらしい）
</div>]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/05/extjsfirebug.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/05/extjsfirebug.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">デバッグ</category>
        
        
         <pubDate>Thu, 15 May 2008 21:06:17 +0900</pubDate>
      </item>
            <item>
         <title>Ext.DataViewの使い方</title>
         <description><![CDATA[<div class="lh">
<a href="http://mojalog.com/images/simpledataview.PNG"><img class="gt" alt="simpledataview.PNG" src="http://mojalog.com/images/simpledataview-thumb.PNG" width="228" height="165" /></a>
<a href="http://extjs.com/products/extjs/download.php">ダウンロードページ</a>より、アーカイブ(Ext JS 2.1 SDK)をダウンロードして解凍してください。20080513時点のバージョンは ext-2.1 です。解凍したら、以下のパスのファイルを開いて見ましょう。
<pre>
【パス】
ext-2.1\examples\view\data-view.html
</pre>
開いてみると、何も見えませんね。これはサーバサイトスクリプトを参照しに行っていてその参照先がローカルのget-images.phpにあるためです。ですので<a href="http://extjs.com/deploy/dev/examples/view/data-view.html">直接ExtJSのDataViewサンプル</a>を見てみます。<br />
このウィジェットがDataViewと呼ばれるものです。サンプルではサムネイル画像がならんでいて、マウスをドラッグするか、CTRLまたはSHIFTキーを押しながら選択すると複数のアイテムが選択できるようになっています。今日はこのDataViewの基本的な実装を解説してみたいと思います。あと、いきなりDataViewとか言われても・・と言う方には<a href="http://mojalog.com/2008/02/extjs20_1.html">ここ</a>にExtJSのチュートリアルを簡単にまとめてみました。<br />
まず、以下に今回解説するDataViewのソースを全て載せてみましたので、この実装方法とコンフィグを解説します。<br />
<a href="http://wiki.mojalog.com/extjs/statics/ExtPack/simpledataview/index.html">動作サンプル</a>とサンプルソース
<pre>
Ext.onReady( function(){
    var lookup = {};

    var siteData = [
        ['http://mojalog.com','http://capture.heartrails.com/small?http://mojalog.com','mojalog'],
        ['http://google.co.jp','http://capture.heartrails.com/small?http://google.co.jp','google'],
        ['http://yahoo.co.jp','http://capture.heartrails.com/small?http://yahoo.co.jp','yahoo'],
        ['http://extjs.com','http://capture.heartrails.com/small?http://extjs.com','extjs'],
        ['http://capture.heartrails.com','http://capture.heartrails.com/small?http://capture.heartrails.com','heartrails' ],
        ['http://youtube.com','http://capture.heartrails.com/small?http://youtube.com','youtube' ]
    ];

    var store = new Ext.data.SimpleStore({
        fields: [
           { name: 'siteurl'},
           { name: 'imgurl' },
           { name: 'name'   }
        ],
        data : siteData
    });

    var formatData = function(data){
        lookup[data.name] = data;
        return data;
    };

    var view = new Ext.DataView({
        tpl: new Ext.XTemplate(
            '&lt;tpl for="."&gt;',
                '&lt;div class="thumb-wrap" id="{name}"&gt;',
                '&lt;div class="thumb"&gt;&lt;img src="{imgurl}" title="{name}"&gt;&lt;/div&gt;',
                '&lt;span&gt;{name}&lt;/span&gt;',
                '&lt;/div&gt;',
            '&lt;/tpl&gt;'
        ),
        singleSelect: true,
        overClass:'x-view-over',
        itemSelector: 'div.thumb-wrap',
        store: store,
        listeners: {
            'dblclick':{
                fn:function(){
                    var selNode = view.getSelectedNodes()[0];
                    var data = lookup[selNode.id];
                    location.href=data.siteurl;
                }
            }
        },
        prepareData: formatData.createDelegate( this )
    });

    var panel = new Ext.Panel({
        id: 'img-chooser-view',
        title: 'DataView',
        renderTo: 'container',
        width:320,
        autoScroll: true,
        items:view,
        collapsible:true
    });
});
</pre>
<h3>【Ext.DataViewの解説】</h3>
それではDataViewを見ていきたいと思います。
<pre>
    var view = new Ext.DataView({
</pre>
という箇所がデータビューそのものになります。前回のgridと同様にstoreというデータストアを保持していてこのstoreの内容がデータの実体になります。<br />
DataViewのコンフィグオプションで必須となるのはitemSelectorと言うもののようです。
<pre>
itemSelector : String
This is a required setting. A simple CSS selector (e.g. div.some-class or span:first-child) that will be used to determine what nodes this DataView will be working with.
</pre>
とあり、これはDataViewがどのノードで動いているかを決定するために使われる、CSSセレクタというものらしいです。今回は値に'div.thumb-wrap'を持たせてあります。このノードを「データビューのデータとして扱います」ということになるんだと思います。<br />
ちなみにdiv.thumb-wrapは、次のtplというコンフィグオプションで定義します。<br /><br />
tplは、以下のように定義してあります。<br /><br />
<pre>
        tpl: new Ext.XTemplate(
            '&lt;tpl for="."&gt;',
                '&lt;div class="thumb-wrap" id="{name}"&gt;',
                '&lt;div class="thumb"&gt;&lt;img src="{imgurl}" title="{name}"&gt;&lt;/div&gt;',
                '&lt;span&gt;{name}&lt;/span&gt;',
                '&lt;/div&gt;',
            '&lt;/tpl&gt;'
        ),
</pre>
このtplはExt.XTemplateを使ってテンプレートとして用いているのですが、このXTemplateが非常に強力で、tplノードのアトリビュートを使って演算を行い、実データをオートフィリングしてくれます。上記ではforという演算式を用いて、store内の複数データをスコープ内のタグに埋めていくようになっていますが、if演算式や内臓テンプレート変数、インラインコードの実行なんかも出来るようです。使いこなせればデータのデータのフィルタなんかも出来そうですね。<a href="http://extjs.com/deploy/dev/docs/?class=Ext.XTemplate">XTemplateのAPIDocを貼っておきます。</a><br />
上記は、{}で括られた name / imgurl をforで展開しています。このnameとimgurlはstoreのfieldsで定義した名前です。<br />
DataViewの基本的なコンフィグオプションはこのくらいで、後はオプションみたいなものです。<br /><br />
overClassはマウスオーバー時のclassを値として持たせています。singleSelectはアイテムを複数選択状態に出来ないようにするものです。これに対してmultiSelectと言うものがあり、このコンフィグオプションを使用してtrueにしておくと、CTRLやSHIFTを押しながら複数選択することが出来ます。
<pre>
    overClass:'x-view-over',
    singleSelect: true,
</pre>
'x-view-over'はスタイルシート内に定義していて、マウスオーバーしたときに表示が変わると言うものです。無くてもいいと思います。<br /><br />
最後にlistenersとprepareDataを解説します。
<pre>
    listeners: {
        'dblclick':{
            fn:function(){
                var selNode = view.getSelectedNodes()[0];
                var data = lookup[selNode.id];
                location.href=data.siteurl;
            }
        }
    },
    prepareData: formatData.createDelegate( this )
</pre>
listenersはイベントリスナーのことです。今回はダブルクリックした際のイベントを拾って画面遷移を行っています。DataViewのgetSelectedNodes()で選択されたノードを返しますので、その先頭を拾ってstoreに格納したデータのsiteurlを解決しています。<br />
prepareDataはメソッドなのですが、ロード時にキックされてデータの準備を行うもののようです。今回はformatDataメソッドにその処理を委譲していてlookupオブジェクトに、各データを突っ込んでいっています。lookupオブジェクトは、選択されたデータを探すために利用しています。<br />
<pre>
    var selNode = view.getSelectedNodes()[0];
    var data = lookup[selNode.id];
</pre>
この２行はまず、DataViewで選択されたノードを取り出します。次に、selNode.idをlookupの連想配列のkeyとして指定して、該当のデータを特定します。これで、data.siteurlとか、data.nameとか、data.imgurlで参照が出来るようになっています。<br />
selNode.idのidは前述のテンプレート定義の中の
<pre>
    '&lt;div class="thumb-wrap" id="{name}"&gt;',
</pre>
にあるように、ノードのidを指しているのですが、この値はstoreのfieldsの{name}が置かれています。<br />
ロード時に、prepareDataで委譲したformatDataメソッドが呼ばれてlookupオブジェクトのkeyであるdata.nameに対してdataがドカドカと格納されていきます。
<pre>
    var formatData = function(data){
        lookup[data.name] = data;
        return data;
    };
</pre>
これでlookupのkeyはnameで解決できると言うことです。（firebugで分かりました。）<br /><br />
というわけで、DataViewの解説をしてみました。ワタシの理解を多分に含めておりますので、誤った情報である可能性がありますのでご注意ください。
</div>]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/05/extdataview.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/05/extdataview.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">DataView</category>
                  <category domain="http://www.sixapart.com/ns/types#category">SimpleStore</category>
                  <category domain="http://www.sixapart.com/ns/types#category">data</category>
        
                  <category domain="http://www.sixapart.com/ns/types#tag">prepareData</category>
        
         <pubDate>Tue, 13 May 2008 21:03:32 +0900</pubDate>
      </item>
            <item>
         <title>Ext.grid.GridPanelの使い方</title>
         <description><![CDATA[<div class="lh">
まず、ExtJS javascriptライブラリを<a href="http://extjs.com/products/extjs/download.php">ダウンロードページ</a>より、アーカイブ(Ext JS 2.1 SDK)をダウンロードして解凍してください。20080428時点のバージョンは ext-2.1 です。解凍したら、以下のパスのファイルを開いて見ましょう。gridのサンプルは<a href="http://extjs.com/products/extjs/#sample-1">ココ</a>からも見れます。
<pre>
【パス】
ext-2.1\examples\grid\array-grid.html
</pre>
このウィジェットがgridと呼ばれるものです。エクセルのような罫線で表現されたウィジェットで、
<ul>
<li>ソート</li>
<li>各セルの編集</li>
<li>グルーピング</li>
<li>サマリ</li>
<li>フィルタ</li>
</ul>
<a href="http://mojalog.com/images/simplegrid.PNG"><img class="gt" alt="simplegrid.PNG" src="http://mojalog.com/images/simplegrid-thumb.PNG" width="228" height="171" /></a>
なんかも出来ます。すごいですね。今日はこのgridの基本的な実装を解説してみたいと思います。あと、いきなりgirdとか言われても・・と言う方には<a href="http://mojalog.com/2008/02/extjs20_1.html">ここ</a>にExtJSのチュートリアルを簡単にまとめてみました。<br />
まず、以下に今回解説するgridのソースを全て載せてみましたので、この実装方法とコンフィグを解説します。<br /><br />
<a href="http://wiki.mojalog.com/extjs/statics/ExtPack/simple-grid/index.html">動作サンプルとサンプルソース</a>
<pre>
Ext.onReady( function(){
    var store = new Ext.data.SimpleStore({
        fields: [
            { name: 'a' },
            { name: 'b' }
        ],
        data:[ 
            [ 'hoge', 1 ],
            [ 'moge', 2 ],
            [ 'fuga', 3 ] 
        ]
    });

    var clmnModel = new Ext.grid.ColumnModel([
        { header: "title", width: 200, dataIndex: 'a' },
        { header: "number", width: 100, sortable: true, dataIndex: 'b' }
    ]);
 
    var grid = new Ext.grid.GridPanel({
        store:store,
        colModel:clmnModel,
        renderTo:'renderTarget',
        title:'simple-grid',
        stripeRows:true,
        height:150,
        width:316,
        frame:true
    });
});
</pre>
<h3>【Ext.grid.GridPanelの解説】</h3>
それではgirdを見ていきたいと思います。
<pre>
    var grid = new Ext.grid.GridPanel({
</pre>
という箇所がグリッドそのものになります。この定義の仕方は、これからたくさん出てくるので先に解説してしまいます。<br />
Ext.grid.GridPanel({});の{}定義体はオブジェクトリテラルと呼ばれるもので、ExtJSではこの書式で実装していくことがほとんどです。使ってみればそんなに難しいものでは無く、<br />
オブジェクトリテラルとは
<ul>
<li>中カッコ{}で囲まれて、</li>
<li>カンマ,を使ってプロパティが区切られて定義されるもの</li>
</ul>
だと理解すればいいのではないかと思います。多分乱暴に色々切り捨てた言い方をしたのかもしれませんが、ワタシはそう理解しています。<br />
そしてこのオブジェクトリテラルのプロパティ１つ１つを、ExtJSではコンフィグオプションと呼んでいます。
<pre>
Ext.grid.GridPanel({ /* コンフィグオプション群 */ })
</pre>
このコンフィグオプションによって、いろんな表示設定や、機能設定が出来るようになっています。<br />
サンプルソースのgridのコンフィグオプションを上から見ていくと、<br />
store / colModel / renderTo / title / stripeRows / height / width / frame とありまして、このほかにも様々なコンフィグオプションがありますが、GridPanelで必須とされるのは store と colModel になります。ただ、renderToで表示先を指定してあげないと、このサンプルソースではgridが表示されませんので、このstore / colModel / renderTo以外をコメントアウトしたりしてどんなコンフィグなのか試してみるといいかもしれません。<br /><br />
それではこのコンフィグを解説していきたいと思います。<br />
storeは、APIDocumentに
<pre>
store : Ext.data.Store
The Ext.data.Store the grid should use as its data source (required). 
</pre>
とあり、storeはデータソースであることがわかります。データの実体ですね。その型はExt.data.Storeを使っているよーと言うことです。<br /><br />
colModelは、
<pre>
colModel : Object
The Ext.grid.ColumnModel to use when rendering the grid (required). 
</pre>
とあり、girdの列定義をあらわしています。<br />
ちなみにcolModelは、cmというコンフィグオプション名でもよくて、cmは、colModelを表すshorthand（ショートハンド（エイリアス？））だとAPIDocにあります。どちらでもいいですが、colModel / cm は必須コンフィグです。<br /><br />
renderToは、
<pre>
    renderTo:'renderTarget',
</pre>
先にも記述したとおり、表示先を指定するコンフィグです。document.bodyとか、DOMノードのidを表示先に設定してあげます。サンプルソースのように、コンフィグオプションでレンダリング先を指定してあげることも出来ますし、出来上がったgridから以下のようにしてメソッドとして呼び出すことも出来ます。（メソッド名とコンフィグオプションは必ずしも一致しませんし、コンフィグオプションが全てメソッドとして利用できるわけではなさそうです。）
<pre>
    var grid = new Ext.grid.GridPanel({ /* config options */ });
    grid.render( 'renderTarget' );
</pre>
サンプルソースで使ったコンフィグの残りは表示レイアウトのオプションになります。
<pre>
    title:'simple-grid',
    stripeRows:true,
    height:150,
    width:316,
    frame:true
</pre>
titleはgirdのタイトルになります。これを設定しないとタイトルバーごと表示されません。何かを設定すれば、（例えば空文字でも）タイトルバーは残ります。<br />
stripeRowsは、行を縞々に表示するコンフィグです。ちょっと色が薄いので判りにくいですが、これをtrueにすると行が縞々に表示されます。stripeRowsコンフィグを使わないで実装した場合、デフォルト値がfalseですので、縞々にはなりません。<br />
height / widthはそのまま、縦・横の幅を表します。<br />
最後のframeはこのgridの枠です。true / false で表示・非表示を表していて、デフォルトはfalseです。<br />
コンフィグオプションをつけたり消したりして、表示を見て試してみれば判りやすいかと思います。<br /><br />
<h3>【Ext.data.SimpleStoreの解説】</h3>
では、GridPanelに必須コンフィグのstoreの解説です。
<pre>
    var store = new Ext.data.SimpleStore({
        fields: [
            { name: 'a' },
            { name: 'b' }
        ],
        data:[ 
            [ 'hoge', 1 ],
            [ 'moge', 2 ],
            [ 'fuga', 3 ] 
        ]
    });
</pre>
ソースは上記のようになっています。gridと同じようにExt.data.SimpleStore({ /* コンフィグオプション群 */ })コンフィグオプションを設定します。Ext.data.SimpleStoreはExt.data.Storeを継承したデータストアで、配列でStoreデータを簡単に構築できるクラスです。見ると、fieldsもdataも配列で構築されていることがわかります。
<pre>
    fields: [
        { name: 'a' },
        { name: 'b' }
    ],
</pre>
fieldsは、ストア上のフィールド定義です。名前に a / b と付けてみました。gridそのものを見ると列ヘッダにtitle / numberとありますが、ストア上にあるフィールド名は a / b となります。（girdはStoreとColumnModelのファサード（ラッパー）だと理解すればいいと思います。）データを正しくマッピングできるように重複しない名前を定義してあげてください。（マッピングは次のExt.grid.ColumnModelで行います。）
<pre>
    data:[ 
        [ 'hoge', 1 ],
        [ 'moge', 2 ],
        [ 'fuga', 3 ] 
    ]
</pre>
dataは、そのまんまデータを表していて、多次元配列（２次元配列）で定義します。表のイメージを実装してあげることが出来るので便利ですが、多次元配列で定義することに注意してください。例えば、fieldsが１つの場合でも
<pre>
    data:[ 
        'hoge', 
        'moge', 
        'fuga' 
    ]
</pre>
とせずに
<pre>
    data:[ 
        [ 'hoge' ], 
        [ 'moge' ], 
        [ 'fuga' ] 
    ]
</pre>
のように多次元配列で構築する必要があります。
<h3>【Ext.grid.ColumnModelの解説】</h3>
<pre>
    var clmnModel = new Ext.grid.ColumnModel([
        { header: "title", width: 200, dataIndex: 'a' },
        { header: "number", width: 100, sortable: true, dataIndex: 'b' }
    ]);
</pre>
まず、ソースを抜き出してみました。このクラスは
<pre>
Ext.grid.ColumnModel([{ /* コンフィグオプション群 */ },{ /* コンフィグオプション群 */ } ]);
</pre>
のように、配列でコンフィグオプションをイニシャライズする必要があります。カラム定義が１つの場合は、コンフィグオプション群も１つになるかと思いますが、以下のように配列で定義しないで実装すると正しく表示されません。（gridの中身が表示されなくなります）
<pre>
    // 正しく表示されない
    Ext.grid.ColumnModel({ /* コンフィグオプション群 */ });

    // 正しく表示される
    Ext.grid.ColumnModel([ { /* コンフィグオプション群 */ } ]);
</pre>
コンフィグオプションの中身はその機能や、表示系のオプションがたくさん用意されていて、今回使ってみた機能はsortableというコンフィグです。読んで字のごとく該当列がソートできるか出来ないかを表すコンフィグです。デフォルト（sortableを実装していない場合）はソートできないので、titleフィールドはソート表示がグレーアウトされていて、numberフィールドはソードが出来るようになっています。<br />
<pre>
    { header: "title", width: 200, dataIndex: 'a' },
    { header: "number", width: 100, sortable: true, dataIndex: 'b' }
</pre>
headerは列のタイトルとなるコンフィグで、widthは列の幅を表しています。dataIndexは上述のstoreで定義したnameとマッピングしています。必須ではありませんので定義しなくても表示されますが、明示的にマッピングして表示してあげたほうがいいかと思います。<br />
他にもこのサンプルソースにすぐ使えそうな機能コンフィグとして以下のようなものがあります。editorというコンフィグで各セルの編集が出来るようになるのですが、これはgirdそのものがExt.grid.EditorGridPanelでないと機能しないようです。（次回解説します。）
<ul>
<li>hidden:Boolean
<ul>
<li>列そのものを表示させるかどうかです。trueにすると非表示となります。カラムメニューから再表示させることが出来ます。</li>
</ul>
</li>
<li>hideable:Boolean
<ul>
<li>列を非表示に出来るかどうかです。falseにすると非表示にすることが出来なくなり、カラムメニューから該当列の表示・非表示のチェックボックスが消えます。</li>
</ul>
</li>
<li>resizable:Boolean
<ul>
<li>列の幅をリサイズできるかどうかです。falseにすると、リサイズが出来なくなります。</li>
</ul>
</li>
<li>menuDisabled:Boolean
<ul>
<li>列メニューを使えるようにするかどうかです。trueにすると、該当列の列メニュードロップダウン表示（▼←こんなの）がなくなりメニューが使えなくなります。</li>
</ul>
</li>
<li>tooltip:String
<ul>
<li>列にマウスをあわせたときにtooltipが表示されます。</li>
</ul>
</li>
</ul>
というわけで、gridの解説をしてみました。ワタシの理解を多分に含めておりますので、誤った情報である可能性がありますのでご注意ください。
</div>]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/04/extjs_extgridgridpanel.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/04/extjs_extgridgridpanel.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">ColumnModel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">GridPanel</category>
                  <category domain="http://www.sixapart.com/ns/types#category">SimpleStore</category>
                  <category domain="http://www.sixapart.com/ns/types#category">data</category>
                  <category domain="http://www.sixapart.com/ns/types#category">grid</category>
        
                  <category domain="http://www.sixapart.com/ns/types#tag">render</category>
                  <category domain="http://www.sixapart.com/ns/types#tag">renderTo</category>
        
         <pubDate>Mon, 28 Apr 2008 21:19:01 +0900</pubDate>
      </item>
            <item>
         <title>お知らせ</title>
         <description><![CDATA[<div class="lh">
<h3>■はじめに</h3>
このブログはExtJS / GWTについて淡々と綴っていくまとめサイトです。位置付けは自分用の備忘録になりますが、誤った情報を垂れ流す可能性も多々ありますのでコメントもトラックバックも開けておきます。<br /><br />
<h3>■更新履歴</h3>
<ul>
<li><a href="http://wiki.mojalog.com/extjs/2008/12/extjsair.html">ExtJSでAIRやってみた</a>[20081211]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/06/extdomquery1.html">Ext.DomQueryの基本的な使い方#1</a>[ 20080626 ]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/06/extgrideditorgridpanel.html">EditorGridPanelの使い方</a>[ 20080623 ]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/05/exttreetreepanel.html">TreePanelの使い方</a>[ 20080522 ]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/05/extjsfirebug.html">デバッグの便利な方法</a>[ 20080515 ]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/05/extdataview.html">DataViewの使い方</a>[ 20080513 ]</li>
<li><a href="http://wiki.mojalog.com/extjs/2008/04/extjs_extgridgridpanel.html">GridPanelの使い方</a>[ 20080428 ]</li>
<li>出来たばっかり。[ 20080421 ]</li>
</ul>
<h3>■リンク</h3>
<ul>
<li><a href="http://extjs.com">ExtJS</a></li>
<li><a href="http://extjs.com/products/extjs/">ExtJS OverViewページ。サンプルがたくさん見れます。</a></li>
<li><a href="http://extjs.com/products/extjs/download.php">ExtJS SDK Downloadページ</a></li>
<li><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_2.0_%28Japanese%29">日本語チュートリアル</a></li>
<ul><li><a href="http://www.ext-japan.org/docs/?class=basic/list1&type=tutorial">ExtJapanのチュートリアル</a></li></ul>
<li><a href="http://extjs.com/deploy/dev/docs/">API Doc（本家）</a></li>
<li><a href="http://www.ext-japan.org/docs/">API Doc（ExtJapanによる一部日本語化）</a></li>
<li><a href="http://extjs.com/forum/">フォーラム（英語）</a></li>
<li><a href="http://extjs.com/products/license.php">ライセンス</a></li>
<ul>
<li>商業ライセンス ・ オープンソースライセンス ・ OEM/再販業者ライセンスがあります。エキサイト翻訳にかけてもそれほど変な翻訳にはならなかったです。</li>
<li><a href="http://hoikuru.net/programming/ext_license.html">Extのライセンス（翻訳）</a></li>
</ul>
<li><a href="http://b.hatena.ne.jp/t/extjs">extjsを含む注目エントリー[はてブ]</a></li>
</ul>
<br />
<h3>■サイトマップ</h3>
[ カテゴリ ]<br /><br />
パッケージレベルをトップレベルカテゴリとして、クラスやコンポーネントまでをカテゴリとして扱います。エントリを探す際にご利用ください。<br /><br />
[ タグ ]<br /><br />
プロパティ、メソッド、イベントをタグとして扱います。エントリを探す際にご利用ください。<br /><br />
</div>]]></description>
         <link>http://wiki.mojalog.com/extjs/2008/04/extjswiki.html</link>
         <guid>http://wiki.mojalog.com/extjs/2008/04/extjswiki.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">notice</category>
        
        
         <pubDate>Tue, 22 Apr 2008 00:20:28 +0900</pubDate>
      </item>
      
   </channel>
</rss>
