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>
原文地址:https://www.cnblogs.com/gynbk/p/7130811.html