0

I am trying to duplicate a whole div on a button click. I've used javascript clone() in order to duplicate the div. I've found the code to do the same here.

I tried the same way. But I didn't get the result. Can anyone help me with this?

Here is my code

html:

<tr>
<div id="duplicater">
<tr>
<td>Service Type:</td>
<td><input type="text" name="servicetype" id="servicetype"></td>
</tr>
<tr>
<td>Amount:</td>
<td><input type="text" name="amount" id="amount"></td>
</tr>
</div>
<tr><td><button id="button" onlick="duplicate()">Add More</button></td></tr>
</tr>

Javascript:

<script>
function duplicate() 
{
var i = 0;
var original = document.getElementById('duplicater');   //alert("hi");
var clone = original.cloneNode(true); // "deep" clone
clone.id = "duplic" + ++i; // there can only be one element with an ID
//original.parentNode.appendChild(clone);
document.body.appendChild(clone);
}

jsfiddle

Community
  • 1
  • 1
Aishwaryas
  • 583
  • 2
  • 14
  • 38
  • 2
    Start by rectifying your **invalid** markup. – undefined Nov 01 '14 at 06:54
  • i.e. `onlick` is a typo; and putting a div that cuts across tr elements is very messy. You also need to move `var i = 0` outside the function – Simon H Nov 01 '14 at 06:59
  • I've corrected the code and avoided the tr elements in [jsfiddle](http://jsfiddle.net/aishwaryas/qp20747v/14/). But still i didn't get the result. – Aishwaryas Nov 01 '14 at 07:09

2 Answers2

3

Your markup is invalid. tr element can't have div child. div element can't have tr child. The markup should be something like:

<tr id="service">
    <td>
        <span>Service Type:</span>
        <input type="text" name="servicetype" id="servicetype">
    </td>
    <td>
        <span>Amount:</span>
        <input type="text" name="amount" id="amount">
    </td>
</tr>

Also the attribute name is onclick not onlick. In the jsFiddle you choose one of the no wrap ... options otherwise JS interpreter can't find your function.

The i variable should be defined outside of the duplicate function otherwise the result is always duplic1, you could also use the length of the rows instead of a counter. Here is an example using insertBefore for inserting the cloned element before the last row:

function duplicate() {    
    var original = document.getElementById('service');
    var rows = original.parentNode.rows;
    var i = rows.length - 1;
    var clone = original.cloneNode(true); // "deep" clone
    clone.id = "duplic" + (i); // there can only be one element with an ID
    original.parentNode.insertBefore(clone, rows[i]);
}

http://jsfiddle.net/4vgrvnn5/

Note that the descendant elements of the cloned element have IDs and your current code/logic doesn't consider this.

undefined
  • 136,817
  • 15
  • 158
  • 186
0

Your markup should be like the following. i.e table rows should only contain table cells (<th>,<td>).

<table> should not have <div>'s as direct child, For grouping <td> elements you can use <tbody>

<table>
 <tfoot>
    <tr>
        <td>
            <button id="addmore" onclick="duplicate()">Add More</button>
        </td>
    </tr>
 </tfoot>
 <tbody id="service">
    <tr>
        <td>Service Type:
            <input type="text" name="servicetype" id="servicetype" />
        </td>
    </tr>
    <tr>
        <td>Amount:
            <input type="text" name="amount" id="amount" />
        </td>
    </tr>
 </tbody>
</table>

Corresponding script will be:

var i = 0;
function duplicate() {
  var table = document.querySelector("table"),
      original = document.getElementById('service'),
      clone = original.cloneNode(true); // "deep" clone
  clone.id = "duplic" + ++i; // there can only be one element with an ID
  table.appendChild(clone);
}

  • You have a typo in the onclick as pointed out in comments.
  • The counter should be outside the function
  • JSFiddle wraps the script in an onload function if it is set to run onload, so inline handlers will not work. You should either set the fiddle script to no-wrap or explicitly declare the function to be global like window.duplicate = function(){}.

Updated Fiddle

T J
  • 40,740
  • 11
  • 73
  • 131