Home > ExtJS Archive

ExtJS Archive

ExtJS GridPanelについて groupingとか

前回はGridPanelでインタラクティブに動く方法を調査してみました。
今回はGridPanelにレンダリングする情報を、グループに分けてみようと思います。

グループに分けていない普通のグリッドは以下の記述で実現できます。というか前回の一番最初に紹介したものと同じです。
デモはこちら

    <script>
    Ext.onReady(function(){

        Ext.BLANK_IMAGE_URL = './extjs/resources/images/default/s.gif';
        Ext.QuickTips.init();

        // グリッド設定
        var grid = new Ext.grid.GridPanel({

            // 表示設定
            renderTo: document.body,

            // フレーム設定
            frame: true,

            // サイズ設定
            height: 300,
            width: 500,

            // ボーダー設定
            border: false,

            // カラムモデル設定
            cm: new Ext.grid.ColumnModel({

                columns: [{
                    width: 180,
                    header: '作業年',
                    dataIndex: 'YYYYMM',
                    sortable:true
                },{
                    width: 180,
                    header: '作業年月',
                    dataIndex: 'DD',
                    sortable:false
                },{
                    width: 180,
                    header: '出勤時間',
                    dataIndex: 'ATTEND_FROM'
                },{
                    width: 180,
                    header: '退出時間',
                    dataIndex: 'ATTEND_TO'
                },{
                    width: 180,
                    header: '状況',
                    dataIndex: 'STATUS',
                    sortable:false
                }]

            }),

            // ビュー設定
            viewConfig: {

                 // 強制フィット設定
                 forceFit: true

            },

            // ストア設定
            store: new Ext.data.JsonStore({

                 // 自動読み込み設定
                 autoLoad: true,

                 // 自動破棄設定
                 autoDestroy: true,

                 // リクエストURL設定
                 url: 'sss/attend-list.php',

                 // StoreID設定
                 storeID: 'AttendListStore',

                 // ルートノード設定
                 root: 'items',

                 // ID設定
                 idProperty: 'id',

                 // フィールド設定
                 fields: ['ID', 'YYYYMM', 'DD', 'ATTEND_FROM', 'ATTEND_TO', 'STATUS']

            })

        });

    });
    </script>

では次に、グルーピングをするコードを記載します。グルーピングしたデモはこちら

    <script>
    Ext.onReady(function(){

        Ext.BLANK_IMAGE_URL = './extjs/resources/images/default/s.gif';
        Ext.QuickTips.init();

        var grid = new Ext.grid.GridPanel({

            // 表示設定
            renderTo: document.body,

            // フレーム設定
            frame: true,

            // サイズ設定
            height: 300,
            width: 500,

            // ボーダー設定
            border: false,

            // カラムモデル設定
            cm: new Ext.grid.ColumnModel({

                columns: [{
                    width: 180,
                    header: '作業年',
                    dataIndex: 'YYYYMM',
                    sortable:true
                },{
                    width: 180,
                    header: '作業年月',
                    groupable: false,
                    dataIndex: 'DD',
                    sortable:false
                },{
                    width: 180,
                    header: '出勤時間',
                    groupable: false,
                    dataIndex: 'ATTEND_FROM'
                },{
                    width: 180,
                    header: '退出時間',
                    groupable: false,
                    dataIndex: 'ATTEND_TO'
                },{
                    width: 180,
                    header: '状況',
                    groupable: false,
                    dataIndex: 'STATUS',
                    sortable:false
                }]

            }),

            // ビュー設定
            viewConfig: {

                 // 強制フィット設定
                 forceFit: true

            },

            // ストア設定
            store: new Ext.data.GroupingStore({

                // 自動読み込み設定
                autoLoad: true,

                // 自動破棄設定
                autoDestroy: true,

                // リクエストURL設定
                url: 'sss/attend-lIst.php',

                // ソート設定
                sortInfo: {
                    field: 'YYYYMM',
                    direction: 'DESC'
                },

                // グループ単位でソート設定
                groupOnSort: true,

                // グループ単位でのソート設定
//                groupDir: 'DESC',

                // グループフィールド設定
                groupField: 'YYYYMM',

                // StoreID設定
                storeID: 'AttendListStore',

                // 読み込み設定
                reader: new Ext.data.JsonReader({

                    // ルートノード設定
                    root: 'items',

                    // ID設定
                    id: 'id',

                    // フィールド設定
                }, ['ID', 'YYYYMM', 'DD', 'ATTEND_FROM', 'ATTEND_TO', 'STATUS']
                )

            }),

            view: new Ext.grid.GroupingView({
                forceFit:true,
                hideGroupedColumn: true
//                groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
            })
        });

    });

    </script>

