預設的ExtJS 3.4版裡只有單純的下拉選單ComboBox的Form元件,假如要顯示的欄位數比較多時,像是顯示姓名、電話,選取後可以設值為使用者編號,就可以利用TriggerField來制作ComboGrid。
Ext.form.TriggerField是ComboBox、DateField、TimeField的父類別,可以直接輸入資料也可以利用選取來取得資料。
範例的的作法是把html元件tag input轉換成Ext.form.TriggerField,然後再針對這個TriggerField做onTriggerClick動作,來show選取Grid,選取Grid的內容,再setValue回去TriggerField,其中還有做了個小技巧,把TriggerField的name屬性值轉到另一個HiddenField裡,如此一來當Form Submit時,回傳的值才會正確。
上圖利用FireBug查看它的原始碼,可以看到有一個hidden的input會把選取的值存在這裡。
如果只給input的ID時,也會有預設的效果。
程式碼:
需要載入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>