[ExtJS]TriggerField建立ComboGrid下拉選單

預設的ExtJS 3.4版裡只有單純的下拉選單ComboBox的Form元件,假如要顯示的欄位數比較多時,像是顯示姓名、電話,選取後可以設值為使用者編號,就可以利用TriggerField來制作ComboGrid。

Ext.form.TriggerField是ComboBox、DateField、TimeField的父類別,可以直接輸入資料也可以利用選取來取得資料。

ExtJs ComboGrid遠端stor

範例的的作法是把html元件tag input轉換成Ext.form.TriggerField,然後再針對這個TriggerField做onTriggerClick動作,來show選取Grid,選取Grid的內容,再setValue回去TriggerField,其中還有做了個小技巧,把TriggerField的name屬性值轉到另一個HiddenField裡,如此一來當Form Submit時,回傳的值才會正確。

上圖利用FireBug查看它的原始碼,可以看到有一個hidden的input會把選取的值存在這裡。

FireBug ComboGrid

如果只給input的ID時,也會有預設的效果。

ComboGrid預設

FireBug查看預設的ComboGird實際值

範例Demo

程式碼:

需要載入ExtJS

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

JavaScript

var ComboGrid = function(param) {
    var options = {
        valueField : 'value',
        textField : 'text',
        autoLoad : false,
        store : new Ext.data.SimpleStore({
            data : [ [ 'text1', 'valu1' ], [ 'text2', 'valu2' ] ],
            fields : [ 'text', 'value' ]
        }),
        columns : [ {
            header : '資料',
            dataIndex : 'text'
        } ]
    };
    Ext.applyIf(param, options);
    this.el = Ext.fly(param.applyId);

    var valueField = param.valueField;
    var textField = param.textField;

    var store = param.store;

    var columns = param.columns;
    if (param.autoLoad) {
        store.load();
    }
    this.grid = new Ext.grid.GridPanel({
        width : 300,
        autoScroll : true,
        height : 200,
        store : store,
        columns : columns,
        viewConfig : {
            forceFit : true
        }
    });

    this.inputVal = new Ext.form.Hidden({
        name : this.el.getAttribute("name"),
        value : this.el.getAttribute("value")
    });
    this.el.dom.setAttribute("name", Ext.id());
    var idx = store.find(valueField, this.el.getAttribute("value"));
    // console.log(idx);
    if (idx >= 0) {
        this.el.setValue(store.getAt(idx).get(textField));
    }

    this.selectMenu = new Ext.menu.Menu({
        items : [ this.grid ]
    });

    this.field = new Ext.form.TriggerField({
        fieldLabel : '選擇',

        onSelect : function(record) {
        },
        onTriggerClick : function(e) {

            this.selectMenu.show(this.field.el, "tl-bl?");
        }.createDelegate(this)

    });
    this.el.on("click", function(e) {
        this.selectMenu.show(this.field.el, "tl-bl?");
    }.createDelegate(this));
    this.grid.on('rowclick', function(grid, rowIndex, e) {
        this.selectMenu.hide();
        var selections = this.grid.getSelectionModel().getSelections();
        if (selections.length == 0) {

            return;
        }

        for ( var i = 0; i < selections.length; i++) {
            var record = selections[i];
            this.field.setValue(record.get(textField));
            this.inputVal.setValue(record.get(valueField));
        }

    }.createDelegate(this));
    this.field.applyToMarkup(param.applyId);
    var parent = this.el.parent("form");

    if (!parent)
        parent = this.el.parent();
    this.inputVal.render(parent);

};
Ext.onReady(function() {
    new ComboGrid({
        applyId : 'xxx'
    });
    new ComboGrid({
        applyId : 'xxx2',
        valueField : 'field3',
        textField : 'field1',
        autoLoad : false,
        store : new Ext.data.SimpleStore(
                {
                    data : [ [ '王先生', '0933111000', '1' ],
                            [ '李小姐', '0922222111', '2' ] ],
                    fields : [ "field1", "field2", "field3" ]
                }),
        columns : [ {
            header : '姓名',
            dataIndex : 'field1',
            width : 80
        }, {
            header : '電話',
            dataIndex : 'field2'
        } ]
    });
});

html

<div
        style="padding-top: 30px; padding-left: 30px; width: 500px; float: left">
        <hr style="width: 100%; border: 1px solid gray" />
        <fieldset style="margin: 10 10 10 10; height: 100px">
            <legend>使用預設值時:</legend>
            <table width="100%" height="100%" border="0">
                <tr valign="middle">
                    <td align="center"><input id="xxx" name="name1" value="value1" />
                    </td>
                </tr>
            </table>
        </fieldset>
    </div>
    <div
        style="padding-top: 30px; padding-left: 30px; width: 500px; float: left">

        <hr style="width: 100%; border: 1px solid gray" />
        <fieldset style="margin: 10 10 10 10; height: 100px">
            <legend>自己設定store:</legend>

            <table width="100%" height="100%" border="0">
                <tr valign="middle">
                    <td align="center"><input id="xxx2" name="name2" value="" />
                    </td>
                </tr>
            </table>
        </fieldset>
    </div>

發表迴響