ExtJSで楽しくRIA業務アプリ開発

株式会社sus4 開発チーム

ExtJS入門34 ComboBoxの基本

2件のコメントがあります

このエントリーを含むはてなブックマークはてなブックマーク - ExtJS入門34 ComboBoxの基本 この記事をクリップ!Livedoorクリップ - ExtJS入門34 ComboBoxの基本 Yahoo!ブックマークに登録 BuzzurlにブックマークBuzzurlにブックマーク このエントリをつぶやくこのWebページのtweets Share on Tumblr FC2ブックマークへ追加 newsing it! この記事をChoix! Googleブックマークに追加 Bookmark this on Delicious Digg This

今回は以前紹グリッドのサンプルで簡単に紹介したコンボボックスを取り上げます。コンボボックスはHTMLフォームのセレクトボックスのような選択式のフォームを生成します。ExtJSのコンボボックスでは、項目のデータをストアから利用します。今回はグリッドの回で使ったサンプルのストアとデータを利用しています。

ComboBoxの基本

ComboBoxの基本

グリッド関連の記事

フォーム関連の過去の記事はこちらからです。

リファレンスはこちらから
ExtJS -3.0 日本語APIドキュメント – Ext.form.ComboBoxクラス
http://extdocs.xenophy.com/?class=Ext.form.ComboBox

JSON DATA:


{
    success:true,
    total:6,
    rows:[

        {
            'id':1,
            'rank':1,
            'name':'IE',
            'percentage':62.69,
            'url' : 'http://www.microsoft.com/japan/windows/products/winfamily/ie/default.mspx',
            'img' : '../img/ie64.png'
        },
        {
            'id':2,
            'rank':2,
            'name':'Firefox',
            'percentage':24.61,
            'url' :'http://mozilla.jp/firefox/',
            'img' : '../img/firefox64.png'
        },
        {
            'id':3,
            'rank':3,
            'name':'Chrome',
            'percentage':4.63,
            'url' : 'http://www.google.com/chrome/',
            'img' : '../img/chrome64.png'
        },
        {
            'id':4,
            'rank':4,
            'name':'Safari',
            'percentage':4.46,
            'url': 'http://www.apple.com/jp/safari/',
            'img' : '../img/safari64.png'
        },
        {
            'id':5,
            'rank':5,
            'name':'Opera',
            'percentage':2.40,
            'url' : 'http://jp.opera.com/',
            'img' : '../img/opera64.png'
        },
        {
            'id':6,
            'rank':6,
            'name':'Opera Mini',
            'percentage':0.53,
            'url' : 'http://jp.opera.com/',
            'img' : '../img/opera64.png'
        }
    ]
}

HTML:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ExtJS名古屋勉強会 フォーム コンボボックス</title>

    <!--Ext JS CSS-->
    <link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
    <!--Ext JS-->
    <script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>

    <script type="text/javascript" src="../js/ext/ext-all.js"></script>
    <script type="text/javascript" src="../js/ext/src/locale/ext-lang-ja.js"></script>
    <script type="text/javascript" src="form-combo.js"></script>
    <style TYPE="text/css">
    <!--
        .tick {background-image: url(../img/icon/tick.png) !important;}
    -->
    </style>
</head>
<body>
    <div style="width:500px;margin:0 auto;padding:15px;background-color:#D3E1F1;font-size:small;">
        <p style="font-weight:bold;padding:3px;margin-bottom:10px;">

            Extのコンボボックス
        </p>
        <div id="form"></div>
        <br/>
        <br/>
        Java Script:<a href="form-combo.js">form-combo.js</a><br/>
        JSON file:<a href="data.json">data.json</a><br/>

    </div>
</body>
</html>

Java Script:


Ext.onReady(function()
{
    var data = [
        {
            'id':1,
            'rank':1,
            'name':'IE',
            'percentage':62.69,
            'url' : 'http://www.microsoft.com/japan/windows/products/winfamily/ie/default.mspx',
            'img' : '../img/ie64.png'
        },
        {
            'id':2,
            'rank':2,
            'name':'Firefox',
            'percentage':24.61,
            'url' :'http://mozilla.jp/firefox/',
            'img' : '../img/firefox64.png'
        },
        {
            'id':3,
            'rank':3,
            'name':'Chrome',
            'percentage':4.63,
            'url' : 'http://www.google.com/chrome/',
            'img' : '../img/chrome64.png'
        },
        {
            'id':4,
            'rank':4,
            'name':'Safari',
            'percentage':4.46,
            'url': 'http://www.apple.com/jp/safari/',
            'img' : '../img/safari64.png'
        },
        {
            'id':5,
            'rank':5,
            'name':'Opera',
            'percentage':2.40,
            'url' : 'http://jp.opera.com/',
            'img' : '../img/opera64.png'
        },
        {
            'id':6,
            'rank':6,
            'name':'Opera Mini',
            'percentage':0.53,
            'url' : 'http://jp.opera.com/',
            'img' : '../img/opera64.png'
        }
    ];

    var combo1 = new Ext.form.ComboBox({
        name:'combo1',
        fieldLabel:'ブラウザを選択(ローカルデータ)',
        store:new Ext.data.JsonStore({
            fields:['id','name'],
            data:data
        }),
        mode:'local',
        typeAhead:true, //入力文字から自動補完
        displayField:'name',
        valueField:'id',
        emptyText:'入力可能',
        hiddenName:'browser1'
    });

    var combo2 = new Ext.form.ComboBox({
        name:'combo2',
        fieldLabel:'ブラウザを選択(リモートデータ)',
        store:new Ext.data.JsonStore({
            fields:['id','name','img'],
            url:'data.json',
            total:'total',
            root:'rows',
            autoLoad:true
        }),
        mode:'remote',
        triggerAction:'all',
        editable:false, //自由入力不可
        displayField:'name',
        emptyText:'選択してください',
        valueField:'id',
        //hidenNameをつけないとgetValuesしたときの値はdisplayFieldの値になる
    });

    var combo3 = new Ext.form.ComboBox({
        name:'combo3',
        fieldLabel:'ブラウザを選択(テンプレート)',
        store:new Ext.data.JsonStore({
            fields:['id','name','img'],
            url:'data.json',
            total:'total',
            root:'rows',
            autoLoad:true
        }),
        mode:'remote',
        triggerAction:'all',
        editable:false, //自由入力不可
        displayField:'name',
        valueField:'id',
        hiddenName:'browser3',
        itemSelector:'div.browser-list',
        emptyText:'選択してください',
        tpl:new Ext.XTemplate(
            '<tpl for=".">',
                '<div class="browser-list" style="text-align:center;">',
                '<img src={img} width="50"/><br/>',
                '{name}',
                '</div>',
            '</tpl>'
        )
    });

    var form = new Ext.form.FormPanel({
        renderTo:'form',
        title:'コンボボックスフォーム',
        height:280,
        width:500,
        bodyStyle:{
            padding:'8px'
        },
        footerStyle:{   //ボタン周りの表示の調整用スタイル
            border:'solid 1px #99BBE8',
            'border-top':'none'
        },
        labelWidth:180,
        items:[
            combo1,combo2,combo3
        ],
        buttonAlign:'center',
        buttons:[
            {
                text:'決定',
                iconCls:'tick',
                handler:function(){
                    //フォームパネルからフィールドを取得
                    var formFields = form.getForm();
                    //フィールドから値を取得
                    var formValues = formFields.getValues();
                    //入力項目を表示する処理(普通は値をポストしますが、今回はフィールド名と値を表示する)
                    var data = [];
                    Ext.iterate(formValues,function(key,val,arr){
                        data.push({
                            fieldname:key,
                            formvalue:val
                        });
                    });

                    var tpl = new Ext.XTemplate(
                        '<tpl for=".">',
                        '<p>{fieldname}:{formvalue}</p>',
                        '</tpl>'
                    );

                    //表示処理
                    Ext.Msg.show({
                        title:'フォームの値を取得',
                        msg:tpl.apply(data),
                        width:300,
                        buttons:Ext.Msg.OK
                    });
                }
            }
        ]
    });
});

実行結果:

ComboBoxの基本

ComboBoxの基本

上の2つが基本的なコンボボックスです。まずこの2つの解説です。
コンボボックスは基本的にテキストフィールドです。スーパークラスも以下のようになっています
Observable > Component > BoxComponent > Field > TextField > TriggerField > ComboBox
クリックできて、クリックすると選択項目がたちあがるTriggerFieldがコンボボックスです。同じような動きをするフィールドにDateFieldがあります。こちらはクリックするとDatePickerが立ち上がるTriggerFieldといえます。
選択項目はDataViewをして描写されます。すこしややこしくなってきましたが、Ext.form.ComboBoxクラスを使っているならば基本的に面倒なことはComboBoxクラスがやってくれます。基本的なコンフィグオプションを設定するだけでコンボボックスを作成できます。

コンボボックスで設定する基本的なコンフィグオプションは以下のようなものです。

  • name: フィールドの名前、getValuesしたときのプロパティ名になる
  • typeAhead: boolean 入力から項目を自動補完するかどうか
  • triggerAction: ▼をクリックしたときに送信するクエリを選択。’all’など
  • store: ストア
  • mode: ストアにデータ読み込む方法 local もしくは remote
  • displayField: コンボボックスの表示部分に設定するストアの項目
  • valueField: コンボボックスの値として設定するストアの項目
  • hiddenName コンボボックスの値として設定するストアの項目

typeAheadとtriggerActionで基本的な動作を制御します。typeAheadがtrueの場合、フィールドに入力を行うとそれに対応する項目が絞り込まれます。triggerActionでは▼をクリックしたときに読み込まれるデータを取得するためにサーバーに送信するクエリを選択します。’all’を指定します。全件を取得したくない場合はフィールドに入力されている項目を初期のクエリとしてサーバーに送信することができます。その場合は以下のように設定します。


 queryParam:'searchkeyword',
 triggerAction:'query',

queryParamに送信するプロパティ名、triggerActionを’query’に変更。これでコンボボックスの項目を取得する際にフィールドに入力されいる項目を送信します。ただしフィールドに入力がない場合は、サーバーへの取得を行わないので注意が必要です。

コンボボックスにもストアが必要です。今回は以前グリッドサンプルコードで使ったブラウザシェアのデータを使いたいと思います。そのためストアも以前のグリッドパネルとよく似ています。
一つ目が選択項目となるデータをJSファイルの中(ローカル)に持ってJsonStoreのdataに読み込んでいる形です。都度リクエストをかけることなく選択項目を表示します。2つ目はデータをリモートに持ちリクエストを投げてデータをストアに読み込みます。


new Ext.data.JsonStore({
	fields:['id','name','img'],
	url:'data.json',	//ローカルの場合はJSONデータを指定
	total:'total',
	root:'rows',
	autoLoad:true
})

modeの設定はストアの読み込み方法に応じて’local’と’remote’のどちらかを設定します。

displayFieldはストアのfieldsの中でコンボボックスの選択項目に表示される項目を指定します。今回はブラウザ名を表示させるためにnameを設定しました。
valueFieldはfieldsのなかで値として設定する項目を指定します。valueFieldで設定された値はhiddenNameに指定された名前でフォームの値としてgetValues()を事項したときに取得されます。
この辺りがコンボボックスの少しややこしいところです。nameは選択されている項目を表示するためのテキストフィールド名前です。nameの名前でフォームの値として設定されるのは表示されている文字列です。
表示は文字列で、実際に送信される値はidの数字がよい、といった場合は別途hiddenNameで設定する必要があります。今回のサンプルではcombo1、combo2の両方にvalueFieldが設定されています、しかしcombo1はhiddenNameが設定されていますが、combo2には設定されていません。この場合getValues()したときに取得されるのは

browser1:2 //ブラウザのID
combo2:Firefox //フィールドに表示されていた文字列

となります。フィールドに表示されている値ではないものを送信したい場合はcombo1のようにhiddenNameを設定するようにします。

以上が基本的なコンボボックスの設定です。

少しややこしい説明でしたが、まとめると

  • ストアを作る
  • ストアに応じてmodeを決める。
  • ストアに応じてdisplayFieldを決める。
  • もし表示している値でないものを送る場合はvalueFieldとhiddenNameを設定する。
  • 基本的にtriggerAction:’all’
  • 入力補完する場合はtypeAheadをtrueに

といった形です。

3つ目のコンボボックスはおまけえ、セレクトボックスの表示項目のデザインを変更しています。


var combo3 = new Ext.form.ComboBox({
		・・・
        itemSelector:'div.browser-list',
        tpl:new Ext.XTemplate(
            '<tpl for=".">',
                '<div class="browser-list" style="text-align:center;">',
                '<img src={img} width="50"/><br/>',
                '{name}',
                '</div>',
            '</tpl>'
        )
		・・・
    });

コンボボックスのtplのコンフィグオプションにXTemplateでテンプレートを設定します。DataViewのようにitemSelectorを設定してクリックするノードを指定します。サンプルコードではdiv.browser-listを指定しています。今回のテンプレートではブラウザの画像を表示するように設定しています。XTemplateとDataViewの知識があれば特に難しいことは無く、簡単にデザインを変更できます。

  • Share/Bookmark


佐竹 裕行

1982年生まれ。滋賀→はこだて→名古屋→大垣→名古屋。
2006年名古屋学芸大学映像メディア学科卒、その後IAMAS卒(Studio2、6期生)。2009年にsus4に入社。学生時代はMax/MSP JitterやGainerばっかり使っていたが、現在社内では主にExtとモバイル開発、動画サービスのバックエンドを担当。知る人ぞ知るアノ鍵の人。

2 Responses to 'ExtJS入門34 ComboBoxの基本'

Subscribe to comments with RSS or TrackBack to 'ExtJS入門34 ComboBoxの基本'.

  1. [...] ExtJS入門34 ComboBoxの基本 [...]

  2. [...] ExtJS入門34 ComboBoxの基本 [...]

コメントを残す

Get Adobe Flash playerPlugin by wpburn.com wordpress themes