如何使用 jquery 构建动态表单构建器
Posted
技术标签:
【中文标题】如何使用 jquery 构建动态表单构建器【英文标题】:how to build dynamic form builder with 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>
单击文本输入时,我想显示一个表格或模式,用户可以在其中保存对输入字段的更改首先编辑按钮不起作用,其次如何编辑和保存对输入字段的更改(该过程将如何工作)。
这就是我想要实现的
【问题讨论】:
【参考方案1】:我一直致力于动态表单构建器,并从一些优秀的开源解决方案中借鉴了一些想法。
他们这样做:
-
在后端将表单结构描述为 JSON。
然后使用以下库之一在前端呈现 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">×</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>
【讨论】:
以上是关于如何使用 jquery 构建动态表单构建器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Wix 中使用 JavaScript 代码构建动态搜索表单?
如何使用 JQuery 和 Rails 创建类似 Wufoo(表单构建器)的 Web 应用程序?