常规功能和模块自定义系统 (cfcmms)—023自定义grid列(7子模块记录数)
还有一种有用的自定义列需要加入,这种列和模块之间的关联关系有关。对于一个父模块来说,可能想要显示当前父模块记录下的子模块(孙模块)的个数,然后鼠标移上去的时候还能显示子模块的具体名称。看看下图的例子:
一个相对完整的功能就是一个子模块个数的列,可以显示当前记录的子模块记录数的个数,并且个数上显示子模块所有名称的tooltip,并且单击可以进入以当前记录为约束条件的子模块。这个功能对于本系统来说只要进行配置即可,在已经发布的cfcmms试用版中除了没有tooltip的功能,另外二个功能已经提供。
下面来完成配置过程,并提供前后台的代码。
1、模块的附加字段:在“系统模块”中,选中省份模块,点击附加字段。选中可计数模块中的“市”,和可求金的字段中的“金额属性”。
为什么要在这里选择附加字段呢,因为在sql语句生成的时候,需要根据这里的选择字段来加入附加字段。前面几节在讲附件列的时候,贴出过一个sql语句,里面是加入了附件个数和附件tooltip的字段。在选择了有附加字段之后,我们来看看sql语句有什么新的变化。
</pre><pre name="code" class="sql"> select
( select
count(*)
from
_Attachment
where
tf_moduleId = '7010'
and tf_moduleIdValue = _t7010.tf_provinceId ) as tf_attachmentCount ,
getAttachmentNames( '7010',
_t7010.tf_provinceId ) as tf_attachmentTooltip ,
。。。。。。
( select
count(*)
from
City _t7012
left outer join
Province _child_t7010
on _child_t7010.tf_provinceId = _t7012.tf_provinceId
where
(
(
_child_t7010.tf_provinceId=_t7010.tf_provinceId
)
) ) as C_City , //每一个省份市的个数
( select
sum(_t7012.tf_money)
from
City _t7012
left outer join
Province _child_t7010
on _child_t7010.tf_provinceId = _t7012.tf_provinceId
where
(
(
_child_t7010.tf_provinceId=_t7010.tf_provinceId
)
) ) as S__t7012___tf_money // 每一个省份市的“金额属性”的汇总数
from
Province _t7010 limit ?
在上面的语句中加入了二个字段:C_City和 S_t7012___tf_monty。这二个字段将随着“省份”的自有字段一起被传送到前台。
2、在grid列选择字段的时候,加入这些列。
经过这样的操作,可以达到本章第一个图的加入了子模块个数列的效果。
下面来具体看看这个类的实现和tooltip的加载过程。
类ChildCountColumn的代码如下:
/**
*
* 在模块的列表中显示了子模块,孙模块的记录数,加外链接,点击,可以直接打开该模块,并加上本记录的筛选值
*
*/
Ext.define('app.module.widget.column.ChildCountColumn', {
extend : 'Ext.grid.column.Column',
alias : 'widget.childcountcolumn',
align : 'center',
initComponent : function() {
this.menuText = this.text;
this.text = this.text.replace('个数',
'<br/><span style="color : green;">个数</span>');
this.callParent();
},
renderer : function(val, metaData, model, row, col, store, gridview) {
if (val) {
var column = gridview.headerCt.getGridColumns()[col];
// 把childModuleName的值加到span的属性里面,以后要用到
var result = '<span class="childCountColumn" childModuleName="'
+ column.moduleName + '">' + val + '个</span>';
return result;
}
},
listeners : {
afterrender : function(column) {
// 把column header的数值的居右去掉,让标题显示在居中的位置。内容仍然是居右
column.getEl().removeCls('x-column-header-align-right');
column.getEl().addCls('x-column-header-align-center');
// render的时候,不能取到gridpanel的view,因此需要延时500毫秒来执行这段代码
Ext.defer(function() {
var view = column.up('gridpanel').getView();
// 创建这个列的tooltip
column.tip = Ext.create('Ext.tip.ToolTip', {
showDelay : 1000,
// closable : true,
// autoHide : false,
hideDelay : 0,
target : view.el,
delegate : '.childCountColumn', // 这个属性是上面renderer里面的class的名称
trackMouse : false,
listeners : {
beforeshow : function updateTipBody(tip) {
var record = view.getRecord(tip.triggerElement);
var id = record.getIdValue();
var childModule = tip.triggerElement
.getAttribute('childModuleName');
var tooltip = '';
// 在这里通过一个同步ajax来取得当前记录的子模块的所有名称
Ext.Ajax.request({
async : false, // 同步
method : 'get',
url : 'module/getChildModuleDetail.do',
params : {
moduleName : record.module.tf_moduleName,//当前模块
id : id,//模块id
childModuleName : childModule //需要取得的子模块tooltip的名称
},
success : function(response) {
var records = eval(response.responseText);
for ( var i in records)
tooltip += '<li>' + records[i].text + "</li>";
}
})
// 更新tooltip
tip.update('<ol class="gridcelltooltip">' + tooltip + '</ol>');
}
}
});
}, 500);
}
},
processEvent : function(type, view, cell, recordIndex, cellIndex, e, record,
row) {
if (type === 'click') {
// 在记数个数上单击后,打开子模块,并且加上当前记录为你模块的约束值
if (e.getTarget().className === 'childCountColumn') {
var column = view.headerCt.getGridColumns()[cellIndex];
column.tip.hide(); // 隐藏tooltip,不然的话还会显示一段时间,效果不好
app.mainRegion.addParentFilterModule(column.moduleName,
record.module.tf_moduleName, record.get(record.idProperty), record
.getTitleTpl());
}
}
}
})
这个类中取得子模块tooltip的过程是一个同步的ajax。这个过程和前面讲过的附件个数的tooltip的获取过程不一样,附件的tooltip是直接加在数据里的,这个是通过ajax到后台取得。每触发一次tooltip都会有一个ajax请求到后台,并且会生成一个sql查询。比如说我移到了最上面图的“江苏省”的市的记录个数上面,就会有下面的sql语句显示在后台输出:
select
_t7012.tf_cityId as tf_cityId ,
_t7012.tf_name as tf_name
from
City _t7012
left outer join
Province _t7010
on _t7010.tf_provinceId = _t7012.tf_provinceId
where
(
(
_t7010.tf_provinceId='07'
)
)
order by
tf_cityId asc
后台的处理过程是应用了spring mvc 的机制。在ModuleController.java中,来处理了这个请求。
@Controller
@RequestMapping(value = "/module")
public class ModuleController implements IModuleService {
@Resource
private SystemBaseDAO systemBaseDAO;
@Resource
private ModuleService moduleService;
@Resource
private PrintRecordService printRecordService;
@Resource
private UploadExcelService uploadExcelService;
@Resource
private ModuleDAO moduleDAO;
private static final Log log = LogFactory.getLog(ModuleController.class);
@RequestMapping(value = "/getChildModuleDetail.do", method = RequestMethod.GET)
public @ResponseBody Object getChildModuleDetail(String moduleName, String id,
String childModuleName, String childField, HttpServletRequest request) {
return moduleDAO.getChildModuleDetail(moduleName, id, childModuleName, childField, request);
}
......
}
根据spring mvc的配置,上面的ajax将会调用ModuleController中的getChildModuleDetail函数,然后返回一个Object给前台。