原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(44)-工作流设计-设计表单

系列目录

设计表单是比较复杂的一步,完成一个表单的设计其实很漫长,主要分为四步。

开始之前先说说表的结构。

其实表Flow_Form与Flow_FormContent设计是有一个缺陷的。我总共是设置最高26个字段从A~Z如果超过26个字段的表单是属于硬编码的。但是我认为26个字段已经足够

因为这里我是单表模式比起表关联无限字段理论上性能会更加快,特别是当数据库申请带到千万级数据的时候(你自己可以设计更加灵活的表单管理)

Flow_Form的A~Z对应的是Flow_FlowAttr表中的数据,

Flow_FormContent表中的数据就是用户对表单的申请内容。同样从A~Z对应。这个表设计也有缺陷,我把内容全部设置为varchar(2048)字段太大,可以根据自己的扩展来确定内容是最佳的方式,比如A-F是大字段,G-L设置的是中级长度的字段,M-O是数字的字段等等

准备开始

1.新建控制器FormController(用代码生成器即可)

新建视图Create.cshtml,这里我设计了一个手风琴,设计表单的同时设计字段

把代码生成器生成的Form表单的的Create代码放到

第一步:设计表单里面

第二步添加字段,添加字段是一个DropDownList+easyui-combogrid来组成。

具体代码实现如下

@model App.Models.Flow.Flow_FormModel
@using App.Common;
@using App.Models.Flow;
@using App.Admin;
@using App.Models.Sys;
@{
ViewBag.Title = "创建";
Layout = "~/Views/Shared/_Index_LayoutEdit.cshtml";
List<permModel> perm = (List<permModel>)ViewBag.Perm;
if (perm == null)
{
perm = new List<permModel>();
}
} <script type="text/javascript">
$(function () {
jQuery("#accordion").accordion({ //初始化accordion
fillSpace: true,
fit: false,
border: false,
animate: false
}); $("#btnSave").click(function () {
if ($("form").valid()) {
$.ajax({
url: "@Url.Action("Create")",
type: "Post",
data: $("form").serialize(),
dataType: "json",
success: function (data) {
if (data.type == 1) {
window.parent.frameReturnByMes(data.message);
window.parent.frameReturnByReload(true);
window.parent.frameReturnByClose()
}
else {
window.parent.frameReturnByMes(data.message);
}
}
});
}
return false;
});
$("#btnReturn").click(function () {
window.parent.frameReturnByClose();
});
//改变字段列表
$("#TypeName").change(function () {
$('#attrVal').val("");
$('#formAttrComboGrid').combogrid('setValue', '').combogrid('clear');
$("#formAttrComboGrid").combogrid('grid').datagrid("load", { queryStr: $("#TypeName").val() });
});
});
//添加一个字段到表单
function AddAttr() { var currentValue= $('#attrVal').val();
if (currentValue == "") {
$.messageBox5s('提示', "请选择要添加的字段!");
}
var charNo = $("#AttrList tr").size()+1;//第几个字符
if (charNo > 26)
{
$.messageBox5s('提示', "目前设计最高26个字段!");
return;
}
var b = false;
$("#AttrList input[type='hidden']").each(function (i) {//判断是否有重复的项目
if ($(this).val() == currentValue)
{
b = true;
return;
}
});
if (b)
{
$.messageBox5s('提示', "已经有重复的项目了!");
return;
}
var grid = $("#formAttrComboGrid").combogrid("grid");//获取表格对象
var row = grid.datagrid('getSelected');//获取行数据
var currentChar = "Attr" + getChar(charNo);//获取当前的字母
var example = getExample(row.AttrType);
//添加到候选区
$("#AttrList").append("<tr id='tr" + currentChar + "'><td style='text-align:right'>" + row.Title + ":</td>" +
"<td>" + example + "<input id='" + currentChar + "' name='" + currentChar + "' type='hidden' value='" + currentValue + "' /></td><td><a href=\"javascript:deleteCurrentTR('tr" + currentChar + "');\">[删除]</a></td></tr>");
//设置combogrid为空
$('#formAttrComboGrid').combogrid('setValue', '');
}
function deleteCurrentTR(c)
{
$.messager.confirm('提示', '删除字段吗?', function (r) {
if (r) {
$("#" + c).remove(); }
});
} function getExample(v)
{
switch (v)
{
case "文本": return "<input type='text' />";
case "多行文本": return "<textarea></textarea>";
case "数字": return "<input type='text' />";
case "日期": return "<input type='text' />";
}
} function getChar(i)
{
switch (i)
{
case 1: return "A"; break;
case 2: return "B"; break;
case 3: return "C"; break;
case 4: return "D"; break;
case 5: return "E"; break;
case 6: return "F"; break;
case 7: return "G"; break;
case 8: return "H"; break;
case 9: return "I"; break;
case 10: return "J"; break;
case 11: return "K"; break;
case 12: return "L"; break;
case 13: return "M"; break;
case 14: return "N"; break;
case 15: return "O"; break;
case 16: return "P"; break;
case 17: return "Q"; break;
case 18: return "R"; break;
case 19: return "S"; break;
case 20: return "T"; break;
case 21: return "U"; break;
case 22: return "V"; break;
case 23: return "W"; break;
case 24: return "S"; break;
case 25: return "Y"; break;
case 26: return "Z"; break;
default: break;
}
} </script>
<div class="mvctool bgb">
@Html.ToolButton("btnSave", "icon-save", "保存", perm, "Save", true)
@Html.ToolButton("btnReturn", "icon-return", "返回", false)
</div> @using (Html.BeginForm())
{
<div id="accordion" class="easyui-accordion">
<div title="第一步:设计表单" style="overflow: auto; padding: 10px;">
@Html.HiddenFor(model => model.Id)
<table class="fromEditTable setTextWidth300">
<tbody>
<tr>
<td style="width: 100px; text-align: right;">
@Html.LabelFor(model => model.Name):
</td>
<td style="width: 310px">
@Html.EditorFor(model => model.Name)
</td>
<td>@Html.ValidationMessageFor(model => model.Name)</td>
</tr>
<tr>
<td style="width: 100px; text-align: right;">
@Html.LabelFor(model => model.Remark):
</td>
<td style="width: 310px">
@Html.TextAreaFor(model => model.Remark, 5, 80, new { })
</td>
<td>@Html.ValidationMessageFor(model => model.Remark)</td>
</tr>
<tr>
<td style="width: 100px; text-align: right;">
@Html.LabelFor(model => model.UsingDep):
</td>
<td style="width: 310px">
@Html.EditorFor(model => model.UsingDep)
</td>
<td>@Html.ValidationMessageFor(model => model.UsingDep)</td>
</tr>
<tr>
<td style="width: 100px; text-align: right;">
@Html.LabelFor(model => model.TypeId):
</td>
<td style="width: 310px">
@Html.DropDownListFor(model => model.TypeId, ViewBag.FlowType as SelectList)
</td>
<td>@Html.ValidationMessageFor(model => model.TypeId)</td>
</tr>
<tr>
<td style="width: 100px; text-align: right;">
@Html.LabelFor(model => model.State):
</td>
<td style="width: 310px">
@Html.CheckBoxFor(model => model.State, new { @checked = true })
</td>
<td>@Html.ValidationMessageFor(model => model.State)</td>
</tr>
<tr>
<td>
<div style="float: right" class="pic_204"></div>
</td>
<td colspan="2" class="gray">注:设计好表单和字段才能组成一个完整的表单,设计好表单后才能设计步骤</td>
</tr>
</tbody>
</table>
</div>
<div title="第二步:添加字段" style="overflow: auto;">
<table class="fromEditTable setTextWidth300 bgb">
<tr>
<td style="width:40px; text-align: right;">类别:
</td>
<td style="width: 110px;">
@Html.DropDownListFor(model => model.TypeName, ViewBag.FlowType as SelectList, new { @style = "width:100px;" })
</td>
<td style="width:40px; text-align: right;">字段:
</td>
<td style="width: 210px">
<input id="attrVal" name="attrVal" type="hidden" />
<select class="easyui-combogrid" style="width:200px" id="formAttrComboGrid" data-options="
panelWidth: 470,
idField: 'Id',
textField: 'Title',
rownumbers: true,//行号
url: '@Url.Action("GetFormAttrList")?page=1&sort=Id&rows=1000&order=desc',
page:1,
columns: [[
{ field: 'Id', title: 'ID', width: 80, hidden: true },
{ field: 'Title', title: '字段标题', width: 80, sortable: true },
{ field: 'Name', title: '英文名称', width: 80, sortable: true },
{ field: 'AttrType', title: '类型', width: 80, sortable: true },
{ field: 'CheckJS', title: '校验脚本', width:50, sortable: true },
{field: 'CreateTime', title: '创建时间', width: 80, sortable: true }
]],
onClickRow: function (index, data) {
var value = $('#formAttrComboGrid').combogrid('getValue');
$('#attrVal').val(value); },
onLoadSuccess:function (data) { },
fitColumns: true
">
</select>
</td>
<td>
<a href="javascript:AddAttr();" class="easyui-linkbutton" data-options="iconCls:'icon-add'">添加</a>
</td>
</tr>
</table> <table id="AttrList" class="fromEditTable setTextWidth300"> </table>
</div>
</div>
}

