前言
两年前在力控的时候就想做一个类似的功能,当时思路大家都讨论好了,诸多原因最终还是夭折了。没想到两年多后再这有重新提出要写一个绘制表单的功能。对此也是有点小激动呢?总共用时8.5天的时间基本功能也就实现了,当然再者中间也借用了网上的一些资料,公司前端也没有帮忙处理,所以样式和部分功能还没有更好地得到处理,github上出的code只有前端脚本,至于后端的处理,会在博客中体现出来。
1.工作前准备
1.1.实现的思路
思路一:
(1)ueditor添加自定义按钮
(2)绘制表单(控件会触发的脚步【暂时考虑范围】)【每个控件均需添加控件名称和创建名称】
(3)保存表单时建立数据库表(无需存储表信息),并保存html字符串
(4)修改表单需同时修改数据库
(5)表单发起获取数据封装成json,进行后台保存。
思路二:
(1)jquery 拖动自定义标签,在指定区域进行绘制
(2)表单属性设置相应的表单属性和表单基本布局
(3)设置每个控件的属性值
(4)把表单信息和控件以json的形式传入后台进行保存
(5)从后台获取数据json对象用jquery 绘制表单页面
(6)创建一张表(F-F200)把表单数据存入表单中。
最终选择的是【思路二】,原因是富文本编辑器绘制起来有很多自动生成的标签,让人感觉很是不爽。当然可以对ueditor进行处理(这个也是两年前的思路)。
1.2.实现过程的确定
整个的过程从借鉴开始网上有些类似的功能,从中得到很多帮助在这就不一一鸣谢了。然后就是没羞没臊的3天脚本修改工作【现在基本完成不过还在持续中】。后台数据的处理完全没有什么可说的,中间用的了一些缓存问题,本来说是用redis呢,结果商量一些说不用难部署(难部署???好吧一脸懵逼),就用了c#的CacheHelper。
2.具体实现
绘制表单预览与保存
2.1.脚本
以上是表单创建的js脚本。
就是上边那个图片的实现。
html重要分左中右三部分。左边是页面上所用到的标签区域,中间是展示区域,右边是表单和控件属性的设置区域。htnl 脚本如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="keywords" content="kmonkey,王延领,在线表单,自定义表单,表单设计器"> <meta name="description" content="表单设计器,支持文本、图片、地图、单选、多选,下拉等多种输入类型,我是准备把它做成一个超级通用的一个插件。让不懂编程的人也能很轻松的设计出想要的表单。继续加油code吧"> <meta name="renderer" content="webkit"> <title>表单设计</title> <link type="text/css" rel="stylesheet" href="~/Content/FormDesign/css/common.css?v=20160929" /> <link type="text/css" rel="stylesheet" href="~/Content/FormDesign/css/jquery-ui-1.9.2.custom.css" /> <link type="text/css" rel="stylesheet" href="~/Content/FormDesign/css/widgets.css?v=20160929" /> <link type="text/css" rel="stylesheet" href="~/Content/FormDesign/css/jquery.mCustomScrollbar.min.css?v=20160929" /> <link type="text/css" rel="stylesheet" href="~/Content/FormDesign/css/formbuild.css?v=20160929" /></head><body> <div id="container"> <!-- left state --> <div id="left"> <div id="addFields" class="overhide"> <h3 class="fields-group">通用字段</h3> <ul id="col1"> <li id="drag_text" ftype="text"><a id="sl" class="btn-field" title="适用于填写简短的文字内容,身份证号、银行卡号、工号等请使用此类型。" href="#"><i class="iconfont"></i>单行文本</a></li> <li id="drag_textarea" ftype="textarea"><a id="pt" class="btn-field" title="适用于填写大段文本,如“备注”、“留言”" href="#"><i class="iconfont"></i>多行文本</a></li> <li id="drag_radio" ftype="radio"><a id="mc" class="btn-field" title="适用于在少量选项里选一个,如“男/女”" href="#"><i class="iconfont"></i>单选框</a></li> <li ftype="date"><a id="dt" class="btn-field" title="适用于选择特定的日期" href="#"><i class="iconfont"></i>日期</a></li> <li ftype="dropdown2"><a id="dd2" class="btn-field" title="适用于展示多级联动,如第一级是饮料,第二级只能选择绿茶、红茶等" href="#"><i class="iconfont"></i>多级下拉框</a></li> <li ftype="file"><a id="fu" class="btn-field" title="适用于收集文件,如简历、照片" href="#"><i class="iconfont"></i>文件上传</a></li> <li id="drag_radio" ftype="section"><a id="sb" class="btn-field" title="用于将字段分组显示,更清晰" href="#"><i class="iconfont"></i>分隔符</a></li> </ul> <ul id="col2"> <li id="drag_number" ftype="number"><a id="nb" class="btn-field" title="适用于填写涉及到数学运算的数字,身份证号、银行卡号、工号等请使用单行文本。" href="#"><i class="iconfont"></i>数字</a></li> <li id="drag_checkboxes" ftype="checkbox"><a id="cb" class="btn-field" title="适用于在几个选项里选多个,如投票" href="#"><i class="iconfont"></i>多选框</a></li> <li id="drag_dropdown" ftype="dropdown"><a id="dd" class="btn-field" title="适用于在非常多的选项里选一个,如省份选择" href="#"><i class="iconfont"></i>下拉框</a></li> <li ftype="time"><a id="ti" class="btn-field" title="适用于填写特定的时间" href="#"><i class="iconfont"></i>时间</a></li> <li ftype="likert"><a id="lk" class="btn-field" title="适用于处理批量单选" href="#"><i class="iconfont"></i>组合单选框</a></li> <li ftype="image"><a id="im" class="btn-field" title="在表单上加入图片,起到宣传产品或美化表单的作用" href="#"><i class="iconfont"></i>图片</a></li> <li id="drag_dropdown" ftype="html"><a id="ht" class="btn-field" title="适用于添加HTML显示元素,如“p,a,span,div”等" href="#"><i class="iconfont"></i>HTML</a></li> </ul> <h3 class="fields-group">联系信息字段</h3> <ul id="col3"> <li ftype="name"><a id="nm" class="btn-field" title="适用于填写用户姓名" href="#"><i class="iconfont"></i>姓名</a></li> <li ftype="address"><a id="ad" class="btn-field" title="适用于填写全国的地址" href="#"><i class="iconfont"></i>地址</a></li> <li ftype="phone"><a id="ph" class="btn-field" title="适用于填写中国大陆内的手机和座机号码" href="#"><i class="iconfont"></i>电话</a></li> </ul> <ul id="col4"> <li ftype="email"><a id="em" class="btn-field" title="适用于填写电子邮箱地址" href="#"><i class="iconfont"></i>电子邮箱</a></li> <li ftype="map"><a id="mp" class="btn-field" title="通过地图收集地理信息,手机上可自动定位" href="#"><i class="iconfont"></i>地理位置</a></li> <li ftype="url"><a id="ws" class="btn-field" title="适用于填写网站链接" href="#"><i class="iconfont"></i>网址</a></li> <!--<li ftype="money"><a id="pr" class="btn-field" title="适用于填写价格" href="#"><i class="iconfont"></i>价格</a></li> --> </ul> <h3 class="fields-group">宏控件</h3> <ul id="col5"> <li ftype="goods"><a id="gd" class="btn-field" title="和已知系统数据配合使用,如当前登入人" href="#"><i class="iconfont"></i>当前登入人</a></li> </ul> <ul id="col6"> <li ftype="goods" subtype="noimg"><a id="gd2" class="btn-field" title="和已知系统数据配合使用,如组织结构部门" href="#"><i class="iconfont"></i>登入人部门</a></li> </ul> </div><!-- addFields --> </div> <!-- left end --> <!-- middle state --> <div id="middle"> <div class="forms"> <div id="fbForm" class="form form-focused"> <h2 id="fTitle"></h2> <div id="fDescription"></div> </div> </div> <div id="nofields" class="notice hide" style="margin:30px 18px 0px 28px"> <div id="addFromButton" style="cursor:pointer;"> <h2 class="color-red">没有字段!</h2> <a href="#">表单中没有字段,点击或拖动左边的组件添加字段。</a> </div> </div> <!--表单绘制区域--> <ul id="fields" class="fields"></ul> <!--表单绘制区域--> <div class="formButtons hide" id="formButtons"> <table style="margin:auto;font-size:1.0em"> <tr> <td style="border:none;"><a class="btn left" id="preview">预览</a></td> <td style="border:none;"><a class="btn blue left" id="saveForm" href="#">保存</a></td> <!-- <td><a class="btn green left" id="btnAddField2" href="#"><b></b>添加新字段</a></td> --> </tr> </table> </div> </div> <!-- middle end --> <!-- right state--> <div id="right"> <!-- --> <div class="notice hide" style="margin-top:30px;border:none" id="noFieldSelected"> <h3><b>没有选择字段</b></h3> <p>请先在右侧选择需要编辑的字段,然后在此编辑字段的属性。</p> </div> <div id="fieldProperties" class="hide"> <!-- field properties --> <h3 class="property-title">表单属性</h3> <div id="allPropsContainer"> <ul id="allProps"> <!-- <li class="num" id="liPos">1.</li> --> <li id="plabel"> <label class="desc" for="lbl"> 字段名称 </label> <textarea id="lbl" name="LBL" class="xxl" rows="2"></textarea> </li> <li id="ptype" class="left half"> <label class="desc" for="type"> 字段类型 <a href="#" class="help" title="关于字段类型" rel="可以修改表单保存之前添加字段的类型。">(?)</a> </label> <select id="type" name="TYP" class="xxl"> <optgroup label="标准类型"> <option value="text">单行文本</option> <option value="textarea">多行文本</option> <option value="radio">单选框</option> <option value="number">数字</option> <option value="checkbox">多选框</option> <option value="dropdown">下拉框</option> </optgroup> <optgroup label="常用类型"> <option value="email">电子邮箱</option> <option value="address">地址</option> <option value="map">地理位置</option> <option value="phone">手机</option> <option value="name">姓名</option> <option value="file">上传文件</option> <option value="date">日期</option> <option value="time">时间</option> <option value="url">网址</option> <option value="likert">组合单选框</option> <option value="dropdown2">多级下拉框</option> <option value="image">图片</option> <option value="goods">配图商品</option> <option value="goodsnoimg">无图商品</option> </optgroup> </select> </li> <li class="right half" id="pfldsize"> <label class="desc" for="fldsize"> 字段长度 <a href="#" class="help" title="关于字段长度" rel="用于限定字段输入框的长度(“多行文本”字段限定输入框高度)。">(?)</a> </label> <select id="fldsize" name="FLDSZ" class="xxl"> <option value="s">短</option> <option value="m">中</option> <option value="xxl">长</option> </select> </li> <li class="right half" id="playout"> <label class="desc" for="layout"> 字段布局 <a href="#" class="help hide" title="关于字段布局" rel="此属性仅对复选框和单选框类型的字段有效,用于定义复选框或单选框的排列方式。其中自动排列是指按一个接一个的方式进行排列。">(?)</a> </label> <select id="layout" name="LAY" class="xxl"> <option value="one">一列</option> <option value="two">二列</option> <option value="three">三列</option> <option value="oneByOne">自动排列</option> </select> </li> <li class="right half" id="pdateformat"> <label class="desc" for="dateformat"> 日期格式 <a href="#" class="help hide" title="关于日期格式" rel="此属性用于指定日期的输入格式。YYYY代表年,MM代表月,DD代表日。">(?)</a> </label> <select id="dateformat" name="FMT" class="xxl"> <option value="ymd" selected="selected">YYYY - MM - DD</option> @*<option value="mdy">MM / DD / YYYY</option> <option value="dmy">DD / MM / YYYY</option>*@ </select> </li> <li class="right half" id="pphoneformat"> <label class="desc" for="phoneformat"> 电话格式 <a href="#" class="help hide" title="关于电话格式" rel="此属性用于指定电话的输入格式。支持普通的电话号码输入和“区号-总机-分机”的座机号码输入。">(?)</a> </label> <select id="phoneformat" name="FMT" class="xxl"> <option value="mobile" selected="selected">手机</option> <option value="tel">座机</option> </select> </li> <li class="right half" id="pnameformat"> <label class="desc" for="nameformat"> 姓名格式 <a href="#" class="help hide" title="关于姓名格式" rel="此属性用于指定姓名的输入格式。支持普通的姓名格式和带称呼的加长格式。">(?)</a> </label> <select id="nameformat" name="FMT" class="xxl"> <option value="short" selected="selected">普通</option> <option value="extend">加长</option> </select> </li> <li class="right half" id="pmoneyformat"> <label class="desc" for="moneyfomat">货币格式</label> <select id="moneyfomat" name="FMT" class="xxl"> <option value="yen">¥ 人民币/日元</option> <option value="dollars">$ 美元</option> <option value="pounds">£ 英镑</option> <option value="euros">