【问题标题】:how to build dynamic form builder with jquery如何使用 jquery 构建动态表单构建器
【发布时间】:2017-04-11 04:18:06
【问题描述】:

我想用 jquery 开发一个动态表单构建器,用户可以在其中构建自己的表单并更改表单名称、输入类型、大小等。我知道有一些很酷的拖放在线表单构建器,但我想开发一个非常简单的表单生成器。

我已经开始开发这个,但我正面临一些问题。

当用户单击标签(输入字段)时,它会使用带有编辑和删除按钮的 jquery 动态创建一个输入字段。

下面的代码是在一个空的 div 中附加输入字段。

$(document).ready(function() {
  $(".text").click(function(){
    $("#textInput").append('<input class="form-control"  type="text">' + '<input class="btn btn-default" type="button" value="Edit" id="editbtn"><input class="btn btn-default"  type="button" value="Delete" >'             ).show().css('display', 'block')});
});


    
.items {
  border: 1px solid lightgray; 
  display: none;  
  padding: 0 10px 10px 10px;
  }
<div class="items" id="textInput">
  <h3>Your Form</h3>
  <hr>    
</div>

单击文本输入时,我想显示一个表格或模式,用户可以在其中保存对输入字段的更改首先编辑按钮不起作用,其次如何编辑和保存对输入字段的更改(该过程将如何工作)。

这就是我想要实现的

