Sidney Sousa
Sidney Sousa

Reputation: 3614

Form field values not pulling through on button click

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

Answers (2)

lissettdm
lissettdm

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

Thales Kenne
Thales Kenne

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

Related Questions