1

My code is listed in this https://jsfiddle.net/tek8b41g/1/

I want to make it so that I can add another form if I need another "trip" is there an easy way to do this? I was thinking about doing hidden divs but wondered if there was another way.

Thanks in advance.

Html:

<body bg=grey>
  <div id="wrap">
    <tr>
      <form method="POST"><br />
        <div id="center">
          <center>Driver Line Input page </center>
        </div>
        <br />
        <div class="centerDynamic">
          <label>
            <input type="radio" name="countyLabel" value="radio" id="countyLabel_0" />Eagle County</label>

          <label>
            <input type="radio" name="countyLabel" value="radio" id="countyLabel_1" />Summit County</label>
            <br />Driver Name: <input name="dNameT1" type="text" value="" size="25" /><br />Trip Time: <input name="tripTimeT1" type="text" value="" size="5" /><br />First Pickup: <input name="firstPickupT1" type="" value="" size="5" /><br />Town: <input name="townT1" type="text" value="" size="25" id="townT1" /><br />
           <label>Transfer during this trip:<input type="radio" name="transferYesT1" value="radio" id="transferGroup_1T1" />Yes</label>
           <label>
             <input name="transferNoT1" type="radio" id="transferGroup_1a" value="radio" checked="checked" />No</label>
              <br />
              <label for="transferDrivera">Transfer Driver</label> <input type="checkbox" name="transferDriverT1" id="transferDrivera" />
              <br />Need Carseat/Booster?<label>
              <input type="radio" name="carseatYesT1" value="radio" id="RadioGroup1_0" />Carseat</label>
              <label><input type="radio" name="boosterYesT1" value="radio" id="RadioGroup1_1" />Booster</label>
              <label><input type="radio" name="noneT1" value="radio" id="RadioGroup1_2" />None</label>
                 <br /><br />
        </div>
       <input type="button" value="Add Another Trip" onClick="addInput('centerDynamic');" />
      </form>
     </tr>
   </div>
 </body>

CSS:

 @charset "utf-8";
 /* CSS Document */

 #wrap { 
 width: 900px; 
 margin: 0 auto; 
 }
 #centerDynamic{
 width: 500px;
 margin: 0 auto;
 }

Javascript:

  var counter = 1;
  var limit = 34;
  function addInput(centerDynamic){
  if (counter == limit) {
     alert("You have reached the limit of adding " + counter + " inputs");
}
   else{
    var newdiv = document.createElement('div');
    newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'>"; 
  document.getElementById(centerDynamic).appendChild(newdiv);
     counter++;
  }
  }
Chickpea
  • 41
  • 1
  • 1
  • 8
  • 1
    Please indent your code properly. See http://mdo.github.io/code-guide/ – Oisin Feb 19 '16 at 23:34
  • Would new `form` element contain same elements as existing `form` element ? Or, should only a single `input` element be added to existing `form` ? – guest271314 Feb 19 '16 at 23:39
  • Why is your question tagged [tag:jquery] if you are using pure JavaScript, not jQuery? – Luke Feb 19 '16 at 23:46
  • same form element, everything in the main div exactly the same as the original form. Different inputs, with different id's so that they can be displayed according to a set of rules. – Chickpea Feb 19 '16 at 23:56
  • i thought someone could use jquery if they knew of a way. also stack overflow suggested it. – Chickpea Feb 19 '16 at 23:57
  • 1. Just because Stackoverflow suggests something doesn't mean that it's right. 2. _i thought someone could use jquery if they knew of a way_ you should have added that information into the question. – Luke Feb 19 '16 at 23:58
  • 1
    _"same form element, everything in the main div exactly the same as the original form"_ Try using `Node.cloneNode` https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode , `setAttribute` – guest271314 Feb 20 '16 at 00:06

2 Answers2

1

centerDynamic is a className , not an id. Also, there was a tr element though no table parent element at html . Try substituting document.querySelector("." + centerDynamic) for document.getElementById(centerDynamic) , removing tr element

@charset "utf-8";

/* CSS Document */

