Reputation: 3614
EDITED based on @issettdm answer
I can duplicate all the form fields, put the data inside an object and that object gets pushed to a data array.
const data = [];
const appendContent = () => {
let form_content = document.querySelector(".form-content");
const template = document.createElement('template');
var html = `<div class="form-inline">
<div class="form-group">
<label class="sr-only" for="field-name">Field Name</label>
<input type="text" class="form-control" id="field-name" placeholder="Field Name" name="name">
</div>
<span>-</span>
<div class="form-group">
<label class="sr-only" for="field-name">Field Name</label>
<input type="text" class="form-control" id="field-name" placeholder="Field Type" name="type">
</div>
<span>-</span>
<div class="form-group">
<label class="sr-only" for="field-name">Field Name</label>
<input type="text" class="form-control" id="field-name" placeholder="Default value" name="default">
</div>
<div class="form-group">
<span class="btn btn-danger" data-role="remove">
<span class="glyphicon glyphicon-remove">-</span>
</span>
<span class="add_button btn btn-primary" data-role="add">
<span class="add_button glyphicon glyphicon-plus">+</span>
</span>
</div>
</div>`;
template.innerHTML = html.trim();
form_content.appendChild(template.content.firstChild);
}
const fake_button = document.querySelector('.btn');
fake_button.addEventListener('click', e => {
record(e);
appendContent();
});
const record = (e) => {
const form = e.target.parentElement.parentElement;
const inputs = form.querySelectorAll('input');
const obj = {};
Array.from(inputs).map(input => {
obj[input.name]= input.value;
})
console.log(obj)
data.push(obj);
console.log(data)
}
appendContent();
However, looking at the console I see one problem:
When I console log the data, I see that each object is wrapped in an array:
(2) [{…}, {…}]
0: {_token: "hRQyJ9NlwLdKpZbU7W2REV2I5YF6Pg8D6HcoCof7", name: "4t43", type: "t34t43", default: "tt34t"}
1: {_token: "hRQyJ9NlwLdKpZbU7W2REV2I5YF6Pg8D6HcoCof7", name: "t3t43", type: "43t4t", default: "t34t3"}
length: 2
__proto__: Array(0)
Is there a way to convert the above to the following so that I can have one array with multiple objects?
(2) [{…}, {…}]
{_token: "hRQyJ9NlwLdKpZbU7W2REV2I5YF6Pg8D6HcoCof7", name: "4t43", type: "t34t43", default: "tt34t"}
{_token: "hRQyJ9NlwLdKpZbU7W2REV2I5YF6Pg8D6HcoCof7", name: "t3t43", type: "43t4t", default: "t34t3"}
length: 2
__proto__: Array(0)
Upvotes: 0
Views: 81
Reputation: 13078
I assumed that you don't want to repeat the add button, then, I removed the button from the template, that way you can only add the input fields:
Here you can find a working example: https://stackblitz.com/edit/js-gp6xjx?file=index.html
const data = [];
const appendContent = () => {
let form_content = document.querySelector(".form-content");
const template = document.createElement('template');
const html = `<div class="row">
<div class="form-group">
<input type="text" placeholder="Enter Name" class="form-control" name="name">
</div>
<div class="form-group">
<input type="text" placeholder="Enter Description" class="form-control" name="description">
</div>
</div>
`
template.innerHTML = html.trim();
form_content.appendChild(template.content.firstChild);
}
const fake_button = document.querySelector('.btn');
fake_button.addEventListener('click', e => {
record(e);
appendContent();
});
const record = (e) => {
const form = e.target.parentElement.parentElement;
const inputs = form.querySelectorAll('input');
const obj = {};
Array.from(inputs).forEach(input => {
obj[input.name]= input.value;
})
data.push(obj);
console.log(data);
}
appendContent();
.btn {
display: block;
width: 70px;
cursor: pointer;
border: 1px solid #333;
padding: 5px 10px;
text-align: center;
}
<form action="" method="post" id="create-db-form">
<div class="form-content"></div>
<div class="form-group btn-with-margin">
<span class="btn btn-primary">Add</span>
</div>
<button type="submit">Save</button>
</form>
Upvotes: 1
Reputation: 2942
Alright, so I was fiddling with it a little bit, I'm not very experienced with pure javascript. I came up with a few ideas:
1 - Separate submit and add field buttons.
When you press add field, it just adds new fields inside your form which will later be submitted as part of a complete form.
2 - Indexed forms
The idea here is to create a form of forms, with each pair of inputs consisting of a form itself. Later, when you want to submit, you just query all forms and each result will be under a 'name = index' prop.
I found this snippet to retrieve form values:
function getFormValues() {
var params = [];
for( var i=0; i<document.myform.elements.length; i++ )
{
var fieldName = document.myform.elements[i].name;
var fieldValue = document.myform.elements[i].value;
params.push({[fieldName]:fieldValue});
}
console.log(params);
}
I was testing it in this fiddle: https://jsfiddle.net/968cL1uz/28/
I only posted an answer to be able to write more about your problem, I'm sorry if this still doesn't solve it. Let's keep working on it :)
Upvotes: 0