0

Hi I am trying to figure out how to add input element on button click using plain javascript to be used latter for sending data to backend.

<div class="myDiv">
<input type="text" id="inputData" name="selectOption">
        <select id="optionData">
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="opel">Opel</option>
            <option value="audi">Audi</option>
        </select>
<div class="myDiv">

<input type="button" value="Add element" onclick="AddElement()">

I would be using that to send data to the backend. The only approach that I could think of was declare a global javascript array and use it to store it

var elements = [];
function AddElement() {
  const inputData = document.getElementById("inputData").value;
  const optionData = document.getElementById("optionData").value;
  const data = {
    inputData: inputData,
    optionData: optionData
  };
  elements.push(data);
  // create new element in dom with the data and random ids and clear the inputData and optionData element.
}

The problem with the above is that changes to existing element would not reflect in the global array.

Could someone suggest a better approach?

ashley
  • 181
  • 1
  • 8
  • _“I would be using that to send data to the backend.”_ - why would that need any IDs in the first place? _“Could someone suggest a better approach?”_ - elements can be selected in a multitude of different ways, it does not always have to be by ID. So explain what they are actually needed for in the first. – CBroe Sep 09 '20 at 12:28
  • 1
    you can use array input , refere https://stackoverflow.com/a/42293411/6309457 – Devsi Odedra Sep 09 '20 at 12:29
  • @CBroe unique id is not required, just simple way to add elements on button click that could be latter used for sending data on backend – ashley Sep 09 '20 at 12:41
  • Then I don’t get what the actual question is supposed to be here. – CBroe Sep 09 '20 at 12:42
  • The current implementation would not reflect the changes on updated made to the already added element – ashley Sep 09 '20 at 12:44
  • You got me a bit censused also, What will you be using to send data to back-end, PHP or JS? Is this part of HTML form? – ikiK Sep 09 '20 at 13:30

1 Answers1

0

It is a bit uncleaner how will you send data to server etc and I see there is some confusion on technique how to achieve this. So I will cover two scenarios. Both will make new input fields out of your initial select and input as requested and additionally quid how to send them to server.

I will not make unique ids or name attributes on those fields because that would mean you would need to know in front what ids or names are generated and fetch them on server side on submit, instead when submitting a form using HTML and PHP, we will make array with input names attribute. Case with JS sending data to server will be similar using arrays.

First way using PHP and setting form inputs names as array:

1 - Create a form below your input and select

<form id="result">
...
</form>

2 - On click of button, save data into variable like you did, then clear those fields:

document.getElementById("inputData").value="";
document.getElementById("optionData").value="";

3 - Then create two input fields, fill them with data and append them into form:

document.querySelector("#result").innerHTML +=
 '<input type="text"  name="inputData[]" value="'+inputData+'">
<input type="text"  name="optionData[]" value="'+optionData+'"><br>';

4 - One of the input fields will have name="inputData[]" other will have name="optionData[]". Notice the [] sign, that will on form submit create on array. Then or server side for example with PHP you catch that array and use foreach() to send them to server as keys and values. Please read more about this here: Posting Form Fields with same Name Attribute

EXAMPLE SNIPPET:

var elements = [];

function AddElement() {
  const inputData = document.getElementById("inputData").value;
  const optionData = document.getElementById("optionData").value;
  
  // create new element in dom with the data and random ids and clear the inputData and optionData element.

  document.getElementById("inputData").value="";
  document.getElementById("optionData").value="";
  //clear the inputData and optionData element.
  
  document.querySelector("#result").innerHTML += '<input type="text"  name="inputData[]" value="'+inputData+'"><input type="text"  name="optionData[]" value="'+optionData+'"><br>';
  // add new line with 2 inputs, one is inputData other is optionData

}
<div class="myDiv">
  <input type="text" id="inputData" name="selectOption">
  <select id="optionData">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="opel">Opel</option>
    <option value="audi">Audi</option>
  </select>
<form id="result">


</form>

  <input type="button" value="Add element" onclick="AddElement()">
</div>

Sending data with JS can be done in multiple ways. You could use above HTML markup and then catch all form data like this:

//EXAMPLE USING JS TO GET FORM DATA
var formData = new FormData(document.querySelector('#result'))
console.clear()
for (var pair of formData.entries()) {
    console.log(pair[0]+ ' - ' + pair[1]); 
    // here you could send AJAX data to server for each entry 
}

Please read more about how to How can I get form data with JavaScript/jQuery?

SNIPPET EXAMPLE:

var elements = [];

function AddElement() {
  const inputData = document.getElementById("inputData").value;
  const optionData = document.getElementById("optionData").value;
  
  // create new element in dom with the data and random ids and clear the inputData and optionData element.

  document.getElementById("inputData").value="";
  document.getElementById("optionData").value="";
  //clear the inputData and optionData element.
  
  document.querySelector("#result").innerHTML += '<input type="text"  name="inputData" value="'+inputData+'"><input type="text"  name="optionData" value="'+optionData+'"><br>';
  // add new line with 2 inputs, one is inputData other is optionData

//EXAMPLE USING JS TO GET FORM DATA
var formData = new FormData(document.querySelector('#result'))
console.clear()
for (var pair of formData.entries()) {
    console.log(pair[0]+ ' - ' + pair[1]); 
    // here you could send AJAX data to server for each entry 
}

}
<div class="myDiv">
  <input type="text" id="inputData" name="selectOption">
  <select id="optionData">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="opel">Opel</option>
    <option value="audi">Audi</option>
  </select>
<form id="result">


</form>

  <input type="button" value="Add element" onclick="AddElement()">
</div>

Or you could like you intended save them into arrays on initial creation per each row and send items using AJAX without even using HTML form.

AND TO answer the question how to create unique ids, names or classes: Declare i variable as number 0 outside of click function:

i="0";
//set initial unique number i

then inside click call it like this ++i this will result in optionData1, optionData2 etc on every ++i initiation:

name="optionData'+(++i)+'"

you can use it on ids, classes or anything:

id="newId'+(++i)+'"

newid1, newid2 etc...

But like i said, you cant really generate unique ids or anything because you can not program them in front to use them to send fields to server.

Example:

var elements = [];

i = "0";
//set initial uniqe number i

function AddElement() {
  const inputData = document.getElementById("inputData").value;
  const optionData = document.getElementById("optionData").value;

  // create new element in dom with the data and random ids and clear the inputData and optionData element.

  document.getElementById("inputData").value = "";
  document.getElementById("optionData").value = "";
  //clear the inputData and optionData element.

  document.querySelector("#result").innerHTML += '<input type="text"  name="inputData' + (++i) + '" value="' + inputData + '"><input type="text"  name="optionData' + (++i) + '" value="' + optionData + '"><br>';
  // add new line with 2 inputs, one is inputData other is optionData
  // use ++i to generate last number plus, and just add it to some name, id or class; name="optionData'+(++i)+'"
  
  console.clear();
  [...document.querySelectorAll('#result > input')].forEach(input => {
      console.log(input.getAttribute("name"));      
    })
  }
<div class="myDiv">
  <input type="text" id="inputData" name="selectOption">
  <select id="optionData">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="opel">Opel</option>
    <option value="audi">Audi</option>
  </select>
  <form id="result">


  </form>

  <input type="button" value="Add element" onclick="AddElement()">
</div>
ikiK
  • 6,328
  • 4
  • 20
  • 40