JSP中的元素定义:
<th field="typeMaskValues" width="150" sortable="false" align="center" formatter="typeMaskFormatter" editor="{type:'combobox',
options:{
multiple:true,
required:true,
url:'iface/findTypeMaskList',valueField:'key',textField:'value',panelHeight:150,
//editable:false,
onHidePanel: onHidePanel,
onShowPanel:onShowPanel,
onChange:onChange,
onLoadSuccess:function(data){
zdyComboboxArray = data;
}
}}">类别掩码
</th>
下拉框的各个函数的定义:
/**
* 下拉面板展开事件
*/
function onShowPanel(){
console.info("onShowPanel");
}
/**
* 下拉面板选择事件
*/
function onChange(){
console.info("onChange");
}
/**
* datagrid的复选框隐藏面板事件
*/
function onHidePanel(){
console.info("hidepanel");
var textField = $('.datagrid-editable-input').val();
//下拉框必选,不能为空
if(comboboxValue.value && textField && textField!=comboboxValue.value){
//单选框
//var valueField = $('.datagrid-editable-input').next().next().val();
//复选框有多个input
var multipleInputs = $('.datagrid-editable-input').nextAll(':input');
var multipleInputsVal = new Array();
var j = 0;
for(var i=0;i<multipleInputs.length;i++){
var multipleInput = multipleInputs[i];
var multipleInputVal = multipleInput.value;
if(multipleInputVal){
multipleInputsVal[j] = multipleInputVal;
j++;
}
}
var row = comboboxValue.row;
row.typeMaskValues = multipleInputsVal;
row.typeMaskTexts = textField;
var options = {};
options.onAfterSubmit = afterSubmit;
_destroyCellEditor($(comboboxValue.id)[0],{index:comboboxValue.rowIndex,field:comboboxValue.field});
onAfterEditing(comboboxValue.rowIndex,row,comboboxValue.changes,comboboxValue.id,comboboxValue.url,new Array(),options);
endEditing(comboboxValue.id);//此行代码让编辑框被销毁之后还能够再次打开编辑器(例如双击打开)
}else{
_destroyCellEditor($('#_list')[0],{index:_rowIndex,field:_field});
endEditing('#_list');
comboboxValue["data"] = comboboxValue.row;
afterSubmit(comboboxValue.rowIndex, comboboxValue.row, "",comboboxValue,comboboxValue.id);
}
_rowIndex = undefined;
_field = undefined;
_rowId = undefined;
comboboxValue = {};
}
为可编辑的单元格设置边框:
//为可编辑的单元格设置外边框
//来自jquery.easyui.1.8.0.js的 function _4d8()方法
function _outerWidthOfEditable(target) {
var dc = $.data(target, "datagrid").dc;
dc.view.find("div.datagrid-editable").each(function () {
var _this = $(this);
var field = _this.parent().attr("field");
var col = $(target).datagrid("getColumnOption", field);
_this._outerWidth(col.width);
var ed = $.data(this, "datagrid.editor");
if (ed.actions.resize) {
ed.actions.resize(ed.target, _this.width());
}
});
}
单元格编辑函数:
//开启编辑单元格状态
function beginEditCell(target, options) {
// var opts = $.data(target, "datagrid").options;
// var tr = opts.finder.getTr(target, options.index);
// var row = opts.finder.getRow(target, options.index);
// //暂时还不知道该代码的含义,忽略使用
// if (tr.hasClass("datagrid-row-editing")) {
// return;
// }
// tr.addClass("datagrid-row-editing");
_initCellEditor(target, options.index, options.field);
_outerWidthOfEditable(target);
// $.validateRow(target, options.index);暂时先不使用,不知道该方法作用
}
初始化表格编辑器:
/**
* 初始化表格编辑器
*/
function _initCellEditor(target, _index, _field) {
var opts = $.data(target, "datagrid").options;
var tr = opts.finder.getTr(target, _index);
var row = opts.finder.getRow(target, _index);
tr.children("td").each(function () {
var cell = $(this).find("div.datagrid-cell");
var field = $(this).attr("field");
if (field == _field) {//找到与传递参数相同field的单元格
var col = $(target).datagrid("getColumnOption", field);
if (col && col.editor) {
var editorType, editorOp;
if (typeof col.editor == "string") {
editorType = col.editor;
} else {
editorType = col.editor.type;
editorOp = col.editor.options;
}
var editor = opts.editors[editorType];
if (editor) {
var html = cell.html();
var outerWidth = cell._outerWidth();
cell.addClass("datagrid-editable");
cell._outerWidth(outerWidth);
cell.html("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td></td></tr></table>");
cell.children("table").bind(
"click dblclick contextmenu",
function (e) {
e.stopPropagation();
});
$.data(cell[0], "datagrid.editor", {
actions: editor,
target: editor.init(cell.find("td"),
editorOp),
field: field,
type: editorType,
oldHtml: html
});
}
}
$('.datagrid-editable').css('height','auto');//设置包裹该editorde的div的样式
$('.datagrid-editable-input').css("line-height","");//设置编辑框的样式
tr.find("div.datagrid-editable").each(function () {
var field = $(this).parent().attr("field");
var ed = $.data(this, "datagrid.editor");
var val = row[field];
if(ed.type == 'combobox'){
//获取编辑器的对应的元素的下拉框的属性集合
var opts = $(ed.target).combobox("options");
//判断下拉框是否为多选(因为多选的话,在调用setValue方法的时候,会调用val的split方法,如果不包含分隔符",",会报错)
if(opts.multiple){
val = val+",";
}
}
ed.actions.setValue(ed.target, val);
});
}
});
}
销毁表格编辑框:
//销毁单元格编辑器
function _destroyCellEditor(target, options) {
var opts = $.data(target, "datagrid").options;
var tr = opts.finder.getTr(target, options.index);
tr.children("td").each(function () {
var field = $(this).attr("field");
if (field == options.field) {//找到与传递参数相同field的单元格
var cell = $(this).find("div.datagrid-editable");
if (cell.length) {
var ed = $.data(cell[0], "datagrid.editor");
if (ed.actions.destroy) {
ed.actions.destroy(ed.target);
}
cell.html(ed.oldHtml);
$.removeData(cell[0], "datagrid.editor");
cell.removeClass("datagrid-editable");
cell.css("width", "");
}
}
});
}
单元格编辑之后执行:
function onAfterEditing(rowIndex,row,changes,id,url,arrays,options){
var saveData=save(rowIndex,row,changes,id,url,arrays,options);
row=saveData[0];
changes=saveData[1];
afterEdit(rowIndex,row,changes,id);
}
单元格编辑之后向后台发送POST请求:
/**
* @param row编辑完单元格修改保存数据
* @param changes
* row 是修改之后的row,而不是原来的row
* @returns {Array}[0]表示row,[1]表示changes
*/
function save(index,row,changes,id,url,arrays,options)
{
var data={"id":row.id};
for (var key in row)
{
if (!$.isArray(row[key]) && !$.isFunction(row[key])
&& (typeof row[key]) == "object")
{
continue;
}
data["object."+key]=row[key];
}
$.post(url,data,function(data){
var obj=eval('('+data+')');
if (obj && obj.returnCode==1)
{
if (options && options.onAfterSubmit && $.isFunction(options.onAfterSubmit))
{
options.onAfterSubmit(index, row, changes,obj,id);
}
return;
}
//$("#_list").datagrid('rejectChanges'); //出错回滚
$("#_list").datagrid('reload');
$.messager.alert('错误',obj.message,'error');
});
var saveData=new Array();
saveData[0]=row;//用来作为datagrid的updateRow的参数用,注意有些特例,该row虽然是更改后的row,但是有些需要传递到action中的值并没有发生变化,例如queryRateValues.jsp.js
saveData[1]=changes;
return saveData;
}
不重载datagrid,而是单独刷新被修改的行:
function afterEdit(rowIndex, rowData, changes,id){
$(id).datagrid('updateRow',{
index: rowIndex,
row: rowData
});
$(id).datagrid('acceptChanges');
}
field的formatter事件:
/**
* 根据typeCode查询下拉框的列表值
* @param value
* @param row
* @returns {String}
*/
function typeMaskFormatter(value,row){
this.editor.options.url = "iface/findTypeMaskList?object.typeCode="+row.typeCode;
return row.typeMaskTexts;
}
值得注意的是:这么写还不能动态的根据row的typeCode的值来设定该行编辑器combobox的url,这个url是table的表头中的url,虽然在每个行初始化的时候都设定了options的url,但是实际上修改的是同一个元素的url的值,即每次进入formatter函数中,是重新设定了options的url,所以需要在单击事件中跟新每一行:调用datagrid的refresh方法即可:
datagrid的表格双击事件:
onDblClickCell: function(rowIndex, field, value){
//return false;
var rowData = $(table).datagrid('getRowData',rowIndex);
onClickRow(rowIndex, field, value,id,url,arrays,options);
},
通用onClickRow()函数:
/**
* 开启单击单元格
*
*/
var _rowIndex = undefined;
var _field = undefined;
var _rowId=undefined;
function onClickRow(rowIndex, field, value,id,url,arrays,options) {
var columnOption=$(id).datagrid("getColumnOption",field);
if(columnOption && columnOption.readonly == true)
return false;
$(id).datagrid("refreshRow", rowIndex);//这行很关键,是实现combobox动态设定url,每次刷新行,也会刷新这一列的combobox的editor属性,刚好借用来刷新url...
if (_rowIndex != rowIndex || _field != field) {
if (endEditing(id)){
$(id).datagrid('selectRow',rowIndex);
$(id).datagrid('beginEditCell', {index: rowIndex, field: field});
var ed = $(id).datagrid('getEditor', {index:rowIndex,field:field});
if(ed == null)
return false;
_rowIndex = rowIndex;
_field = field;
_rowId=id;
var row=$(id).datagrid("getRowData",rowIndex);
if(ed.type == 'combobox'){
//只要下拉框被编辑,那么就点击倒三角形,打开下拉面板选项
$(".datagrid-editable-input").next('span').find('.combo-arrow').click();
$(".datagrid-editable-input").focus();
comboboxValue.row= row;
}else{
$(".datagrid-editable-input").focus(function(){
this.select();
});
$(ed.target).focus();
}
$(".datagrid-editable-input").blur(function(){
var changes={};
if(ed.type=='combobox'){
//需要注意的是:如果是下拉框,分为两种情况:
//1.点击了下拉面板,那么先执行.datagrid-editable-input的blur()事件,此时comboboxValue被赋值,再执行onHidePanel事件
//2.没有点击下拉面板,只是点击了面板的其他地方而失去焦点,那么会先执行onHidePanel事件,再执行.datagrid-editable-input的blur()事件,此时comboboxValue并没有被赋值(只是被赋值了一个row属性,其他属性没有被赋值)
//1和2两种情况,下拉编辑框的关闭都是放到onHidePanel中执行
comboboxValue.id = id;
comboboxValue.rowIndex = rowIndex;
comboboxValue.field = field;
changes['status'] = "p";
// comboboxValue.row = row;
comboboxValue.url = url,
comboboxValue.changes = changes;
comboboxValue.value = $(".datagrid-editable-input").val();
}else {
if(ed.type=='checkbox'){
_destroyCellEditor($(id)[0],{index:rowIndex,field:field});
var state = $(this).prop('checked');
var obj = checkbox(row,state);
if(obj.state){
changes["status"]="P";
onAfterEditing(rowIndex,row,changes,id,url,arrays,options);
}
}else{
_destroyCellEditor($(id)[0],{index:rowIndex,field:field});
var oldVal=row[field];
var newVal=this.value;
if(oldVal!=newVal){//值有改变
changes[field]=newVal;
row[field]=newVal;
changes["status"]="P";
onAfterEditing(rowIndex,row,changes,id,url,arrays,options);
}
}
//因为在下拉框的onHidePanel中需要用到这两个变量,所以这两个变量的置空要放到hiddenpanel中执行
_rowIndex = undefined;
_field = undefined;
}
});
var rows=$(id).datagrid("getRows");
$(ed.target).bind('keydown', function()
{
switch (window.event.keyCode) {
case 13://enter
$(this).blur();
endEditing(id);
event.returnValue=false;
if(rowIndex<rows.length-1){
onClickRow(rowIndex+1,field,value,id,url,arrays,options);
}
break;
case 37://left
$(this).blur();
//停止上一个框的编辑
endEditing(id);
//禁止默认键盘事件
event.returnValue=false;
var prevfiled=$(id).datagrid("prevColumn",field);
if(prevfiled!=null&&prevfiled.editor){
onClickRow(rowIndex,prevfiled.field,value,id,url,arrays,options);
}
break;
case 38://up
$(this).blur();
endEditing(id);
event.returnValue=false;
if(rowIndex>0){
onClickRow(rowIndex-1,field,value,id,url,arrays,options);
}
break;
case 39://right
$(this).blur();
endEditing(id);
event.returnValue=false;
var nextfiled=$(id).datagrid("nextColumn",field);
if(nextfiled!=null&&nextfiled.editor){
onClickRow(rowIndex,nextfiled.field,value,id,url,arrays,options);
}
break;
case 40://down
$(this).blur();
endEditing(id);
event.returnValue=false;
if(rowIndex<rows.length-1){
onClickRow(rowIndex+1,field,value,id,url,arrays,options);
}
break;
case 27:// Escape Escape
$(this).blur();
endEditing(id);
break;
}
});
}
}
return true;
}
附上datagrid的combobox的单选框:
<th field="makeRule" width="150" sortable="false" align="center" formatter="makeRuleFormatter" editor="{type:'combobox',
options:{required: true,url:'iface/findMakeRuleList',valueField:'key',textField:'value',panelHeight:100,
onHidePanel: function()
{
var textField = $('.datagrid-editable-input').val();
if(comboboxValue.value && textField!=comboboxValue.value){
var valueField = $('.datagrid-editable-input').next().next().val();
var row = comboboxValue.row;
row.makeRuleName = textField
row.makeRule = valueField;
_destroyCellEditor($(comboboxValue.id)[0],{index:comboboxValue.rowIndex,field:comboboxValue.field});
onAfterEditing(comboboxValue.rowIndex,row,comboboxValue.changes,comboboxValue.id,comboboxValue.url);
endEditing(comboboxValue.id);//此行代码让编辑框被销毁之后还能够再次打开编辑器(例如双击打开)
}else{
_destroyCellEditor($('#_list')[0],{index:_rowIndex,field:_field});
endEditing('#_list');
}
_rowIndex = undefined;
_field = undefined;
comboboxValue = {};
},
onLoadSuccess:function(data){
zdyComboboxArray = data;
}
}}">对应编制办法
</th>
另外设置combobox的显示的text和value:
//类别掩码的类型集合,以","号连接,用来做下拉框的value,因为下拉框可以多选,所以这里使用集合ArrayList或者数组
private List<Integer> typeMaskValues;
//显示类别掩码的名称,用来做下拉框的显示用,可以是集合ArrayList或者数组
private List<String> typeMaskTexts;
public List<Integer> getTypeMaskValues() {
return typeMaskValues;
}
public void setTypeMaskValues(List<Integer> typeMaskValues) {
this.typeMaskValues = typeMaskValues;
}
public List<String> getTypeMaskTexts() {
return typeMaskTexts;
}
public void setTypeMaskTexts(List<String> typeMaskTexts) {
this.typeMaskTexts = typeMaskTexts;
}
datagrid的editor的target是一个combobox,通过调用它的setValue来设定combobox的value值,然后combobox的会根据它的value值来设定显示值,即能够在input框中看到的文本值,同时让下拉列表的对应的选项处于选中状态;如果combobox是单选,那么会直接根据combobox的value值来设定显示值,同时选中列表选项;如果为多选,那么会根据combobox的value值,先调用split(",")方法得到value的数组,然后循环数组,根据其中的每个value的值设定显示值text(text是追加上去的),同时循环选中下拉列表对应的选项.
效果图:
datagrid的类别掩码显示:
双击单元格,开启编辑,单元格的editor为下拉框,向后台发送不同的请求url,返回指定列表: