用AOM作的editdatagrid的省市区三级连动,有些小技巧,记载在这里方便日后查看。直接贴代码。
基于AOM3.0,该版本建立在JSF1.2和Ext2.0RC上。grid有3列,分别是省市区,均为combo编辑器,编辑市时需要看前一列的省是什么,编辑区要看前一列的市是什么。这说明需要动态更换combo的store,难点在于多行编辑时,同一列的每行的编辑器都是不一样。这样编辑后面的行,前面的行数据就会由于匹配不到store的值而直接把value显示在页面上。覆盖Ext.form.ComboBox拦截匹配可解决该问题。
连动的基本思路是:
双击grid单元格进行编辑时,监听beforeedit事件:去看前一列是什么,根据前一列的值去后台请求该combo的模型值。
监听afteredit事件:需要清空后面列的数据,比如更换了省这一列,那么之前选的市和区都需要清空才行。
代码中还有些不完善的地方,这里只记录思路,以后用到了再改吧。

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
xmlns:h="http://java.sun.com/jsf/html" xmlns:ajax="http://www.apusic.com/jsf/ajax"
renderKitId="AJAX">
<w:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript">
<!--
/*
根据jsonObje, 更换相关combo的store
*/
function changeStore(comboJsvar, jsonObj){
//捕获分析jsonObj
//构造store
//加载数据 ;
var newdata = [];
for (var ind = 0; ind < jsonObj.length ; ind ++ ){
var obj = jsonObj[ind];
var record = [obj.value, obj.text];
//这里建立键值对
window.comboliandong.cachedText[comboJsvar.id+'_'+obj.value] = obj.text;
newdata.push(record);
}
var newstore = new Ext.data.SimpleStore({
fields:['value','text'],
data:newdata
});
comboJsvar.bindStore(newstore);
comboJsvar.fireEvent('load');
}
/*
省份的combo被选择了之后
*/
function provinceComboSelected(inputjson){
var citis = eval('(' + inputjson + ')').city;
changeStore(cityJsvar, citis);
}
/*
市的combo被选择了之后
*/
function cityComboSelected(inputjson){
var areas = eval('(' + inputjson + ')').area;
changeStore(areaJsvar, areas);
}
/*
清空相关combo.可用可不用,目前这里没用到该方法。
*/
function nullEveryCombo(){
changeStore(cityJsvar, "");
changeStore(areaJsvar, "");
}
function comboRenderer(v,m,r,row,col,s){
if ( !gridJsvar.getColumnModel() || !gridJsvar.getColumnModel().getCellEditor(col,row)){
return v;
}
//取到当前列的combo编辑器(唯一的),并以之为key去全局键值对中取text
var currentEditor = gridJsvar.getColumnModel().getCellEditor(col,row).field;
var text = window.comboliandong.cachedText[currentEditor.id+'_'+v];
if (text){
return text;
}
return v;
}
//-->
</script>
</w:head>
<w:page title="省市联动">
<w:form>
<w:editDataGrid id="editdatagrid" jsvar="gridJsvar" width="500" height="500" clicksToEdit="1" >
<w:pagingToolbar>
<w:button id="add"/>
<w:button id="del"/>
<w:button id="refresh"/>
</w:pagingToolbar>
<w:outputColumn id="id" hidden="true" />
<w:outputColumn id="province" header="省份" width="150" clientFormatter="comboRenderer" >
<w:combo id="provinceCombo" jsvar="provinceJsvar" emptyText="请选择省份" >
<f:selectItems id="provinceList"/>
</w:combo>
</w:outputColumn>
<w:outputColumn id="city" header="市" width="150" clientFormatter="comboRenderer" >
<w:combo id="cityCombo" jsvar="cityJsvar">
</w:combo>
</w:outputColumn>
<w:outputColumn id="area" header="区" width="150" clientFormatter="comboRenderer" >
<w:combo id="areaCombo" jsvar="areaJsvar">
</w:combo>
</w:outputColumn>
</w:editDataGrid>
</w:form>
<w:form>
<ajax:submitAction jsvar="submitaction" action="#{datagrid.shengshiliandongBean.queryComboStore}" />
</w:form>
</w:page>
<script type="text/javascript">
<!--
Ext.onReady(function(){
window.comboliandong = {};
window.comboliandong.cachedText = {};
Ext.override(Ext.form.ComboBox, {
setValue : function(v){
var text = v;
if(this.valueField){
var r = this.findRecord(this.valueField, v);
if(r){
text = r.data[this.displayField];
}else if (window.comboliandong.cachedText[this.id+'_'+v]) {
text = window.comboliandong.cachedText[this.id+'_'+v];
}else if(this.valueNotFoundText !== undefined){
text = this.valueNotFoundText;
}
}
this.lastSelectionText = text;
if(this.hiddenField){
this.hiddenField.value = v;
}
Ext.form.ComboBox.superclass.setValue.call(this, text);
this.value = v;
}
});
gridJsvar.on('afteredit',function(e){
var ind = e.column;
while( e.record.fields.keys[ind] != '_serverRowIndex'){
//如果表格有rowIndex这一列的话,最后一列是_serverRowIndex 要在该列之前终止。
e.record.data[e.record.fields.keys[ind++]] = '';
}
e.grid.getView().refresh();
});
gridJsvar.on('beforeedit',function(e){
if (e.column == 2){//如果列是 省份。则直接返回
return true;
}
//否则去看前一列是什么,然后去获取当前列的combo的数据。
var record = e.record;
var parentField = record.fields.keys[e.column -2];
var parentValue = record.data[parentField];
var currentCombo;
var ed = e.grid.colModel && e.grid.colModel.getCellEditor(e.column,e.row);
if (ed){
currentCombo = ed.field;
}
if (!currentCombo){
return false;
}
if (!parentValue){//父列的值是null,说明该列的combo也应该为null.停止编辑,直接返回
return false;
}
/*
拿到程序后可以在这里做缓存。
var cachedData = window.comboMap[parentField+'_'+parentValue];
if (!!cachedData){
var combojsvar = cachedData[0];
var combostore = cachedData[1];
changeStore(combojsvar, combostore);
return ;
}
*/
//根据父列的值去求本列的combo的值
submitaction.addParam('parentField',parentField);
submitaction.addParam('parentValue',parentValue);
submitaction.submit();
});
});
//-->
</script>
</f:view>