【问题讨论】:

    标签: javascript jquery html forms twitter-bootstrap-3


    【解决方案1】:

    我一直致力于动态表单构建器,并从一些优秀的开源解决方案中借鉴了一些想法。

    他们这样做:

    1. 在后端将表单结构描述为 JSON。
    2. 然后使用以下库之一在前端呈现 JSON 格式。

    jsonform/jsonform

    源代码:jsonform/jsonform

    示例:

    rjsf-team/react-jsonschema-form

    源代码:https://github.com/rjsf-team/react-jsonschema-form

    【讨论】:

      【解决方案2】:

      我建议您查看从模式到表单的库(例如这里How to Create a form from a json-schema? 中描述的一些库)。

      使用此类库有多种好处,其中一些是灵活的布局功能以及验证挂钩。

      更重要的是,您的编辑器只能使用 JSON 结构,并且从中呈现表单并不是您最头疼的问题。

      【讨论】:

        【解决方案3】:

        我使用 JQuery、HTML 和 Bootstrap 完成了这项工作

        表单被构建为尽可能动态,并且还为我修改了构建

        有一个脚本可以通过ajax提交表单

        function d(object) {
          const id = $(object).data('check');
          $('#' + id).remove();
        }
        //picks and submits form inputs
        $(document).ready(function() {
          $('form.myForm').on('submit', function() {
        
            var that = $(this),
              url = that.attr('action'),
              type = that.attr('method'),
              data = {};
        
            that.find('[name]').each(function(index, value) {
              var that = $(this),
                name = that.attr('name'),
                value = that.val();
        
              data[name] = value;
            });
        
            $.ajax({
              url: url,
              type: type,
              data: data,
        
              success: function(response) {
        
              }
            });
            return false;
          });
        });
        
        $(function() {
          //here i will populate the appendi field if the user selects file
          //the user should select the file type
          $('#type').on('change', function() {
            let type = $("#type option:selected").val();
            var add;
            if (type === 'file') {
              //here i will append the new option in the appendi part
              add = "<label for=\"\">What type of file?</label>";
              add += "<select name=\"image_type\" id=\"\" class=\"form-control\">";
              add += "<option value=\"all\">All</option>";
              add += "<option value=\"image\">Image</option>";
              add += "<option value=\"document\">Document</option>";
              add += "</select>";
        
              $('#appendi').html(add);
            }
            if (type === 'radio' || type === 'checkbox') {
              //here i will append the new option in the appendi part
              add = "<label for=\"\">Enter the names of the option separated by a comma (,)</label>";
              add += "<textarea col=\"\" class=\"form-control\" row=\"\" name=\"options\" required></textarea>";
        
              $('#appendi').html(add);
            }
            if (type === 'paragraph' || type === 'text') {
              $('#appendi').empty();
            }
          })
        })
        
        $(document).ready(function() {
          $('form.myInput').on('submit', function() {
        
            var that = $(this),
              data = {};
        
            that.find('[name]').each(function(index, value) {
              var that = $(this),
                name = that.attr('name'),
                value = that.val();
        
              data[name] = value;
            });
            addBody(data);
            return false;
          });
        });
        
        function addBody(data) {
          //first thing first is to generate an outer shell
          let id_tag = "shell_" + generateId(8);
          let shell1_open = "<div class='form-group' " + "id = '" + id_tag + "'>";
          shell1_open += "<button type='button' onclick='d(this)' id=\"delete\" data-check='" + id_tag + "'><i class=\"fa-minus-square\">remove</i></button>"
          let shell1_close = "</div>";
          let shell2, label, shell2_close;
          if (data.type === 'text' || data.type === 'date' || data.type === 'file' || data.type === 'email') {
            shell2 = "<input type='";
            shell2 += data.type + "'";
            shell2_close = ">";
          }
        
          if (data.type === 'paragraph') {
            shell2 = "<textarea";
            shell2_close = "></textarea>";
          }
        
          if (data.type === 'radio') {
            let myArr = data.options.split(",");
            shell2 = '';
            let name = 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '');
            for (let i = 0; i < myArr.length; i++) {
              shell2 += "<input type='radio'";
              shell2 += "value ='" + myArr[i] + "'";
              shell2 += "name ='" + name + "'";
              //add a class to it
              shell2 += " class = 'form-control'";
              if (data.required === 'yes') {
                shell2 += " required";
              }
              shell2 += ">" + myArr[i];
            }
            shell2_close = "";
          }
        
          if (data.type === 'checkbox') {
            let myArr = data.options.split(",");
            shell2 = '';
            for (let i = 0; i < myArr.length; i++) {
              shell2 += "<input type='checkbox'";
              shell2 += "value ='" + myArr[i] + "'";
              shell2 += " name='" + 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '') + "'";
              //add a class to it
              shell2 += " class = 'form-control'";
              if (data.required === 'yes') {
                shell2 += " required";
              }
              shell2 += ">" + myArr[i];
            }
            shell2_close = "";
          }
        
          if (data.image_type) {
            if (data.image_type === 'all') {
              shell2 += " accept";
            }
        
            if (data.image_type === 'image') {
              shell2 += " accept='.jpeg, .png'";
            }
        
            if (data.image_type === 'document') {
              shell2 += " accept='.pdf, .xls, .docx'";
            }
          }
        
          if (data.type !== 'radio' && data.type !== 'checkbox') {
            if (data.required === 'yes') {
              shell2 += " required";
            }
        
            /**
             * after thinking i decided to map the name the user chose to the placeholder/label
             * and squash the name to get the input name, so to remove whitespaces
             * also i'll append input_ to all input names
             */
            shell2 += " name='" + 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '') + "'";
        
            //add a class to it
            shell2 += " class = 'form-control'";
        
            //add placeholder
            shell2 += " placeholder = '" + data.name + '\'';
          }
        
          $('#main-form-body').append(shell1_open + shell2 + shell2_close + shell1_close)
          //console.log(shell1_open + shell2 + shell2_close +shell1_close);
        }
        
        function dec2hex(dec) {
          return dec.toString(16).padStart(2, "0")
        }
        
        // generateId :: Integer -> String
        function generateId(len) {
          var arr = new Uint8Array((len || 40) / 2)
          window.crypto.getRandomValues(arr)
          return Array.from(arr, dec2hex).join('')
        }
        <html>
        
        <head>
          <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
          <script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
          <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
        </head>
        
        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
            Add input
        </button>
        
        <form action="" method="post" class="myForm">
          <div id="main-form-body">
        
          </div>
          <button type='submit'>Submit</button>
        </form>
        
        <!-- The Modal -->
        <div class="modal" id="myModal">
          <div class="modal-dialog">
            <div class="modal-content">
        
              <!-- Modal Header -->
              <div class="modal-header">
                <h4 class="modal-title">Add form input</h4>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
              </div>
        
              <form action="" method="get" class="myInput">
                <!-- Modal body -->
                <div class="modal-body">
                  <div class="form-group">
                    <label for="">What should this be called?</label>
                    <input type="text" name="name" class="form-control">
                  </div>
        
                  <div class="form-group">
                    <label for="">What type of data will it hold?</label>
                    <select name="type" id="type" class="form-control">
                      <option value="text">Text</option>
                      <option value="paragraph">Paragraph</option>
                      <option value="file">File</option>
                      <option value="radio">Radio</option>
                      <option value="checkbox">Checkbox</option>
                      <option value="date">Date</option>
                    </select>
                  </div>
        
                  <div class="form-group" id="appendi">
        
                  </div>
        
                  <div class="form-group">
                    <label>Should it be a required field?</label>
                    <select name="required" id="" class="form-control">
                      <option value="yes">yes</option>
                      <option value="no">no</option>
                    </select>
                  </div>
        
                </div>
        
                <!-- Modal footer -->
                <div class="modal-footer">
                  <button type="submit" class="btn btn-primary">Add</button>
                  <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
                </div>
              </form>
        
            </div>
          </div>
        </div>
        
        </html>

        【讨论】:

          猜你喜欢
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-12
          • 2012-10-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多