それでは、コードを見ていきましょう。上と下で違うのはデータレコードを保持する設定のstoreと、それに付随するviewの設定です。まずstoreの設定から見ていきましょう。上はExt.data.JsonStoreを設定していますが、下はExt.data.GroupingStoreを設定しています。もう少し詳しく見てみると、GroupingStoreの中でJsonStoreを設定しています。
そもそもstoreは何を設定するかというと、Ext.data.storeを設定することになっています。ではGroupingStoreは大丈夫なのかというとExt.data.GroupingStoreはExt.data.storeを継承しているので使用しても問題ないようです。

では、グルーピングで設定しているコンフィグオプションを見ていきましょう。、

                // ソート設定
                sortInfo: {
                    field: 'YYYYMM',
                    direction: 'DESC'
                },

                // グループ単位でソート設定
                groupOnSort: true,

                // グループ単位でのソート設定
//                groupDir: 'DESC',

                // グループフィールド設定
                groupField: 'YYYYMM',

                // StoreID設定
                storeID: 'AttendListStore',

                // 読み込み設定
                reader: new Ext.data.JsonReader({

                    // ルートノード設定
                    root: 'items',

                    // ID設定
                    id: 'id',

                    // フィールド設定
                }, ['ID', 'YYYYMM', 'DD', 'ATTEND_FROM', 'ATTEND_TO', 'STATUS']
                )

sortInfoはソート順を指定します。ローカルなソートのために、ソート方向(direction)プロパティが大文字小文字の違いを識別することに注意してください。
そして次にgroupOnSort 。これはgroupFieldで指定したフィールドでソート可、不可設定の役割をします。これをfalseにすると、groupFieldで設定したフィールドでソートできません。ここでちょっと話がそれますが、sortに関して今回私は手こずりました。というか、満足した形で終えられてません。あとで詳しく書かせてもらいます。
groupFieldは何でグルーピングするか。
storeIDはStoreMgrに登録するために使用するidです。 メモ: もし、id(非推奨)が指定される場合、割り当てがstoreIdに変わります。
readerはデータレコードを取り扱います。
あと、注意することに、groupFieldで指定したカラムはcm(columnModel)の方でも記述しないと正常に動作しませんので気をつけてください。

最後にviewの設定を付け加えます。hideGroupedColumnでグルーピングしたカラムを隠しています。

            view: new Ext.grid.GroupingView({
                forceFit:true,
                hideGroupedColumn: true
//                groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
            })

さてさて、とりあえず動くようにはなると思います。
 
 
ただ、ソート処理に関して今でもクエスチョンの疑問符が頭の上に浮いてます。

デフォルトではグルーピングのソート処理は、グルーピングされた中のレコードを対象にソート処理ができます。グルーピングでソート処理していないデモです

今回、私はグルーピングした中の情報だけでなく、グルーピングそのもののソートも実現しようとしました。デモを見ていただければ、グルーピングした情報でソートできると思います(デモではグルーピングしたフィールドが隠れているので、一旦「作業年月」のフィールドを表示してからでないと見ることができません)。groupOnSortを指定すると中のレコードでなくグルーピングでソートができるようになりました。
で、問題はgroupField以外でソートしようとすると、そのカラムでグルーピングしようとしてしまいデフォルトで実現されていたグルーピング内でのソートが実現できませんでした。なのでgourpField以外はソートできないようにしています。本当はグルーピングされた中のレコードでソートしたかったのですけど。。

う〜ん、そんなこんなで実現できなかったこともあるので、今回の実装は満足していません。分かる方いましたら是非教えてください。

ではでは

ExtJS GridPanelについて イベントリスナーとか

