2

I got this code from here which i have modified a bit to add unique numbers to the inputs.

var i = 1;

function addkid() {
  i++;
  var div = document.createElement('div');
  var id = i;
  div.innerHTML = 'Child_' + id + ': <input type="text" name="child_' + id + '"/>' + ' <input type="button" id="add_kid()_' + id + '" onclick="addkid()" value="+" />' + ' <input type="button" id="rem_kid()_' + id + '" onclick="remkid(this)" value="-" />';
  document.getElementById('kids').appendChild(div);
}

function remkid(div) {
  document.getElementById('kids').removeChild(div.parentNode);
  i--;
}
<form>
  Name:
  <input type="text" name="name">
  <br/>
  <div id="kids">
    Child_1:
    <input type="text" name="child_1">
    <input type="button" id="add_kid()_1" onclick="addkid()" value="+" />
  </div>
  Phone:
  <input type="text" name="phone">
  <br/>
  <input type="submit" name="submit" value="submit" />
</form>

When i view it in the browser, i can add/remove textboxes properly, but if i remove some textboxes from in-between, then the Child_id numbers repeat again, resulting in input textboxes with duplicate IDs.

  1. How do i make sure there are no duplicate or missing ids?
  2. How can i grab values from each of these dynamic textboxes using their IDs or name and create a JSON object dynamically on submit?
  3. How can i pass on these values or the JSON object to Appscript?

Any help would be most welcome.

3 Answers 3

3

Question 1: This code should take care of giving unique ids to your textBox with out any gaps in the id number. I achieve this by using a function getID which keeps track of available ids in an array. Whenever we remove an element, the array value with that index is set to -1. We search for "-1" using indexOf and keep track of unused ID.

var index = [];
// Array starts with 0 but the id start with 0 so push a dummy value
index.push(0);
// Push 1 at index 1 since one child element is already created
index.push(1)

function addkid() {
  
  var div = document.createElement('div');
  var id = getID();
  // Set this attritube id so that we can access this element using Id 
  div.setAttribute("id","Div_"+id);
  
  div.innerHTML = 'Child_' + id + ': <input type="text" name="child_' + id + '"/>' + ' <input type="button" id="add_kid()_' + id + '" onclick="addkid()" value="+" />' + ' <input type="button" id="rem_kid()_' + id + '" onclick="remkid('+id+')" value="-" />';
  // inside of passing this parameter in remkid we pass id number
  document.getElementById('kids').appendChild(div);
}
   
function remkid(id) {
// use the id arugment to get the div element using unique id set in addkid
  try{
var element = document.getElementById("Div_"+id)
element.parentNode.removeChild(element);
    index[id] = -1;
    //id number is = index of the array so we set to -1 to indicate its empty
    }
  catch(err){
    alert("id: Div_"+id)
    alert(err)
    
    }
}  
 function getID(){
   var emptyIndex = index.indexOf(-1);
   if (emptyIndex != -1){
     index[emptyIndex] = emptyIndex
     
     return emptyIndex
   } else {
   emptyIndex = index.length
   index.push(emptyIndex)
   return emptyIndex
     }
   }
  
<form action ="Your app script link here" method="post">
  Name:
  <input type="text" name="name">
  <br/>
  <div id="kids">
    Child_1:
    <input type="text" name="child_1">
    <input type="button" id="add_kid()_1" onclick="addkid()" value="+" />
  </div>
  Phone:
  <input type="text" name="phone">
  <br/>
  <input type="submit" name="submit" value="submit" />
</form>

Question 2,3: You can pass the value of the form to a app script using the form tag:

<form action= "app script web app link" method ="post/get">

Now to access the data using appscripts, we will have to make a web app and get a link to it. This will help you get started:https://developers.google.com/apps-script/guides/web

You will create a appscript like this:

function doPost(e) {
  var ss = SpreadsheetApp.openById("Your Spd ID")
  var sheet = ss.getSheetByName("Sheet1")
  var response = []
  response[0] = new Date() 
  response[1] = e.contentLength
  response[2] = JSON.stringify(e.parameters)
  sheet.appendRow(response)
  return HtmlService.createHtmlOutput('<b>Hello, world!</b>');
}

And your sheet1 will receive a response like so:

2/12/2017 14:17:37  47  {"parameter":{"submit":"submit","child_1":"asd","phone":"1234","name":"jagan"},"contextPath":"","contentLength":47,"queryString":null,"parameters":{"submit":["submit"],"child_1":["asd"],"phone":["1234"],"name":["jagan"]},"postData":{"type":"application/x-www-form-urlencoded","length":47,"contents":"name=jagan&child_1=asd&phone=1234&submit=submit","name":"postData"}}
Sign up to request clarification or add additional context in comments.

5 Comments

This works! Thanks @jagannathan alagurajan. One question: right now the jsondata only includes the dynamic textboxes values. can it also be made to include values from other static controls .e.g "name", "phone" or a date field?
I am not sure I understand your question, name and phone values will be passed to app script as long they are within the form tag ( <form> Input element within here will be posted to the URL </form>)
understood. what do i put in '<form action= "app script web app link" method ="post/get">' ? the link to the webapp that gets created, just as you showed how to create?
action = "put your app script url here", method ="post" if you are using my example. To get app script url, copy and past the dopost function in script.google.com and publish it.
Particularly interesting is your getID function. Could you elaborate on it (when free) to make my understanding clear?
1

If skipping id numbers is not a concern, you could just remove the i-- from remkid(). That would prevent any duplicate IDs. Otherwise, you could do something like:

var i = 1;
var removedkids = [];

function addkid() {
  if (removedkids.length > 0) {
    newid = removedkids.shift();
  } else {
    newid = i;
    i++;
  }
}

function removeKid(id) {
  removedkids = removedkids.push(id).sort();
}

6 Comments

If suppose i have added 30 text input boxes and then i go ahead and delete some input boxes say, 2, 5, 9, 16 in between, can i add these below and still maintain the sequence again from 31 onwards?
This code will remove the 2,5,9,16 forever, when you add a new kid the counter will start from 31.
Essentially your id numbers won't be consecutive and will have breaks in them like so 1,3,4,6,7,8,10-30
@Mohd Asim Suhail, but can i also fill in the blanks and then start from 31?
@Jagannathan Alagurajan, but can i also fill in the blanks and then start from 31?
|
1
  1. Instead of monitoring i you can monitor name of last child added inside div#kids by using document.querySelectorAll('#kids input[type=text]')[document.querySelectorAll('#kids input[type=text]').length-1].name.split("_")[1]

this will get the name of last child and set the id of next child according to it.

Demo : https://jsfiddle.net/8Ljvgmac/1/

  1. I have update the jsfiddle link and a function named captureResponse will dynamically iterate over childs added and return a JSONObject. You can call this function onsubmit of function.

3.You can hit a GET or POST request to Appscript and get the data in Appscript to process it

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.