Создание массива объектов из формы

#javascript #html

#javascript #HTML

Вопрос:

Я работаю над формой, в которую пользователь (родитель) может добавлять информацию о нескольких дочерних элементах.
Мой текущий код выглядит примерно так::

 (() => {
  let currentCount = 0
  const submitButton = document.querySelector('#submitForm')

  document.querySelector('#addMoreFields').addEventListener('click', (event) => {
    event.preventDefault()

    // find and clone the template content
    const theForm = document.querySelector('#theForm')
    const template = theForm.getElementsByTagName('template')[0]
    const clone = template.content.cloneNode(true)

    // if the submitButton is hidden, show it
    if (submitButton.offsetParent === null) {
      submitButton.removeAttribute('style')
    }

    // add class to set and name on input fields
    clone.querySelector('.set').classList.add(`set-${currentCount}`)
    clone.querySelector('.first_name').setAttribute('name', `firstName[${currentCount}]`)
    clone.querySelector('.middle_name').setAttribute('name', `middleName[${currentCount}]`)
    clone.querySelector('.last_name').setAttribute('name', `lastName[${currentCount}]`)
    theForm.append(clone)

    currentCount  
  })
  
  submitButton.addEventListener('click', (event) => {
    event.preventDefault()
    
    const theArray = []
    // create an object and push to the array
  })
})()  
 .set {
  margin: 5px;
  padding: 5px;
  outline: 1px solid #ccc;
}  
 <form id="theForm">
  <template>
    <div class="set">
      <input class="first_name" placeholder="first name" />
      <input class="middle_name" placeholder="middle name" />
      <input class="last_name" placeholder="last name" />
    </div>
  </template>
  <button id="addMoreFields">add</button>
  <button id="submitForm" style="display: none;">submit</button>
</form>  

Моя проблема в том, как я могу создать массив объектов для отправки на серверную часть.
Мы используем только ванильный javascript, поэтому jQuery не подходит 😞

Ответ №1:

Вы можете уменьшить все div.set , используя редуктор, также для input -полей внутри каждого div.set . Нравится:

 (() => {
  let currentCount = 0
  const submitButton = document.querySelector('#submitForm')
  // reducer for inputs within div.set
  const inputs2ObjectReducer = (acc, inp) => ( { ...acc, [inp.className]: inp.value } );
    
  document.querySelector('#addMoreFields').addEventListener('click', (event) => {
    event.preventDefault();

    // find and clone the template content
    const theForm = document.querySelector('#theForm');
    const template = theForm.getElementsByTagName('template')[0];
    const clone = template.content.cloneNode(true);

    // if the submitButton is hidden, show it
    if (submitButton.offsetParent === null) {
      submitButton.removeAttribute('style');
    }

    // add class to set and name on input fields
    clone.querySelector('.set').classList.add(`set-${currentCount}`);
    clone.querySelector('.first_name').setAttribute('name', `firstName[${currentCount}]`);
    clone.querySelector('.middle_name').setAttribute('name', `middleName[${currentCount}]`);
    clone.querySelector('.last_name').setAttribute('name', `lastName[${currentCount}]`);
    theForm.append(clone);

    currentCount  ;
  })

  submitButton.addEventListener('click', (event) => {
    event.preventDefault();
    
    // Reduce all div.set to array of objects
    const theArray = [...document.querySelectorAll(".set")]
      .reduce( (acc, val) =>
        [...acc, 
        [...val.querySelectorAll("input")]
          .reduce(inputs2ObjectReducer, {})], [] );
        
    console.log(theArray);
  })
})()  
 .set {
  margin: 5px;
  padding: 5px;
  outline: 1px solid #ccc;
}  
 <form id="theForm">
  <template>
    <div class="set">
      <input class="first_name" placeholder="first name" />
      <input class="middle_name" placeholder="middle name" />
      <input class="last_name" placeholder="last name" />
    </div>
  </template>
  <button id="addMoreFields">add</button>
  <button id="submitForm" style="display: none;">submit</button>
</form>