Create.cshtml

FormController核心代码

 [HttpPost]
public JsonResult GetFormAttrList(GridPager pager, string queryStr)
{
List<Flow_FormAttrModel> list = attrBLL.GetList(ref pager, queryStr);
var json = new
{
total = pager.totalRows,
rows = (from r in list
select new Flow_FormAttrModel()
{
Id = r.Id,
Title = r.Title,
Name = r.Name,
AttrType = r.AttrType,
CheckJS = r.CheckJS,
TypeId = r.TypeId,
CreateTime = r.CreateTime }).ToArray() }; return Json(json);
}

获取字段列表

代码分析:

主要难点在切换类表需要重新加载combogrid,然后根据选择的字段组成表单。

利用前端技术控制,进行字段类表的筛选获得字段。再添加字段的ID到隐藏的DIV,最后序列化整张表单保存。

整个工作流中,前端的技术代码量远超后台代码。所以关注点都在前端代码中

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(44)-工作流设计-设计表单的更多相关文章

  1. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与目录(持续更新中...)

    转自:http://www.cnblogs.com/ymnets/p/3424309.html 曾几何时我想写一个系列的文章,但是由于工作很忙,一直没有时间更新博客.博客园园龄都1年了,却一直都是空空 ...

  2. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请 系列目录 创建新表单之后,我们就可以起草申请了,申请按照严格的表单步骤和分 ...

  3. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(47)-工作流设计-补充

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(47)-工作流设计-补充 系列目录 补充一下,有人要表单的代码,这个用代码生成器生成表Flow_Form表 ...

  4. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(46)-工作流设计-设计分支

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(46)-工作流设计-设计分支 系列目录 步骤设置完毕之后,就要设置好流转了,比如财务申请大于50000元( ...

  5. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(45)-工作流设计-设计步骤

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(45)-工作流设计-设计步骤 系列目录 步骤设计很重要,特别是规则的选择. 我这里分为几个规则 1.按自行 ...

  6. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(43)-工作流设计-字段分类设计

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(43)-工作流设计-字段分类设计 系列目录 建立好42节的表之后,每个字段英文表示都是有意义的说明.先建立 ...

  7. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(42)-工作流设计01

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(42)-工作流设计01 工作流在实际应用中还是比较广泛,网络中存在很多工作流的图形化插件,可以做到拉拽的工 ...

  8. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(40)-精准在线人数统计实现-[过滤器+Cache] 系列目录 上次的探讨没有任何结果,我浏览了大量的文章 ...

  9. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(41)-组织架构

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(41)-组织架构 本节开始我们要实现工作流,此工作流可以和之前的所有章节脱离关系,也可以紧密合并. 我们当 ...

随机推荐

  1. USACO 2.2 Party Lamps 派对灯 (lamps)

    题目描述 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码.这些灯都连接到四个按钮: 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭 ...

  2. Linux 防火墙设置,禁止某个ip访问

    service  iptables  status        查看防火墙状态 service  iptables  start           开启防火墙 service  iptables  ...

  3. centos7 更改语言

    vim /etc/locale.conf 修改 LANG="en_US.UTF-8"

  4. 关于【键鼠<局域网>共享软件:synergy】install

    Installation 另外,本人在centos6.5环境下作为server运行时,遇到一个问题,synergy1.5随着系统升级居然变成了1.3X,所以如果遇到类似问题,请您先用 rpm -qa ...

  5. uoj164. 【清华集训2015】V 统计

    坑爹题面:http://uoj.ac/problem/164 正常题面: 对于一个序列支持下列5个操作: 1.区间加x 2.区间减x并与0取max 3.区间覆盖 4.单点查询 5.单点历史最大值查询 ...

  6. iptables 配置需要保存

    iptables-save > /root/myiptables 将iptables规则导入到文件/root/myiptablse iptables-restore < /root/myi ...

  7. linux socket使用经验总结

    1.  scoket函数中PF_INET AF_INET区别 在UNIX系列中,PF_INET表示poxis, BSD系列用AF_INET 2.  in_addr_t inet_addr(const ...

  8. 转:char*, char[] ,CString, string的转换

    转:char*, char[] ,CString, string的转换 (一) 概述 string和CString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C++标准 ...

  9. C语言嵌入式系统编程修炼之五:键盘操作

    处理功能键 功能键的问题在于,用户界面并非固定的,用户功能键的选择将使屏幕画面处于不同的显示状态下.例如,主画面如图1:图1 主画面 当用户在设置XX上按下Enter键之后,画面就切换到了设置XX的界 ...

  10. mysql优化, 删除数据后物理空间未释放(转载)

    mysql优化, 删除数据后物理空间未释放(转载) OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTI ...