JSFiddle - React, Tailwind, and code Playground
by Viruthagiri
HTML
<body>
<h2>Click + or - to Clone</h2>
<br/>
<div class='project_group'>
<input id='user_project_name' name='user[project][name]'></input>
<input id='user_project_description' name='user[project][description]'></input>
<input type="file" id='user_project_image' name='user[project][image]'></input>
</div>
<br/>
</body>
CSS
.simple_wrapper {
display: block;
}
.simple_wrapper .simple_label {
float: left;
margin-right: 20px;
}
.simple_wrapper .simple_plus, .simple_wrapper .simple_minus {
float: left;
cursor: pointer;
padding: 0 0.5em;
}
.simple_wrapper .left {
float: left;
}
.simple_wrapper .simple_clear {
clear: both;
}
JavaScript
$(document).ready(function(){
$(".project_group").simple_clone({
nested: true
});
});
(function($) {
$.fn.simple_clone = function(option){
var option = option || {};
var e = $(this);
e.addClass("left")
var out_wrapper = "<div class='outer_simple_wrapper'></div>"
var wrapper = "<div class='simple_wrapper'></div>"
var plus = "<span class='simple_plus'>+</span>"
var minus = "<span class='simple_minus'>-</span>"
var clear = "<div class='simple_clear'></div>";
// ------------ case 1: if have already multiple groups
if(e.length > 1) {
e.wrap(wrapper);
// we only wrapper one outer_simple_wrapper for all groups
var existing_outer_wrapper;
e.each(function(i){
existing_outer_wrapper = $(this).parent().siblings(".outer_simple_wrapper");
if(existing_outer_wrapper.length == 0) {
$(this).parent().wrap(out_wrapper);
} else {
$(this).parent().appendTo(existing_outer_wrapper);
}
// append '- +' after the last group, otherwise append only a '-'
if(i == e.length-1){
$(this).after(plus).after(minus);
} else{
$(this).after(minus);
}
})
}
// ------------- case 2: if only has one wrapper, general case
else{
// wrap wrappers
e.wrap(out_wrapper).wrap(wrapper);
// if the list can be empty (all elements can be removed), add an "-" after the first elements
if(option.canBeEmpty) {
e.after(minus);
}
// add an original "+" after the elements
e.after(plus);
}
// append a initial number to elements id, if options[:nested] true, also assign a initial number to the element name
e.find("input, select").each(function(){
var old_id = $(this).attr("id");
$(this).attr("id", old_id+'_0');
if(option.nested == true) {
var old_name = $(this).attr("name");
var reg = /\[\w*\]$/;
var match = reg.exec(old_name);
var new_name = old_name.substr(0, match.index) + "[0]" + match[0];
...