jquery 实现动态表单设计
只是实现了前台页面的动态表单的设计,并未实现后台绑定数据到数据库等功能。技术使用到的为jquery和bootstrap。俗话说有图有真相,先说下具体效果如下:
点击添加一个面板容器:
容器添加成功:
实现的代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="../css/bootstrap.min.css"> <script src="../js/jquery-1.8.3.min.js"></script> <script src="../js/bootstrap.min.js"></script> </head> <style type="text/css"> body{ background-color: rgba(0, 231, 68, 0.06); } /*隐藏的编辑面板属性的样式*/ .setPanel{ top:10%; margin-left: 20%; margin-right: 20%; position: absolute; border: solid 1px #000000; background-color: rgba(138, 174, 14, 0.5); display: none; } .setElement{ top:10%; margin-left: 20%; margin-right: 20%; position: absolute; border: solid 1px #000000; background-color: rgba(138, 174, 14, 0.5); display: none; } </style> <body> <div class="row"> <!--表单需要的原件区域开始--> <div id="labelContext" class="col-md-3"> <!-- 样式选择开始--> <ul class="nav nav-tabs"> <li value="0" role="presentation" class="active"><a href="#">列表</a></li> <li value="1" role="presentation"><a href="#">单行</a></li> </ul> <!-- 样式选择结束--> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">文本框</label> <div class="col-sm-8"> <input type="text" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">下拉框</label> <div class="col-sm-8"> <select class="form-control" > <option>-请选择-</option> </select> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">日期框</label> <div class="col-sm-8"> <input type="date" class="form-control"/> </div> </div> <div class="form-group col-sm-12 text-right"> <label class="col-sm-4 control-label"></label> <div class="col-sm-8"> <input type="radio"/>单选框 </div> </div> <div class="form-group col-sm-12 text-right"> <label class="col-sm-4 control-label"></label> <div class="col-sm-8"> <input type="checkbox"/>多选框 </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">文本域</label> <div class="col-sm-8"> <textarea class="form-control" style="height: 100px; margin-top: 5px; resize: none;"></textarea> </div> </div> <!--添加标识name="panel"用于实现原件添加的作用域--> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right"></label> <div class="col-sm-8"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">面板</h3> </div> <div class="panel-body"></div> </div> </div> </div> <div class="form-group col-sm-12"> <label for="inputEmail3" class="col-sm-4 control-label text-right">邮件</label> <div class="col-sm-8"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> <div class="form-group col-sm-12"> <label for="inputPassword3" class="col-sm-4 control-label text-right">密码框</label> <div class="col-sm-8"> <input type="password" class="form-control" id="inputPassword3" placeholder="Password"> </div> </div> </div> <!--表单需要的原件区域结束--> <!--表单的显示区域开始--> <div id="formContext" class="col-md-9"> <form class="form-horizontal"> </form> </div> <!--表单的显示区域结束--> </div> <!--表单的设置属性区域开始--> <div id="setPanelAttr" class="setPanel"> <span class='glyphicon glyphicon-remove' style="float: right" aria-hidden='true'></span> <br/> <form class="form-horizontal"> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">ID</label> <div class="col-sm-8"> <input name="id" type="text" disabled="disabled" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">数据表名</label> <div class="col-sm-8"> <input name="table" type="text" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">面板名称</label> <div class="col-sm-8"> <input name="name" type="text" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">排序</label> <div class="col-sm-8"> <input name="order" type="text" class="form-control" placeholder="预留字段,功能暂时没有实现"/> </div> </div> </form> </div> <!--表单的设置属性区域结束--> <!--Element元件设置属性区域开始--> <div id="setElementAttr" class="setElement"> <span class='glyphicon glyphicon-remove' style="float: right" aria-hidden='true'></span> <br/> <form class="form-horizontal"> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">ID</label> <div class="col-sm-8"> <input name="id" type="text" disabled="disabled" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">对应字段</label> <div class="col-sm-8"> <input name="column" type="text" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">名称</label> <div class="col-sm-8"> <input name="name" type="text" class="form-control"/> </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">排序</label> <div class="col-sm-8"> <input name="order" type="text" class="form-control" placeholder="预留字段,功能暂时没有实现"/> </div> </div> <div class="form-group col-sm-12 text-right"> <label class="col-sm-4 control-label"></label> <div class="col-sm-8"> <input name="required" type="checkbox"/>是否必填 </div> </div> <div class="form-group col-sm-12"> <label class="col-sm-4 control-label text-right">数据源</label> <div class="col-sm-8"> <textarea name="dataSource" class="form-control" style="height: 100px; margin-top: 5px; resize: none;"></textarea> </div> </div> </form> </div> <!--Element元件设置属性区域结束--> </body> <script type="text/javascript"> $(function(){ /*--------------------表单样式选项触发事件开始----------------*/ //全局样式变量:0代表列表,1代表单行 var formStyle=0; $(".nav li").click(function () { $(".nav li").removeClass(); $(this).addClass("active"); //设置表单样式的选项 formStyle=$(this).val(); }); /* ========表单样式选项触发事件结束========= */ //全局的原件作用域标识 var labelScope=null; //全局标识,当前有效的panel的id var globalPanelId=null; //全局存放Panel的数组 var panels=[]; //全局存放Element的数组 var elements=[]; /* -------设置点击原件要添加的作用域开始---------*/ /* ==========设置点击原件要添加的作用域结束===========*/ /* -----------控制原件区域内的内容点击放到表单区域开始---------------*/ $("#labelContext .form-group").click(function(){ //将当前元素克隆处理 var label=$(this).clone(); //判断是否为面板 var panelnum=$(this).find(".panel").size(); //表单容器中是否存在一个面板 var panelJudge=$("#formContext .panel").size(); if(!panelJudge){ if(!panelnum){alert("你必须添加一个面板"); return;} } //设置删除图标,用于删除元件 var delIco=$("<span class='glyphicon glyphicon-remove' aria-hidden='true'></span>"); //为删除图标bind删除事件,删除父级标签 delIco.bind("click",function () { //获取父级元素的id var id=$(this).parent().attr("id"); if(id!="undefined" && id!=null && id!=""){ //处理Panel的数组panels的函数delPanel(id) delPanel(id); //删除Element元件时同时删除elements数组中的信息 delElement(id); } $(this).parent().remove(); }); //设置设置图标,用于触发panel属性编辑页面,或div var setPanelIco=$("<span class='glyphicon glyphicon-wrench' aria-hidden='true'></span>"); //bind click 事件用于触发属性编辑div setPanelIco.bind("click",function () { //面板显示 $("#setPanelAttr").css("display","block"); //面板的id属性 var parentId=$(this).parent().attr("id"); //获取下标值 var panelIndex=parentId.substr(5,parentId.length)-1; //将面板的属性带到设置属性的div中 var panel=panels[panelIndex]; //在设置面板属性的input中添加值 $("#setPanelAttr").find("input[name='id']").val(panel.id); $("#setPanelAttr").find("input[name='name']").val(panel.name); $("#setPanelAttr").find("input[name='table']").val(panel.table); $("#setPanelAttr").find("input[name='order']").val(panel.order); }); if(panelnum){ //对象化栅格化容器 var panelmd12=$("<div class='col-md-12'></div>"); //对面板进行处理,保证面板的显示为class=col-md-12 label.find("label").remove(); label.find(".col-sm-8").removeClass(); /* 将元件放到表单的区域中*/ $("#formContext").find("form:first").append(panelmd12.append(label).click( function () { //将点击的面板作为作用域,作用域为.panel-body的class属性div labelScope=$(this).find(".panel-body"); //作用域标识 var span="<span id='labelScope' class='badge'>操作的面板</span>"; //通过span标签显示为作用域 $(".panel").find(".panel-heading").find("span").remove(); $(this).find(".panel-heading").prepend(span); //将当前有效的panelId赋值给全局变量globalPanelId globalPanelId=$(this).attr("id"); })); //创建panelId参数:添加的元件panelmd12 createPanelId(panelmd12); //触发一次panel的单击事件 panelmd12.trigger("click"); //添加删除图标 panelmd12.append(delIco); //添加设置图标 panelmd12.append(setPanelIco); return; } //设置设置图标,用于触发Element编辑页面,或div var setElementIco=$("<span class='glyphicon glyphicon-wrench' aria-hidden='true'></span>"); //bind click 事件用于触发属性编辑div setElementIco.bind("click",function () { //面板显示 $("#setElementAttr").css("display","block"); //面板的id属性 var parentId=$(this).parent().attr("id"); //获取下标值 var panelIndex=parentId.substr(7,parentId.length)-1; //将面板的属性带到设置属性的div中 var element=elements[panelIndex]; //在Element设置属性的input中添加值 $("#setElementAttr").find("input[name='id']").val(element.Id); $("#setElementAttr").find("input[name='name']").val(element.name); $("#setElementAttr").find("input[name='column']").val(element.column); $("#setElementAttr").find("input[name='order']").val(element.order); $("#setElementAttr").find("input[name='required']").val(element.required); $("#setElementAttr").find("textarea[name='dataSource']").val(element.dataSource); }); //判断是否为文本域 if(formStyle){ //创建栅格化容器 var md12=$("<div class='col-md-12'></div>"); //改变label选择元件的栅格化布局 label.find(".col-sm-4").addClass("col-sm-2"); label.find(".col-sm-8").addClass("col-sm-10"); label.find(".col-sm-4").removeClass("col-sm-4"); label.find(".col-sm-8").removeClass("col-sm-8"); //消除微小的差距导致无法对齐的bug label.css("margin-left","-25px"); /* 将元件放到表单的区域中*/ labelScope.append(md12.append(label)); //创建element的ID和默认名称 createElementId(md12); //添加删除图标 md12.append(delIco); //添加设置图标 md12.append(setElementIco); return; } //创建栅格化容器 var md6=$("<div class='col-md-6'></div>"); /* 将元素方到表单的区域中*/ labelScope.append(md6.append(label)); //将删除的图标添加到创建栅格化容器 //创建element的ID和默认名称 createElementId(md6); md6.append(delIco); //添加设置图标 md6.append(setElementIco); }); /* =====================控制原件区域内的内容点击放到表单区域结束=================*/ /* ------------生成panel的id属性和Panel对象类开始--------------*/ //定义panel类 /* 参数说明:id:唯一标识; name:显示名称; table:对应的表; flow:对应的模板; order:显示顺序; context:panel中的元件json数据*/ function Panel(id,name,table,flow,order,context){ this.id=id; this.name=name; this.table=table; this.flow=flow; this.order=order; this.context=context; } //创建panelId参数:添加的元件panelmd12 function createPanelId(panelmd12) { //为数组长度基础上默认+1,作为id和面板的区别数字 var panelsLength=panels.length+1; //设置面板的名字 panelmd12.find("h3").text("面板"+panelsLength); //panel添加成功后为panel指定唯一的id和设置相关默认属性 panels.push(new Panel("panel"+panelsLength,"面板"+panelsLength,"","","","")); panelmd12.attr("id","panel"+panelsLength); } //处理Panel的数组panels function delPanel(id) { //判断是否为panel if(id.substr(0,5)=="panel"){ //在数组中删除panel信息,但保留占位 delete panels[id.substr(5,id.length)-1]; } } /* =============生成panel的id属性结束================*/ /*---------------设置panel属性div的关闭事件开始--------------------*/ //面板属性设置div,在隐藏时同时将编辑的数据保存到panels数组中 $("#setPanelAttr .glyphicon-remove").click(function () { //隐藏属性编辑div $(this).parent().css("display","none"); //获取面板的id用于获取Panel对象存放在panels数组中的下标 var panelId=$(this).parent().find("input[name='id']").val(); var panelIndex=panelId.substr(5,panelId.length)-1; //面板的新名称 var panelName=$(this).parent().find("input[name='name']").val(); //将编辑好的值存放到panels数组中 panels[panelIndex]=new Panel($(this).parent().find("input[name='id']").val(), panelName, $(this).parent().find("input[name='table']").val(),"", $(this).parent().find("input[name='order']").val(),""); //改变面板显示名称 $("#"+panelId).find("h3").text(panelName); }); /* =========设置panel属性div的关闭事件结束=============*/ /* ----------设置element属性和element的id开始----------*/ /* Element是元件对象属性有: panelId:对应面板的Id; Id:元件的id; column:对应数据库字段; required:必填选项; dataSource:元件显示的数据源;*/ function Element(panelId,Id,name,column,required,order,dataSource) { this.panelId=panelId; this.Id=Id; this.name=name; this.column=column; this.required=required; this.order=order; this.dataSource=dataSource; } //创建element的ID和默认名称,md元件自身,labelScope元件所在的panel function createElementId(md) { //获取elements数组的长度,在+1的基础上作为元件的ID var elementLength=elements.length+1; md.attr("id","element"+elementLength); //将Element元件的信息添加到elements数组中 elements.push(new Element(globalPanelId,"element"+elementLength,"","","","","")); } //删除Element元件时同时删除elements数组中的信息 function delElement(id) { /*判断是否为element*/ if(id.substr(0,7)=="element"){ //在elements数组中删除Element信息,但保留占位 delete elements[id.substr(7,id.length)-1]; } } /*=======设置element属性和element的id结束========*/ /* -------------设置Element编辑div的关闭事件开始--------------*/ //面板属性设置div,在隐藏时同时将编辑的数据保存到elements数组中 $("#setElementAttr .glyphicon-remove").click(function () { //隐藏属性编辑div $(this).parent().css("display","none"); //获取Element的id用于获取Element对象存放在elements数组中的下标 var elementId=$(this).parent().find("input[name='id']").val(); var elementIndex=elementId.substr(7,elementId.length)-1; //元件的新名称 var elementName=$(this).parent().find("input[name='name']").val(); //将编辑好的值存放到elements数组中 elements[elementIndex]=new Element(globalPanelId,$(this).parent().find("input[name='id']").val(), elementName, $(this).parent().find("input[name='column']").val(), $(this).parent().find("input[name='required']").val(), $(this).parent().find("input[name='order']").val(), $(this).parent().find("textarea[name='dataSource']").val()); //改变元件显示名称 $("#"+elementId).find("h3").text(panelName); }); /* =============设置Element编辑div的关闭事件结束===================*/ }); </script> </html>
将一些逻辑问题使用代码实现