#wrap {
  width: 900px;
  margin: 0 auto;
}
.centerDynamic {
  width: 500px;
  margin: 0 auto;
}
<body bg=grey>
  <div id="wrap">
    <form method="POST">
      <br />
      <div id="center">
        <center>Driver Line Input page</center>
      </div>
      <br />
      <div class="centerDynamic">
        <label>
          <input type="radio" name="countyLabel" value="radio" id="countyLabel_0" />Eagle County</label>

        <label>
          <input type="radio" name="countyLabel" value="radio" id="countyLabel_1" />Summit County</label>
        <br />Driver Name:
        <input name="dNameT1" type="text" value="" size="25" />
        <br>Trip Time:
        <input name="tripTimeT1" type="text" value="" size="5" />
        <br>First Pickup:
        <input name="firstPickupT1" type="" value="" size="5" />
        <br>Town:
        <input name="townT1" type="text" value="" size="25" id="townT1" />
        <br>
        <label>
          Transfer during this trip:
          <input type="radio" name="transferYesT1" value="radio" id="transferGroup_1T1" />Yes
        </label>
        <label>
          <input name="transferNoT1" type="radio" id="transferGroup_1a" value="radio" checked="checked" />No
        </label>
        <br />
        <label for="transferDrivera">Transfer Driver</label>
        <input type="checkbox" name="transferDriverT1" id="transferDrivera" />
        <br>Need Carseat/Booster?
        <label>
          <input type="radio" name="carseatYesT1" value="radio" id="RadioGroup1_0" />Carseat
        </label>
        <label>
          <input type="radio" name="boosterYesT1" value="radio" id="RadioGroup1_1" />Booster
        </label>
        <label>
          <input type="radio" name="noneT1" value="radio" id="RadioGroup1_2" />None
        </label>
        <br />
        <br />
      </div>
      <input type="button" value="Add Another Trip" onclick="addInput('centerDynamic');" />
    </form>
  </div>
  <script>
    var counter = 1;
    var limit = 34;

    function addInput(centerDynamic) {
      event.preventDefault();
      if (counter == limit) {
        alert("You have reached the limit of adding " + counter + " inputs");
      } else {
        var newdiv = document.createElement('div');
        newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'>";
        document.querySelector("." + centerDynamic).appendChild(newdiv);
        counter++;
      }
    }
  </script>
</body>
guest271314
  • 1
  • 15
  • 104
  • 177
  • Ok so I removed tr elements. Is there a problem with having the parent div as a class instead of an id? – Chickpea Feb 20 '16 at 00:07
  • No, there is no issue with parent `div` having `class` instead of `id` ; issue was that `#centerDynamic` did not exist in document – guest271314 Feb 20 '16 at 00:10
  • Sorry, ive been fiddling with this for a while and went originally from id to class and must have forgotten to change something. My only issue is that this snippet doesn't work either. It looks like the fiddle had the right code. – Chickpea Feb 20 '16 at 00:15
  • _"My only issue is that this snippet doesn't work either."_ ? Can describe "doesn't work" ? Appears to add an `input` to `form` at stacksnippets, here. Note also that `event.preventDefault()` was included due to `button` click within `form` submits `form` . stacksnippets and jsfiddle should have same `html` , `js` ; can you describe what is different between the two ? – guest271314 Feb 20 '16 at 00:17
  • when i click on run code snippet from your above code I see no physical change for when I click "add another trip" button. That is what I mean by it doesn't work – Chickpea Feb 20 '16 at 00:26
  • _"when i click on run code snippet from your above code I see no physical change"_ Interesting. An `input` element is appended to document, here. Did you scroll down after clicking button ? – guest271314 Feb 20 '16 at 00:38
  • I used full page to view – Chickpea Feb 20 '16 at 00:39
  • Not sure why stacksnippets not returning expected results there ? Are any errors logged to `console` ? – guest271314 Feb 20 '16 at 00:43
  • "ReferenceError: event is not defined" – Chickpea Feb 20 '16 at 01:23
  • @Chickpea Not receiving that error here. Try including `console.log(event)` before `event.preventDefault()` – guest271314 Feb 20 '16 at 01:39
1

Copy a Form

Objective: Click a button to duplicate a form.

Solution: Utilized cloneNode() and appendChild() methods

Issues: OP's function in general was not nearly adequate enough to handle objective. Instead of going down a list of what was wrong, we will continue to explore the solution and attempt to highlight certain areas where there were discrepancies.

HTML

  • #id: OP's code had no occurrence of duplicated ids but I'm mentioning this because it's a common mistake seen very frequently. When duplicating HTML it's important to always remember that there should never be any duplicated ids.

  • name: This attribute is used extensively by form elements and is essential when used with <input type="radio">. For each group of radio buttons we should always assign one name to each radio button. This insures that only one radio button is selected out of the group.

  • Tip: When assigning id and name to <form> and form elements, it's easier just to make them both the same value (with the exception of radio buttons). For a short unbiased explanation see this post. There are varying opinions on this topic, my take is if you use the same name and id on each form element, then you have every option available and you don't have to worry whether you used the correct one or not. Keep in mind, if at all possible, try keeping id and name simple yet functional especially if you intend to copy and number them.

CSS

Assuming this is only a draft, and not a finished project, we won't go into the minutiae of styling. Note, I have changed the CSS significantly, so feel free to ask or critique.

JS

I couldn't really consider OP's code as copying a form, it's more like an extension:

Result:

 // up to 34 extra identical inputs that don't match up to the original form.

 <br><input type='text' name='myInputs[]'>   

