您的位置:首页 > 产品设计 > UI/UE

【EasyUi DataGrid】动态加载列

2015-07-31 17:16 776 查看
       动态加载列可以说是一个从无到有的过程,如果只是网页上的DataGrid实现那就太无味了,有趣的在这里,这个页面上连带着一大堆的数据库表的查询修改,尤其是做着做着发现数据表设计有缺陷,需要的数据竟然只有出口没有入口,想想也是醉了,对业务不熟悉真心的杀不起。其实吧这个蛮好玩的,就像玩捉迷藏藏得那个人叫做nothing,再后来我又遇到了Multiple-births(多胞胎),一个页面上涉及到了六七张数据库表,里边的字段名虽然不一样,可它就是达到了百分之七八十的相似度!来吧,先看看页面上的操作流程

一、操作流程

       1.页面一加载是这个样子的



       2.输入招标编号后,一点击确定是这个样子的



       这里已经把DataGrid动态加载出来了,如果你想问为什么不在页面加载前就定义了DataGrid呢?好吧,没有招标编号这个参数,它只会报错、报错、报错!或者提前先定义好几套DataGrid的js,在输入了招标编号后根据招标编号动态调用?在网上查阅到很多人都是这样做的,不过我得定义多少套呢,况且我还不知道它会有多少列,每列叫什么。把上边的图划分一下,大家再看看



       有了1,才有2和3,有了2才有了3中的4,这样说好像很傻的样子,可以略过,goon

       3.选择投标商后,即可显示我们需要的信息



       评委还没有对该投标商评过分,所以“专家评分Id”、评分项“暗标”等是空的。上图只是它很平静的表面,它的真实面目如下图,其中没有算计投标商以及联系起投标商和DataGrid二者用到的表。D表的显示数据可以有多个列,这里只用了一条演示



       4.填入分数后,可以用咱们上篇博客写到的对DataGrid的编辑功能,提交到后台了



       当然,更换了组合框中的投标商后,DataGrid中的信息也跟着变动



二、代码实现
       1.Html页面上的代码很简单
<body>
<div style="margin-top: auto; margin-left: 50px;">
<div class="easyui-panel" title="评分信息" style="width: 1142px;">

<div style="margin: 10px 20px; float: left">
@* 1.加载搜索框 *@
请输入招标编号:@Html.TextBox("BidRecordId")
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-search',plain:true" onclick="Ok()">确定</a>
</div>

<div id="dropDownList" style="margin: 12px 50px; display: none;">
请选择投标商:
<input id="companyName" class="easyui-combobox" name="companyName" value="--请选择--" data-option="
method:'get',
panelWidth:350,
panelHeight:'auto',
formatter:formatItem
">
</div>
</div>
</div>
@*主体内容部分*@
<div id="contentAreas" style="margin-top: 10px; margin-left: 50px; width: 1142px; display: none">

<div class="easyui-panel" title="评分项管理" style="width: 1142px;">
@* 加载按钮 *@
<div id="btnAreas" style="margin-bottom: 5px; margin-top: 10px;">
<div id="tb" style="width: auto; height: auto">
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-save',plain:true" onclick="save()">保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-undo',plain:true" onclick="reject()">撤销</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-search',plain:true" onclick="getChanges()">获取修改行</a>
</div>
</div>

<div>
<table id="dg" class="easyui-datagrid" style="width: 1140px; height: 400px; padding-left: 200px;">
</table>
</div>
</div>
</div>
</body>
       2.js中的实现代码比较多,精简了一些,下边是我用到的主要函数
var editIndex = undefined; //用来获取编辑的行号
var bidRecordId; //定义一个变量,用来保存招标编号
var columnsAll = new Array(); //定义一个新的列集合,用来保存返回的数据