グリッドを作成している途中で学んだことを記述していきます。

単純なグリッド表示は以下のコードです。デモはこちら

    <script>
    Ext.onReady(function(){

        Ext.BLANK_IMAGE_URL = './extjs/resources/images/default/s.gif';
        Ext.QuickTips.init();

        // グリッド設定
        var grid = new Ext.grid.GridPanel({

            // 表示設定
            renderTo: document.body,

            // フレーム設定
            frame: true,

            // サイズ設定
            height: 300,
            width: 500,

            // ボーダー設定
            border: false,

            // カラムモデル設定
            cm: new Ext.grid.ColumnModel({

                columns: [{
                    width: 180,
                    header: '作業年',
                    dataIndex: 'YYYYMM',
                    sortable:true
                },{
                    width: 180,
                    header: '作業年月',
                    dataIndex: 'DD',
                    sortable:false
                },{
                    width: 180,
                    header: '出勤時間',
                    dataIndex: 'ATTEND_FROM'
                },{
                    width: 180,
                    header: '退出時間',
                    dataIndex: 'ATTEND_TO'
                },{
                    width: 180,
                    header: '状況',
                    dataIndex: 'STATUS',
                    sortable:false
                }]

            }),

            // ビュー設定
            viewConfig: {

                 // 強制フィット設定
                 forceFit: true

            },

            // ストア設定
            store: new Ext.data.JsonStore({

                 // 自動読み込み設定
                 autoLoad: true,

                 // 自動破棄設定
                 autoDestroy: true,

                 // リクエストURL設定
                 url: 'sss/attend-list.php',

                 // StoreID設定
                 storeID: 'AttendListStore',

                 // ルートノード設定
                 root: 'items',

                 // ID設定
                 idProperty: 'id',

                 // フィールド設定
                 fields: ['ID', 'YYYYMM', 'DD', 'ATTEND_FROM', 'ATTEND_TO', 'STATUS']

            })

        });

    });
    </script>

では次に、
セルと列を選択したときのインタラクティブな設定方法を実現してみます。
列、セル、カラムに対してユーザからのインタラクティブな設定をするにはセレクションモデルと呼ばれるものを設定します。

セレクションモデルを設定するには、グリッドパネルのコンフィグ設定にsmコンフィグオプションを加えます。

以下を加えると、複数選択できた列が一つしか選択できなくなります。

            // 列を選択する際のモニタリング設定
            sm: new Ext.grid.RowSelectionModel({
                 // シングルセレクト設定
                singleSelect: true
            })

次に、ユーザからの動作を監視する記述をしてみます。それにはlistenersを設定し、発火イベントを設定します。発火イベントは以下です。

  1. beforerkowselect:列が選択される前に発火。
  2. rowdeselect:選択が解除されたときに発火
  3. reowselect:列が選択されたときに発火
  4. selectionchange:列の選択が変更されたときに発火

ここでは選択した列に対して発火する記述をしてみます。

            // 列を選択する際のモニタリング設定
            sm: new Ext.grid.RowSelectionModel({
                // シングルセレクト設定
                singleSelect: true,
                listeners: {
                    rowselect: {
                        fn: function(sm,index,record) {
                            Ext.Msg.alert('You Selected',record.data.YYYYMM + '/' + record.data.DD);
                        }
                    }
                }
            })

さらに、カラムが移動したときにもイベントを発火させてみます。
まず、カラムモデルを取得します。取得方法はgetColumnModel()。そして、columnModelクラスのメソッドをリスナーイベントにより発火させます。ここで指定できるメソッドは、columnmoved, configchange, headerchange, hiddenchange, widthchangeがあるみたいです(詳細はcolumnModelのドキュメントを参照してください)。
ここまでのデモです

        // 列の移動時発火 移動したカラム数を表示
        // cm: ColumnModel、oindex: oldIndex、nindex: newIndex
        grid.getColumnModel().on('columnmoved',function(cm,oindex,nindex) {
            var dirmsg = '', title = 'You Moved '+cm.getColumnHeader(nindex);
            if (oindex > nindex){
                dirmsg = (oindex-nindex)+' Column(s) to the Left';
            }else{
                dirmsg = (nindex-oindex)+' Column(s) to the Right';
            }
            Ext.Msg.alert(title,dirmsg);
        });