Not very useful. Here's a breakdown of what I've seen on the subject of duplicating forms:

  • The common way of using JS to duplicating a form is by using the methods cloneNode() and appendChild().

  • By default cloneNode() is actually cloneNode(false) the argument is a boolean that determines how deep the cloning is. If set to false or not at all, cloneNode() will result in a shallow copy--all attributes, value, and no children. Set to true, will result in a deep copy--all descendants, attributes, and values--everything (with one exception--being event listeners/binding will not be copied).

  • Since all attributes are copied, that would also mean id as well. We must make provisions for this by way of collecting every element in the clone and assigning each one a unique id. The demo provides this by means of using the following:

Demo

There are step by step comments in the JS. I left out some details because I don't want to put you to sleep. Be aware this is not the only way to achieve your objective, this is one of many.

Plunker

Snippet

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>35517008</title>
<style>
* { vertical-align: baseline; }
h2 { text-align: center; }
.center { margin: 0 auto; }
fieldset { margin: 0 auto; width: 50%; }
fieldset div { float: left; clear: left; }
#btn1 { position: relative; left: 65%; }
input[type="submit"] { float: right; }
input { margin: 0 5px 5px 0; }
label { padding: 0 0 5px 5px; }
input + input { margin-left: 10px; }

</style>
</head>

<body>

  <h2>Driver Line Input Page</h2>
<input id="btn1" class="center" type="button" value="Add Additional Trip" />

    <form id="line1" name="line1" method="post" class="center">
    <fieldset>
    <legend>Line 1</legend>
    <div>
      <label>
        <input type="radio" name="county" value="radio" id="eagle" />
        Eagle County
        <input type="radio" name="county" value="radio" id="summit" />
        Summit County
        </label>
     </div>
     <div>
      <label for="driver">Driver Name:
      <input name="driver" id="driver" type="text" size="25" />
      </label>
      </div>
      <div>
      <label for="time">Trip Time:
      <input name="time" id="time" type="text" size="5" />
      </label>
      <label for="pickup">First Pickup:
      <input name="pickup" id="pickup" type="text" size="5" />
      </label>
      
      <label for="city">City:
      <input name="ciy"  id="city" type="text" size="25" />
      </label>
      </div>
      <div>
      <label>Transfer Enroute:
        <input type="radio" name="trans" id="yes" />
        Yes
     
        <input type="radio" name="trans" id="no" checked />
        No
     </label>
     
      <label for="tDriver">Transfer Driver:
      <input name="tDriver" id="tDriver" />
      </label>
    </div>
    <div>
      <label>Carseat/Booster Request:
   
        <input type="radio" name="child" id="seat" />
        Carseat
     
        <input type="radio" name="child" id="booster" />
        Booster
      
        <input type="radio" name="child" id="none" checked />
        None
        </label>
        </div>
        <input type="submit" id="submit" name="submit"/>

</fieldset>
      <br />
      <br />
      
    </form>


<script>

/* When the "Add Additional Trip" button is clicked ... */
var btn1 = document.getElementById('btn1');
btn1.addEventListener('click', function(e) {
 
 // Collect all forms into a NodeList
  var forms = document.querySelectorAll('form');
 
 // Total number of forms and the new serial number
  var qty = forms.length;
 var step = (qty + 1).toString();
 
 // The original form
  var template = forms[0];
 
 // Make a clone of the original form
  var dupe = template.cloneNode(true);
 
 // Reference the clone's displayed title
 var line = dupe.querySelector('legend');
 
 // Set clone's title to Line {{number}}
 line.innerHTML = "Line "+ step;
 
 // Set clone's id and name to form{{number}}
  dupe.setAttribute('id', 'line'+ step);
 dupe.setAttribute('name', 'line'+ step);
 
 // Collect all of clone's inputs into a NodeList
 var inputs = dupe.querySelectorAll('input');
 
 // Convert the NodeList into an Array
 var inpArray = Array.prototype.slice.call(inputs);
 
 // Iterate through the Array and assign a unique id and name to each one
 for(var i = 0; i < inpArray.length; i++) {
  var inpID = inpArray[i].getAttribute('id');
  var inpName = inpArray[i].getAttribute('name');
  inpArray[i].setAttribute('id', inpID + step);
  inpArray[i].setAttribute('name', inpName + step);
 }
 
 // Place clone after the last form
  document.body.appendChild(dupe);
}, false);
</script>
</body>
</html>
Community
  • 1
  • 1
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • Thank you for being so detailed. This is exactly what I was looking for. I figured there was multiple ways to achieve the same result. This is perfect. – Chickpea Feb 24 '16 at 03:44
  • You're very Welcome, I'm happy to oblige. :-) – zer00ne Feb 24 '16 at 04:19