Clone HTML form with Js
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang=""> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang=""> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="stylesheet" href="css/bootstrap.min.css">
<style>
body {
padding-top: 50px;
padding-bottom: 20px;
}
</style>
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/vendor/modernizr-2.8.3-respond-1.4.2.min.js"></script>
</head>
<body>
<!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right" role="form">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control">
</div>
<div class="form-group">
<input type="password" placeholder="Password" class="form-control">
</div>
<button type="submit" class="btn btn-success">Sign in</button>
</form>
</div><!--/.navbar-collapse -->
</div>
</nav>
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<div class="container">
<h4>Clones</h4>
<p>Code for clone inputs and forms.</p>
</div>
</div>
<div class="container">
<div class="duplicate" data-type="forms" data-maxOccurs="2" data-reference="special_instruction">
<div class="row">
<div class="col-sm-6">
<div class="duplicate" data-type="inputs" data-maxOccurs="3" data-reference="text">
<div class="fg-line">
<input type="text" id="receipt_aditional_complement_special_instruction_text" name="receipt[aditional_complement][special_instruction][0][text][0]" class="form-control", placeholder="text">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="duplicate" data-type="inputs" data-maxOccurs="5" data-reference="test">
<div class="fg-line">
<input type="text" name="receipt[aditional_complement][special_instruction][0][test][0]" class="form-control", placeholder="test">
</div>
</div>
</div>
</div>
</div>
<hr>
<div class="duplicate" data-type="forms" data-maxOccurs="2" data-reference="special_instruction">
<div class="row">
<div class="col-sm-6">
<div class="duplicate" data-type="inputs" data-maxOccurs="3" data-reference="text">
<div class="fg-line">
<input type="text" id="receipt_aditional_complement_special_instruction_text" name="receipt[aditional_complement][special_instruction][0][text][0]" class="form-control", placeholder="text">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="duplicate" data-type="inputs" data-maxOccurs="5" data-reference="test">
<div class="fg-line">
<input type="text" name="receipt[aditional_complement][special_instruction][0][test][0]" class="form-control", placeholder="test">
</div>
</div>
</div>
</div>
</div>
<hr>
<footer>
<p>© Company 2015</p>
</footer>
</div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script>
<script src="js/vendor/bootstrap.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
// element: contenido del nodo a clonar
// type: tipo de nodo "referencia para return structure"
// index: identificador unico para cada nodo
function addClone(element, type, index) {
let button = ''
switch(type) {
case "inputs":
button = '<span class="input-group-addon last"><button class="btn btn-default btn-add-clone" type="button"><i class="zmdi zmdi-plus"></i></button></span>'
return '<div class="clonned input-group" data-index="'+index+'">'+element+button+'</div>'
break
case "forms":
button = '<span class="pull-right"><button class="btn btn-primary btn-add-clone" type="button"><i class="zmdi zmdi-plus"></i></button></span>'
return '<div class="clonned row" data-index="'+index+'">'+element+button+'</div>'
break
}
}
let clones = {"inputs": [], "forms": []}
$.each(clones, function(type, _) {
let duplicates = $(".duplicate[data-type='"+type+"']")
for (var i = 0; i < duplicates.length; i++) {
duplicates[i].dataset.id = i
clones[type][i] = duplicates[i].innerHTML
duplicates[i].innerHTML = addClone(clones[type][i], type, 0)
//delete this lines
let input = $(duplicates[i]).find(".clonned:last-child input")
$(input).attr("placeholder", $(input).attr("name"))
}
})
$(document).on('click', '.btn-add-clone', function(event){
event.preventDefault()
//Verificar estructura para determinar si se puede remover un padre SPAN
let clonned = $(this).parent().parent()
let duplicate = clonned.parent()
let maxOccurs = duplicate.attr("data-maxOccurs")
let clonnes = duplicate.find("> .clonned")
if(maxOccurs != undefined){
if (parseInt(clonnes.length) >= parseInt(maxOccurs)) {
return false
}
}
let id = duplicate.attr("data-id")
let type = duplicate.attr("data-type")
let reference = duplicate.attr("data-reference")
let index = parseInt(clonned.attr("data-index")) + 1
let regex = new RegExp("\\["+reference+"\\]\\[(\\d+)\\]", "g")
let clone = clones[type][id].replace(regex, "["+reference+"]["+index+"]")
let clone_parents = duplicate.parents(".clonned")
if (clone_parents.length > 0) {
for (var i = clone_parents.length - 1; i >= 0; i--) {
let parent_index = clone_parents[i].dataset.index
reference = clone_parents[i].parentElement.dataset.reference
regex = new RegExp("\\["+reference+"\\]\\[(\\d+)\\]", "g")
clone = clone.replace(regex, "["+reference+"]["+parent_index+"]")
}
}
$(duplicate).append(addClone(clone, type, index))
//delete this lines
let inputs = $(duplicate).find(".clonned input")
for (var i = inputs.length - 1; i >= 0; i--) {
$(inputs[i]).attr("placeholder", $(inputs[i]).attr("name"))
}
$(this).removeClass('btn-add-clone').addClass('btn-remove-clone')
.html('<i class="zmdi zmdi-minus"></i>')
}).on('click', '.btn-remove-clone', function(event){
$(this).parent().parent().remove()
event.preventDefault()
return false
});