[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>

發表迴響