最後にセレクトとした列の取得と、任意のセルに対してアクションを起こす例で締めくくりたいと思います。トップバーにボタンを表示します。tbarの部分です。ボタンを押下したときに列が選択されていれば、プロンプトを表示します。hasSelectionでチェックして、Msg.showで出力しています。最後に入力した値を状況カラムにセットする処理をしています。
重要なのはセレクションモデルを取得し、abstractSelectionModelを継承しているrowSelectionModelやcellSelectionModel、columnSelectionModelのメソッドが使えることですかね。
とりあえず、デモです。

            tbar: [{
               text: '状況を変更',
               handler: function(){
                   //
                   var sm = grid.getSelectionModel();

                   // 選択されている列オブジェクトを取得(選択されていれば)
                   var sel = sm.getSelected();

                   // 列が選択されているか
                   if (sm.hasSelection()){
                       Ext.Msg.show({
                           title: 'Change Title',
                           prompt: true,
                           buttons: Ext.MessageBox.OKCANCEL,
                           value: sel.data.title,
                           fn: function(btn,text){
                               if (btn == 'ok'){
                                   // 状況に
                                   sel.set('STATUS', text);
                               }
                           }
                       });
                   }
               }
            }]

ん~、いまいちクラスの全体像がまだ把握できないですね。どこかのタイミングで把握しないとな。(把握できるのかな?できなさそうです汗)

今回記述した例は、次の本を参考にしています。

ではでは

ExtJS addListenerまたはon

ExtJSのaddListenerの振る舞いをAPI Documentで調べてたら説明が俊逸すぎでした。分かりやすい!
このドキュメントを作ってくれたxenophyさんに感謝です。
(できれば、実践ガイド完成してほしいです。本でたら買います。)

その中でもドキュメントに記載されてなかったことを書き記しておきます。内容は以下二つ
1. 第一引数に指定するイベント名一覧
2. 第二引数で呼び出される関数に渡る引数の詳細

 
まず基本で、addListener(on)がとる引数です。
第一引数はイベント名(string):イベント名 一覧として下記に記載
第二引数はイベントによって呼び出される関数(function):任意
第三引数は(オプション)スコープ。指定しない場合、イベント発火したオブジェクト:任意
第四引数は(オプション)ハンドラ設定プロパティを含んでいるオブジェクト:ドキュメント参照
 

では、1. 第一引数に指定するイベント名一覧です。

Mouse events
click Fires when a mouse click is detected within the element.
dblclick Fires when a mouse double click is detected within the element.
mousedown Fires when a mousedown is detected within the element.
mouseup Fires when a mouseup is detected within the element.
mouseover Fires when a mouseover is detected within the element.
mousemove Fires when a mousemove is detected with the element.
mouseout Fires when a mouseout is detected with the element.
mouseenter Fires when the mouse enters the element.
mouseleave Fires when the mouse leaves the element.
Key events
keypress Fires when a keypress is detected within the element.
keydown Fires when a keydown is detected within the element.
keyup Fires when a keyup is detected within the element.
HTML frame/object events
load Fires when the user agent finishes loading all content within the element. Only supported by window, frames, objects and images.
unload Fires when the user agent removes all content from a window or frame. For elements, it fires when the target element or any of its content has been removed.
abort Fires when an object/image is stopped from loading before completely loaded.
error Fires when an object/image/frame cannot be loaded properly.
resize Fires when a document view is resized.
scroll Fires when a document view is scrolled.
Form events
select Fires when a user selects some text in a text field, including input and textarea.
change Fires when a control loses the input focus and its value has been modified since gaining focus.
submit Fires when a form is submitted.
reset Fires when a form is reset.
focus Fires when an element receives focus either via the pointing device or by tab navigation.
blur Fires when an element loses focus either via the pointing device or by tabbing navigation.
User Interface events
DOMFocusIn Where supported. Similar to HTML focus event, but can be applied to any focusable element.
DOMFocusOut Where supported. Similar to HTML blur event, but can be applied to any focusable element.
DOMActivate Where supported. Fires when an element is activated, for instance, through a mouse click or a keypress.
DOM Mutation events
DOMSubtreeModified Where supported. Fires when the subtree is modified.
DOMNodeInserted Where supported. Fires when a node has been added as a child of another node.
DOMNodeRemoved Where supported. Fires when a descendant node of the element is removed.
DOMNodeRemovedFromDocument Where supported. Fires when a node is being removed from a document.
DOMNodeInsertedIntoDocument Where supported. Fires when a node is being inserted into a document.
DOMAttrModified Where supported. Fires when an attribute has been modified
DOMCharacterDataModified Where supported. Fires when the character data has been modified.

 
次に2. 第二引数で呼び出される関数に渡されるパラメータです。
* @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.まぁつまりはExt.EventObjectクラスのメソッドが使えるということですね。
* @param {HtmlElement} t The target of the event.
* @param {Object} o The options configuration passed to the {@link #addListener} call.
 

使用例です。

// idがElementIdの要素(オブジェクト)取得
el = Ext.get('ElementId');

// ElementId配下のaタグをクリックしたらthis.onClickを発火
el.on('click', this.onClick, this, {delegate:a});

// preventDefault:trueに設定した場合、ブラウザ標準のイベントハンドリングを防ぎます。
// emptyFnは空の関数です。ここでは空の関数を指定定義して、ブラウザ固有の処理を防ぐことを意図しています。
el.on('click', Ext.emptyFn, this, {preventDefault:})

onClick = function( e, t ) {

    // eはExt.EventObject。Ext.EventObjectクラスのメソッドが使える
    // stopEvent:イベントを停止します(preventDefaultとstopPropagationをコールします)。
    e.stopEvent();

    // 発火したエレメントのid属性アラート
    alert(t.id);

}

ExtJS少し触ってみて得た感触は、それなりに使いこなそうと思うならクラスは何があるか、クラス階層はどういう風になっているかを把握してなかったら使えこなせないような気がしました。

ちゃんちゃん
ではでは

ExtJS ローディング表示とViewport表示

表題の実装をしようと思っていたら、すばらしいエントリを見つけてしまいました。
ローディングウィンドウを作る
ExtJSに関して調べると、このブログに高い確率で遭遇するんではないでしょうか。

さらに、コードを記述する際の設計方針に関しても大変参考になるエントリがあります。
第二回ExtJS勉強会資料:ExtJS アプリケーション開発

ちょっとコーディング内容は変えましたが、ほぼ参考サイトにある通りにやっていきます。

まず環境ですが、extjsフォルダをindex.php(またはindex.html)と同階層にしてます。

参考サイトではローディング画面が黒だったので、白にしました。

/* ローディング */
#cypher-loading-mask {
    width:100%;
    height:100%;
    background:white;
    position:absolute; /* 分かりやすい説明 http://h2ham.seesaa.net/article/109909802.html 参照 */
    z-index: 20000;
    left: 0;
    top:0;
}

#cypher-loading {
    position:absolute;
    left:43%;
    top:40%;
    padding:2px;
    width:150px;
    text-align:left;
    z-index:20001;
}

#cypher-loading .cypher-loading-indicator {
    background:white;
    color:#555;
    font:bold 13px tahoma,arial,helvetica;
    padding:9px;
    margin:0;
}

ローディングのDIVを記述します。

    <!-- Loading Mask -->
    <div id="cypher-loading-mask" style=""></div>
    <div id="cypher-loading">

        <div class="cypher-loading-indicator">
            <img src="./extjs/resources/images/default/grid/loading.gif" width="16" height="16" style="margin-bottom:3px; margin-right:3px;" align="absmiddle"/>
            読み込み中...
        </div>
    </div>
    <!-- /Loading Mask -->

これでローディングが出力されると思います。
参考サイトでは、ローディングを消す処理はExtの仕事とありますので、次にそれをやりましょう。

コーディングの構成は第二回ExtJS勉強会資料:ExtJS アプリケーション開発を参考にしました。

// 名前空間の設定
// {{{ NameSpace
Ext.ns(
    'Cypher',
    'Cypher.app',
);
// }}}

// {{{ Cypher App設定
Cypher.app.App = Ext.extend( Ext.util.Observable, {

    // {{{ commonInit
    /**
     * 共通初期化メソッド
     */
    commonInit : function() {

        // s.gif設定
        Ext.BLANK_IMAGE_URL = './extjs/resources/images/default/s.gif';

    },

    // }}}
    // {{{ initApp
    /**
     * アプリケーション初期化メソッド
     */
    initApp : function() {

        // ここにviewportの記述をしていく

        // ローディングマスク解除
        setTimeout(function(){
            Ext.get('cypher-loading').remove();
            Ext.get('cypher-loading-mask').fadeOut({remove:true});
        }, 750);

    },

    // }}}
    // {{{ run
    /**
     * アプリケーション実行メソッド
     */
    run : function() {

        // 共通初期化処理実行
        this.commonInit();

        // アプリケーション初期化
        this.initApp();

    }
    // }}}
});
// }}}
// {{{ onReady
Ext.onReady( function() {

    // アプリケーション実行
    window.Application = new Cypher.app.App();
    Application.run();

});
// }}}

ローディング処理が消えると思います。
次にviewportの設定を記述していきます。
先程のviewportの記述場所に以下をそのまま記述します。

        // ビューポート生成
        new Ext.Viewport({

            // レイアウト設定
            layout: 'border',

            // アイテム設定
            items: [{

                // タイトル設定
                title: 'north',

                // ID設定
                id: 'header',

                // サイズ設定
                height: 100,

                // リージョン設定
                region: 'north'

            },{

                // タイトル設定
                title: 'west',

                // ID設定
                id: 'west',

                // 幅設定
                width: 150,

                // リージョン設定
                region: 'west',

                // 開閉設定
                collapsible: true

            },{

                // タイトル設定
                title: 'center',

                // ID設定
                id: 'center',

                // リージョン設定
                region: 'center',

                // xtype設定
                xtype: 'tabpanel',

                // アイテム設定
                items: {

                    // タブタイトル設定
                    title: 'Default Tab',

                    // コンテンツ設定
                    html: 'The first tab\'s content.'

                }

            },{

                // タイトル設定
                title: 'east',

                // ID設定
                id: 'east',

                // 幅設定
                width: 100,

                // リージョン設定
                region: 'east',

                // 幅移動設定
                split: true

            },{

                // タイトル設定
                title: 'south',

                // ID設定
                id: 'south',

                // 幅設定
                height: 100,

                // リージョン設定
                region: 'south'

            }],

            // レンダリング先指定
            renderTo: Ext.getBody()

        });

以上になります。

今回紹介したデモです

ではでは。

ExtJS 9arrows Install作業にちょっとはまる

ExtJsとRailsの連携を参考にするため9arrowsをインストールしました。

Readmeのインストールログには不備があります。その不備を補う情報が下記サイトに載っています。
私も参考にさせて頂きました。管理者様ありがとうございます。
9arrows導入でつまづいた点をメモる

MacにRailsのpostgtesqlアダプタが入れることにはまりました。下記サイトは手動でインストールするときに参考にできるサイトです。ちなみに筆者は手動ではいれていません
Macに手動でRuby-pgを入れる

WEBrick起動時にエラー。下記解決参考サイトです。管理者様ありがとうございます。
Rails 2.2.2でのconfig. action_view. cache_template_extensions

9arrowsのインストール作業は以上です。で、下記は当初の目的の助けになるかもしれないので載せておきます。RailsとExtJsを連携させるTutorialサイト
Tutorial:Using Ext Grid with Ruby on Rails

ExtJS RSS READER

インターフェイスにExtJSをふんだんに利用したWebアプリケーション作成をしていきたいと思いまして、練習がてらサンプルを利用して作成しました。

ExtJSのサンプルからfeed-viewerを利用して、サーバサイドと連携したrss readerを動作させました。

使用した環境は以下です。

rails2.3.3
MySQL
ExtJS-3.0.0

デモを用意しました。こちらから

id : guest@example.com
password : guest

で、ログインできます。

またあとで、学んだこと、はまったことを書きたいと思います。

とりあえず

ではでは

ExtJS タブの中でグリッド表示

タブの中でグリッドを表示する処理を紹介します。

出力する内容は、前回からの続きということで外部サーバから取得したXMLデータと想定します。

前回までの処理

        var xmlreader = new Ext.data.XmlReader(
              {record: 'item'}
              ,[ {name: 'title'} ,{name: 'link'},{name: 'pubDate'} ]
          );
        var myStoreData = new Ext.data.Store({
          //url: 'feed-proxy.php',
          proxy: new Ext.data.HttpProxy({
            url: 'desktop/feed-proxy.php?feed=http://どっかのRSSフィード'
          }),
          reader: xmlreader
        });
        myStoreData.load();

そして次に、グリッドで表示するカラムを宣言

        var myColumns = [
          {header: 'Date', width: 80, dataIndex: 'pubDate', sortable: true, renderer : renderDate}
          ,{ header: 'Title', width: 450, dataIndex: 'title' ,sortable: true}
        ];

タブを宣言しグリッドを表示。下サンプルはext/examples/desktop/sample.jsを拝借してグリッドを表示する処理を加えています。

        if(!win){
            win = desktop.createWindow({
                id: 'tab-win',
                title:'Tab Window',
                width:560,
                height:300,
                iconCls: 'tabs',
                shim:false,
                animCollapse:false,
                border:false,
                constrainHeader:true,

                layout: 'fit',
                items:
                    new Ext.TabPanel({
                        activeTab:0,

                        items: [{
                            title: 'TECHNOLOGY'
                            ,header:false
                            ,layout: 'fit'
                            ,items: [{
                              xtype: 'grid'
                              ,store: myStoreData
                              ,columns: myColumns
                              , sm : new Ext.grid.RowSelectionModel({
                                  singleSelect :true,
                                  listeners: {
                                    rowselect: {
                                      fn :function(sm, index, record) {
                                        //location.href = record.data.link;
                                        window.open(record.data.link);
                                      }
                                    }
                                  }
                              })
                            }]
                            ,border:false
                        }]
                    })
            });
        }
        win.show();

new Ext.TabPanelでタブを生成し、その中のitemsのプロパティxtypeで’grid’を指定します。
これはグリッドを使用する準備です。

,store: myStoreData

,store: myStoreDataでは上で取得したデータを指定します。

,columns: myColumns

,columns: myColumnsではmyStoreDataをパースする情報を指定します。

, sm : new Ext.grid.RowSelectionModel({

, sm : new Ext.grid.RowSelectionModel({以下はグリッドの列を押下したときの処理です。

タブの中でグリッドを表示する処理の概要はこんな感じです。

上の処理だけをコピペしてつなげるだけでは動作しないと思いますが、ext/examples/desktop/sample.jsを参考に以上のコードを当てはめてもらえば動くと思います。

以上です

ではでは

ExtJS 外部サーバーからXMLデータ読み込み

表題の件で、はまったことがあったのでここで紹介します。

XMLを読む込む処理はExt.data.XmlReaderを使います。
以下外部サーバから読み込む一連の処理

        var xmlreader = new Ext.data.XmlReader(
              {record: 'item'}
              ,[ {name: 'title'} ,{name: 'link'},{name: 'pubDate'} ]
          );
        var myStoreData = new Ext.data.Store({
          //url: 'feed-proxy.php',
          proxy: new Ext.data.HttpProxy({
            url: 'desktop/feed-proxy.php?feed=http://どっかのRSSフィード'
          }),
          reader: xmlreader
        });
        myStoreData.load();

Ext.data.XmlReaderから生成したインスタンスをExt.data.Storeで利用します。
そしてmyStoreData.load();で取得しているのでしょうね。

少し細かく見ると、

{record: ‘item’}

で取得ノードを指定しています。

,[ {name: 'title'} ,{name: 'link'},{name: 'pubDate'} ]

はitemノードの子ノードで取得したいノードを指定しています。

Ext.data.HttpProxy

リファレンスを参照するとExt.data.HttpProxyは、Ext.data.Connectionオブジェクトを読み込むときに利用できます。ただ別ドメイン(外部サーバ)から取得する際はこのクラスは不向きなので注意が必要です。その際は、Ext.data.ScriptTagProxyを利用して下さい。(その利用方法がこのIBMのサイトに詳しく載っています。)

この説明だとExt.data.HttpProxyを利用しての外部サーバからのxml取得は違うのではないかと思います。
筆者もExt.data.ScriptTagProxyを利用して取得しようかと思いましたが、サンプルがjson形式であったり、同ドメインであったり、なんかやめてしまいました。

そこで、プロキシ的な役割の仲介するphpファイルを用意してのサンプルがあったのでそれを利用しました。

url: ‘desktop/feed-proxy.php?feed=http://どっかのRSSフィード’

このdesktop/feed-proxy.phpが仲介するphpファイルです。

中身は

$feed = $_REQUEST['feed'];
if($feed != '' &amp;amp;&amp;amp; strpos($feed, 'http') === 0){
	header('Content-Type: text/xml');
	$xml = file_get_contents($feed);
	$xml = str_replace('<content:encoded>', '<content>', $xml);
	$xml = str_replace('</content:encoded>', '</content>', $xml);
	$xml = str_replace('</dc:creator>', '</author>', $xml);
	echo str_replace('<dc:creator', '<author', $xml);
	return;
}

file_get_contents関数で取得したいxmlデータを取得しています。
先ほどのリファレンスにも言及されていたのですが、このように使うときは
header(’Content-Type: text/xml’);
を記述しなさい、とのことです。

最後に取得

myStoreData.load();

そんなこんなで取得できましたとさ。

次回に出力する箇所の説明をしたいと思います。

あとはまった箇所は、feed-proxy.phpの文字エンコードがおかくしくなっていたせいで、
正常にずっと読み込めなくて四苦八苦してました。慣れないCotEditerの作業でやってしまったみたいです。
無駄な時間を過ごしてしまいました。みなさんは気をつけてください。

ではでは

ExtJS デスクトップ

このサイトのrootにあたるページをExtJSのデスクトップデザインに変えました。

http://cypher-works.com
extjs0

私が構築した階層を紹介します。

こんな感じです。
index.php
ext・・・・・・ExtJSコアライブラリ
desktop・・・・デスクトップデザイン用ライブラリ

http://extjs.co.jp/products/extjs/download.phpからExt JS 3.x.x SDKをダウンロード。

extjs1

作業しやすいようにext-3.x.xをextに名前変更。

ext-3.x.xのexamples直下にあるdesktopをext-3.x.xと同じ階層に移動。

desktop直下に或るdesktop.htmlをextとdesktopと同じ階層に移動(し、私はindex.phpに変更。phpスクリプトを処理したかっったら)。

index.phpで読み込むファイルのパスを修正。

index.php

cssまわり
    <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />
    <link rel="stylesheet" type="text/css" href="desktop/css/desktop.css" />
jsまわり
    <script type="text/javascript" src="desktop/js/StartMenu.js"></script>
    <script type="text/javascript" src="desktop/js/TaskBar.js"></script>
    <script type="text/javascript" src="desktop/js/Desktop.js"></script>
    <script type="text/javascript" src="desktop/js/App.js"></script>
    <script type="text/javascript" src="desktop/js/Module.js"></script>
    <script type="text/javascript" src="desktop/mydesktop.js"></script>
画像まわり(下の方にあります)
<img src="desktop/images/s.gif" />
<img src="desktop/images/s.gif" />

以上で動作します。

あとデスクトップに表示されているアイコンを変更したい場合の紹介をします。

例えば、一番左上に表示されているアイコンを変更したい場合は、
extjs2

    <dl id="x-shortcuts">
        <dt id="grid-win-shortcut">

grid-win-shortcutの部分を覚えておいて下さい。

次に該当する画像の部分を変更。desktop/css/desctop.cssの下記部分を編集します

#grid-win-shortcut img {
    width:48px;
    height:48px;
    background-image: url(../images/example.png); // example.pngに変更
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/example.png', sizingMethod='scale'); //example.pngに変更
}

これで一番左上のアイコン画像は変更されました。

以上です。

ではでは

Home > ExtJS Archive

Search
Feeds
Meta

Return to page top