Easyui動態顯示列的應用例項
1、前言
專案中一個考勤資訊功能,考勤資訊的資料表結構如下:
CREATE TABLE `t_attendance` (
`id` varchar(50) NOT NULL,
`beautician_id` varchar(50) NOT NULL COMMENT '美容師id',
`att_date` date DEFAULT NULL COMMENT '考勤日期',
`att_type` tinyint(4) DEFAULT NULL COMMENT '考勤型別:1:出勤;2:出勤半天;3:請假;4:遲到;5:曠工;6:休假;',
`late_min` int (11) DEFAULT NULL COMMENT '遲到分鐘數',
`leavebill_min` int(11) DEFAULT NULL COMMENT '請假分鐘數',
`summary` text COMMENT '備註',
`create_date` date DEFAULT NULL COMMENT '建立日期',
`update_date` date DEFAULT NULL COMMENT '修改日期',
`update_id` varchar(50) DEFAULT NULL COMMENT '修改id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考勤資訊'
考勤表資料如下圖:
客戶要求實現的介面樣式如下圖:
說明:根據年月查詢店鋪員的考勤資訊,每個月份的天數是不一樣的,5月份31天,6月份30天,2月份根據年份的不同,天數也不一樣。所以上圖的datagrid列表中的列是動態變化的。
A、該功能需求用的技術、知識點
1、MySql行轉列、group_concat(此處可參考本人之前blog MySql行轉列、group_concat使用)
2、js中動態建立datagrid列
3、EasyUi日期控制元件datebox設定,只顯示年月,也只能選擇年月。該問題檢視本人的blog
4、EasyUi點選單元格檢視、編輯員工某一天的考勤資訊
2、程式碼實現
1、圖中datagrid的列分兩種,員工姓名是frozenColumns,
列,其他動態列是columns。
att.jsp頁面程式碼片段
//獲取年月日期框的年月值
var attYearMonthStr = $("#attYearMonth").datebox("getValue");
//${headerString}是獲取跳轉到att.jsp頁面時後臺丟取的列集合資料字串
//${headerString}字串的內容為'2017-06-01,2017-06-02 ...省略 2017-06-30'
var headerString = '${headerString}';
//將字串轉換為datagrid的column的data,然後在頁面中可以直接用colObjArr
var colObjArr = covertHeader(headerString);
//建立考勤datagrid
var attDataGrid = $('#attDataGrid').datagrid({
url : '${pageContext.request.contextPath}/shop/att/queryAtts.do?attYearMonth=' +attYearMonthStr ,
fit : true,
fitColumns : false,
border : false,
idField : 'id',
remoteSort: false,
singleSelect:true,
checkOnSelect : true,
selectOnCheck : true,
nowrap : true,
showPageList:false,
frozenColumns : [ [ {
field : 'id',
title : '編號',
width : 120,
hidden : true
},{
field : 'name',
title : '員工姓名',
width : 120,
align:'center'
}
]],
//使用後臺丟取的資料動態載入動態列
columns:[colObjArr],
//下面的是測試資料,(也可以理解為示例資料)
/* columns:[ [ {
field : '2017-06-01',
title : '2017-06-01',
width : 100,
align:'center',
formatter: function (value, rowData, rowIndex) {
if(value == null){
return "";
}else if(value == '出勤'){
return value;
}else{
return '<font color="red">'+value+'</font>';
}
}
},{
field : '2017-06-02',
title : '2017-06-02',
width : 100,
align:'center',
formatter: function (value, rowData, rowIndex) {
if(value == null){
return "";
}else if(value == '出勤'){
return value;
}else{
return '<font color="red">'+value+'</font>';
}
}
}]], */
toolbar : '#attToolbar',
onLoadSuccess : function() {
$(this).datagrid('clearChecked');
$(this).datagrid('clearSelections');
},
onSelect : function(rowIndex, rowData){
},
onClickRow: function (rowIndex, rowData) {
$(this).datagrid('unselectRow', rowIndex);
},
//單擊單元格
onClickCell:function(rowIndex, field, value){
//根據rowIndex獲取datagrid的行
var row = $('#attDataGrid').datagrid('getData').rows[rowIndex];
//通過row獲取員工id
var beauticianId = row.id;
//獲取列頭,實際上就是員的考勤日期
var attDate = field;
//彈出考勤設定頁面
showAtt(beauticianId,attDate);
}
}
});
covertHeader轉換函式:
根據列資料動態生成datagrid的列data。
//動態新增列,將字串轉換為datagrid的column的data
function covertHeader(headerString){
//datagrid的columns集合
var colObjArr = new Array();
if(headerString){
var headArr = headerString.split(',');
for(var i = 0;i < headArr.length; i++) {
var fieldName = headArr[i];
//建立一個column列物件
var colObj = new Object();
//設定field屬性
colObj['field'] = fieldName;
//設定title屬性
colObj['title'] = fieldName;
colObj['width'] = '120';
colObj['align'] = 'center';
colObj['formatter'] = function(value,rowData,rowIndex){
if(value == null){
return "";
}else if(value == '出勤'){
return value;
}else{
return '<font color="red">'+value+'</font>';
}
};
//將建立的column列物件新增到columns集合
colObjArr.push(colObj);
}
}
return colObjArr;
}
controller跳轉到att.jsp頁面的程式碼
/**
* 跳轉考勤資訊頁面
* @return
*/
@RequestMapping("/goToAttJsp")
public String goToAttJsp(HttpServletRequest request){
try {
//獲取當前月的第一天
Date beginDate = DateUtil.getCurrentMonthFirstDay();
//獲取當前月的天數
int days = DateUtil.getCurrentMonthDaysCount();
//當前月的日期集合
String[] dateArr = new String[days];
for (int i = 0; i < dateArr.length; i++) {
//當月的第一天加i
Date tempDate = DateUtil.dateAddToDate("d", i, beginDate, "yyyy-MM-dd");
//將當月的第i天新增到當月的日期集合中
dateArr[i] = DateUtil.datetoStr(tempDate, "yyyy-MM-dd");
}
//動態拼裝datagrid列頭資訊
String headerString = StringUtil.join(dateArr, ",");
request.setAttribute("headerString", headerString);
return "/views/shop/att/att";
} catch (Exception e) {
log.error("跳轉考勤資訊頁面失敗",e);
}
return "/error/500";
}
考勤列表datagrid通過url /shop/att/queryAtts.do載入資料的程式碼:
controller資料:
/**
* 查詢某店鋪的某個月份的所有考勤資訊
* @param attYearMonth 考勤年月
* @param request
* @return
*/
@ResponseBody
@RequestMapping("/queryAtts")
public List<Map<String,Object>> queryAtts(String attYearMonth){
try {
//根據動態列封裝的動態資料
List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
//查詢某個店鋪某個月的考勤資訊
List<Object[]> rows = attendanceService.queryAttendances(Constant.SHOP_ID, attYearMonth);
if(rows != null && rows.size() > 0){
for(Object[] row : rows){
//考勤id
String id = row[0].toString();
//員工姓名
String name = row[1].toString();
//員工某個月份考勤日期集合字串
String att_dates = row[2].toString();
//員工某個月份考勤型別集合字串
String att_types = row[3] == null ? "" : row[3].toString();
//員工某個月份遲到分鐘數集合字串
String late_mins = row[4] == null ? "" : row[4].toString();
//員工某個月份請假分鐘數集合字串
String leavebill_mins = row[5] == null ? "" : row[5].toString();
Map<String,Object> map = new HashMap<String,Object>();
map.put("id", id);
map.put("name", name);
if(StringUtil.notNull(att_dates)){
//員工某個月份考勤日期集合陣列
String[] attDateArr = att_dates.split(",");
//員工某個月份考勤型別集合陣列
String[] attTypeArr = att_types.split(",");
//員工某個月份遲到分鐘數集合陣列
String[] lateMinAtt = late_mins.split(",");
//員工某個月份請假分鐘數集合陣列
String[] leavebillMinAtt = leavebill_mins.split(",");
for (int i = 0; i < attDateArr.length; i++) {
if(StringUtil.notNull(attTypeArr[i])){
//考勤型別
int attType = Integer.parseInt(attTypeArr[i]);
//考勤資訊
String attInfo = getAttInfo(attType);
if(attType == 3){
//請假分鐘數
attInfo += " :" + leavebillMinAtt[i] + "分";
}else if(attType == 4){
//遲到分鐘數
attInfo += " :" + lateMinAtt[i] + "分";
}
//設定員工某一天的考勤資訊
map.put(attDateArr[i], attInfo);
}
}
}
result.add(map);
}
}
return result;
} catch (Exception e) {
log.error("查詢某店鋪的某個月份的所有考勤資訊失敗",e);
}
return null;
}
service層程式碼:
sql語句中使用了行轉列以及group_concat
/**
*
* @Description 查詢某店鋪的某個月份的所有考勤資訊
* @param shopId 店鋪id
* @param attYearMonth 查詢考勤的年月
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
@Override
public List<Object[]> queryAttendances(String shopId, String attYearMonth) throws Exception {
//月初1號
//attYearMonth = "2017-06";
Date beginDate = DateUtil.strToDate(attYearMonth + "-01", "yyyy-MM-dd");
//月末最後一天(月初1號加一個月)
Date endDate = DateUtil.getLastDayByYearMonth(attYearMonth);
StringBuffer sb = new StringBuffer(" select t.beautician_id,b.name as bname, ");
sb.append(" GROUP_CONCAT(t.att_date) as att_dates, ");
sb.append(" GROUP_CONCAT(IFNULL(t.att_type,' ')) as att_types, ");
sb.append(" GROUP_CONCAT(IFNULL(t.late_min,' ')) as late_mins, ");
sb.append(" GROUP_CONCAT(IFNULL(t.leavebill_min,' ')) as leavebill_mins, ");
sb.append(" GROUP_CONCAT(t.summary) as summarys ");
sb.append(" from t_attendance t,t_beautician b ");
sb.append(" where t.beautician_id = b.id ");
sb.append(" and t.att_date >= ? ");
sb.append(" and t.att_date <= ? ");
sb.append(" group by t.beautician_id ");
return (List<Object[]>)baseDao.queryBySql(sb.toString(), beginDate,endDate);
}
3、點查詢按鈕動態生成列的方式(此方式與上面的跳轉到att.jsp頁面生成動態列的方式不同)
/**
* 查詢考勤資訊
*/
function getAtts(){
var attYearMonthStr = $("#attYearMonth").datebox("getValue");
//通ajax從後臺動態獲取動態列的字串
$.ajax({
type:"POST",
dataType : "json",
async: false,
url : '${pageContext.request.contextPath}/shop/att/queryHeader.do',
data : {attYearMonth:attYearMonthStr},
success : function(json){
//從後臺獲取的動態列的字串
var headerStr = json.obj;
//將字串轉換為datagrid的column的data
var colObjArr = covertHeader(headerStr);
//動態載入動態列
var options={};
options.columns = [colObjArr];
$('#attDataGrid').datagrid(options);
//動態列重新載入後重新整理datagrid
$('#attDataGrid').datagrid('reload');
},
error:function(){
messagerShow('提示', json);
}
});
4、EasyUi點選單元格檢視、編輯員工某一天的考勤資訊
下面的程式碼也在考勤列表(上面att.jsp頁面程式碼片段)中
//單擊單元格
onClickCell:function(rowIndex, field, value){
//根據rowIndex獲取datagrid的行
var row = $('#attDataGrid').datagrid('getData').rows[rowIndex];
//通過row獲取員工id
var beauticianId = row.id;
//獲取列頭,實際上就是員的考勤日期
var attDate = field;
//彈出考勤設定頁面
showAtt(beauticianId,attDate);
}
}
5、小結:上面的程式碼是一個初步的實現,可以進一步優化的地方有,動態生成列的兩個地方都是從後臺獲取資料,可以改為根據databox年月框的值,在頁面前端動態生成動態列的資料。後面有時間會將前端動態生成列的程式碼補上。