//显示隐藏的信息
function Ok() {
if ($("#BidRecordId").val() == "") {
alert("请输入招标编号!");
$("#BidRecordId").select();
} else {
//显示组合框
document.getElementById("dropDownList").style.display = "";

//获取搜索框中的内容
bidRecordId = document.getElementById("BidRecordId").value;

//2.动态加载组合框中的数据,写法有误,返回函数功能不能实现
$('#companyName').combobox({
url: '/BidManager/GetTUserByZUser?BidRecordId=' + bidRecordId,
valueField: 'Value',
textField: 'Text'
});

//显示主体内容页
document.getElementById("contentAreas").style.display = "";

//动态加载表头中的数据,ajax调用后台方法
load_dg();

//当组合框中的文本更换时,获取组合框中所对应的Id值,并加载表格中的数据
$('#companyName').combobox({
onSelect: function () {
bidRecorderId = $('#companyName').combobox('getValue').trim(); //获取组合框中文本所对应的id值

//TODO:添加一个弹出框,在有未保存信息的情况下,提醒用户是否保存
if (editIndex != undefined) {
alert("您修改的数据将不被保存!");
}

editIndex = undefined; //确保在组合框中的文本更换时,对应的datagrid的编辑功能可用
//id值为空,则只传递招标编号,否则把“招标编号”和“投标商id”拼接成字符串
if (bidRecorderId != "[object HTMLInputElement]") {
var key = bidRecordId + "," + bidRecorderId;
} else {
var key = bidRecordId
}

//2.加载数据并显示DataGrid中的值
$.ajax({
url: '/BidManager/GetSpecialistByZBid?Key=' + key,
success: function (data) {
//加载完数据后,切割评分项
var array = new Array;

//将加载到的值,重新赋值传给datagrid
for (var i = 0; i < data.length; i++) {
var obj = new Object();
obj.SpecialistId = data[i].SpecialistId;
obj.ItemScoreId = data[i].ItemScoreId;
obj.SpecialistName = data[i].SpecialistName;
obj.Score = data[i].Score; //或者用obj['Scores']=data[i].Score;
obj.BidRecorderId = bidRecorderId;

//评分的分数不为空,则对评分项分数进行切割
if (data[i].ItemScores != null) {
//将整体的评分项,切割成单个的评分项
var ItemScores = data[i].ItemScores; //获取所有评分项的评分Id及分数
var scoreEvery = new Array(); //定义一个数组来接收每个评分Id及其分数
scoreEvery = ItemScores.split("##"); //将切割得到的各个评分项Id及其分数,放入定义好的数组中

//将单个的评分项id与分数值切割开
for (var j = 0; j < scoreEvery.length; j++) {
var score = new Array(); //定义一个数组,用来装载评分项分数切割后的值
score = scoreEvery[j].split("#"); //将一个评分项分数的id与分数值分隔开
obj[score[0].toLowerCase()] = score[1]; //把切割好的分数值对(id+分数)添加到数组中
}
};
//将对象装载到数组中
array.push(obj);
}
$('#dg').datagrid('loadData', array);
}
})
}
})
};
}

//动态加载表头中的数据,ajax调用后台方法
function load_dg() {
$.post('/BidManager/ShowBidProperties?BidRecordId=' + bidRecordId, function (jsonObj) {

//如果返回的数据不为空,则添加遍历该数据集合
if (jsonObj.length > 0) {
for (var i = 0; i < jsonObj.length; i++) {
//把返回的数据封装到一个对象中
var col = {}
col["title"] = jsonObj[i].FieldText;
col["field"] = jsonObj[i].FieldValue;
col["editor"] = jsonObj[i].Editor;
col["width"] = 150;
col["align"] = 'center'
//col["hidden"] = jsonObj[i].Hidden;

//把这个对象添加到列集合中
columnsAll.push(col);
}

//重新加载表格
$('#dg').datagrid({
height: 500,
singleSelect: true,
url: '',
fit: true,
singleSelect: true,
toolbar: '#tb',
method: 'get',
columns: [columnsAll],
onClickRow: onClickRow, //单击事件
}).datagrid("reload");
}
else {
$.messager.alert('提示信息', '没有可用数据,请联系管理员!', 'warning');
}
}, "JSON");
}

//保存按钮,多条数据一起提交
function save() {
if (endEditing()) {

//获取更新更改的行的集合
row = $("#dg").datagrid('getChanges');

//DataGrid的更该行为不为0
if (row.length) {
var array = new Array;
for (var i = 0; i < row.length; i++) {

var obj = new Object();
obj.SpecialistId = row[i].SpecialistId;
obj.ItemScoreId = row[i].ItemScoreId;
obj.SpecialistName = row[i].SpecialistName;
obj.Score = row[i].Score;
obj.BidRecorderId = row[i].BidRecorderId;

//拼接所有评分项的值
var valueAll = "";
for (var h = 3; h < columnsAll.length - 1; h++) {

var title = columnsAll[h].field.toUpperCase(); //获取这列的列Id
var field = row[i][columnsAll[h].field]; //获取单元格的值

//获取所有评分项的id与值
if (valueAll == "" || valueAll == null) {
valueAll += title + "#" + field;
} else {
valueAll += "##" + title + "#" + field;
}
}
obj.ItemScores = valueAll;
array.push(obj);
}

$.ajax(
{
type: 'POST',
url: "/BidManager/UpdateOrAddItemScore",
data: { arrayList: JSON.stringify(array), },
success: function (data) {
if (data != "") {
$.messager.alert('提示', '保存成功!');

$('#dg').datagrid('reload');    // 重新载入当前页面数据

}
else {
$.messager.alert('提示信息', '保存失败,请联系管理员!', 'warning');
}
}
});
}
else  //如果没有修改数据,则提醒用户
{
$.messager.alert('提示信息', '您还没有修改信息!', 'warning');
}
}
editIndex = undefined;
}
       3.Controller中的代码就是查询并定义DataGrid的表头,其中有四列是固定的,即A、B、C、E四个表对应的表头是固定的,A、B两表对应的列在实际中会被隐藏,D表对应的列根据实际评分项的数量自动扩充或缩减。因为每一列的属性都是固定的,所以我新建了一个专门的ViewModel类用来管理列属性(这个ViewModel放在服务端)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace LFBidSystem.ViewModel
{
[DataContract]
public class TableHeaderViewModel
{
/*表头描述
* 1.FieldValue:键值
* 2.FieldText:显示名称
* 3.Hidden:是否隐藏
*/
[DataMember]
public string FieldValue;
[DataMember]
public string FieldText;
[DataMember]
public bool Hidden;
[DataMember]
public string Editor;

}
}
       Controller中加载表头的方法如下

string bidRecordId;
#region 加载表头信息 + 王静娜 2015-5-28 10:31:54
public ActionResult ShowBidProperties()
{
//表头实体集合
List<TableHeaderViewModel> listHeaderVM = new List<TableHeaderViewModel>();

//隐藏的表头列“评分项得分编号”
TableHeaderViewModel judgeHeader1Hide = new TableHeaderViewModel
{
FieldValue = "SpecialistId",
FieldText = "专家Id",
Hidden = true
};
listHeaderVM.Add(judgeHeader1Hide);

//隐藏的表头列“评分项得分编号”
TableHeaderViewModel judgeHeader2Hide = new TableHeaderViewModel
{
FieldValue = "ItemScoreId",
FieldText = "专家评分Id",
Hidden = true
};
listHeaderVM.Add(judgeHeader2Hide);

//第一列“评委”
TableHeaderViewModel judgeHeaderFirst = new TableHeaderViewModel
{
FieldValue = "SpecialistName",
FieldText = "评委",
Hidden = false
};
listHeaderVM.Add(judgeHeaderFirst);

//第二列及倒数第二列之前,各评分项遍历
//获取页面上的招标编号,并转化成Guid格式的数据类型
bidRecordId = Request.Params["BidRecordId"];
Guid recordId = new Guid(bidRecordId);

//根据招标编号,获取所对应的所有评分项信息,评分名称作为表头
List<BidJudgeViewModel> listBidJudge = iBidJudgeService.GetBidJudge(recordId);

foreach (var item in listBidJudge)
{
TableHeaderViewModel JudgeHeader = new TableHeaderViewModel();

JudgeHeader.FieldValue = item.JudgeId.ToString();
JudgeHeader.FieldText = item.JudgeItemName;
JudgeHeader.Hidden = false;
JudgeHeader.Editor = "text";
listHeaderVM.Add(JudgeHeader);
}

//最后一列“总分”
TableHeaderViewModel judgeHeaderLast = new TableHeaderViewModel
{
FieldValue = "Score",
FieldText = "总分",
Editor = "text",
Hidden = false
};
listHeaderVM.Add(judgeHeaderLast);

//将封装的表头信息返回给前台
return Json(listHeaderVM, JsonRequestBehavior.AllowGet);
}
#endregion

        这样动态加载列基本上就实现了,里边比较麻烦的是把Controller中查询到的表头信息显示到页面上,这部分在js中实现。由于数据库表字段中有一列(D表)用到了值拼接,所以循环切割拼接在所难免,从而也导致了列显示更加复杂一些,都做出来后整个感觉都好了。。。

       三篇DataGrid的总结已经写完,有失误的地方,欢迎指正~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: