jessica
jessica

Reputation: 495

Clone div and traverse to whats inside

I have a div with an input inside it, i want to clone this div on click with different id, and i want the id of the input inside it to change also, and i want to limit the number of clones,

var div = document.getElementById('clonedDiv'),
clone = div.cloneNode(true); 
clone.id = "some_id";
document.body.appendChild(clone);
<div id="clonedDiv">
<p>Clone this div</p>
<input type="file" id="clonedInput">
</div>
<br>
<button type="button">Clone me</button>

how can i do that? here is my code:

Upvotes: 0

Views: 277

Answers (4)

Balakrishna Gondesi
Balakrishna Gondesi

Reputation: 118

<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="4.0.6" src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    

    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div id = 'files'>
      
    </div>
    
    <br>
    <button type="button" id = 'clonebtn'>Clone me</button>
  </body>
<script type="text/javascript" charset="utf-8">
  // Code goes here

window.onload = init;

function init() {
 
  const observable = Rx.Observable.fromEvent($('#clonebtn'),'click');

  observable
  .take(4)
  .map(1)
  .scan((acc, curr) => acc + curr)
  .subscribe(i=>$('#files').before(getFileTemplate(i)));
  
}
function getFileTemplate(i){
  
  return `<div id='clonedDiv${i}'>
  <p>Clone this div${i}</p>
  <input type="file" id='clonedInput${i}'>
  </div>`;
}
</script>
</html>

Upvotes: 0

Thijs
Thijs

Reputation: 2351

I'd like to offer a native JS solution to your problem. It is rather straight forward and works in all modern browsers.

  • outerHTML is IE4+, see here
  • insertAdjacentHTML is IE4+, see here

const
  sourceDiv = document.getElementById('clonedDiv'),
  cloneTrigger  = document.getElementById('make-clone'),
  maxClones = 3;
  
let
  clonesCreated = 0;
  
function makeClone() {
  // Make sure there aren't too many clones created.
  if (clonesCreated === maxClones) {
    console.log('max clones reached');
    return;
  }
  
  let
    // outerHTML is llke innerHTML but includes the element itself.
    clone = sourceDiv.outerHTML;
      
  // Replace the two IDs for unique IDs    
  clone = clone.replace('clonedDiv', `clonedDiv_${clones}`);
  clone = clone.replace('clonedInput', `clonedInput_${clones}`);  
  
  // insertAdjacentHTML is like innerHTML except your can tell where it should be inserted in relation to the element. 
  // In this case, add the clone before the button element.
  cloneTrigger.insertAdjacentHTML('beforebegin', clone);
  
  // Increase the number of clones created.
  clonesCreated++;
}
  
cloneTrigger.addEventListener('click', makeClone);
<div id="clonedDiv">
<p>Clone this div</p>
<input type="file" id="clonedInput">
</div>
<br>
<button id="make-clone" type="button">Clone me</button>

Upvotes: 1

Naga Sai A
Naga Sai A

Reputation: 10975

To achieve expected result, use below option

var div = document.getElementById('clonedDiv');
var count = 0;
$('button').on('click',function(){
  if(count <= 3){
    $('#clonedDiv').clone().attr('id','cloneDiv'+count).appendTo('body');
  }

count++;


})

https://codepen.io/nagasai/pen/JrjNmq

Restrict the number clones using count variable
Using ID attribute and count, different ids can be assigned to cloned div - cloneDiv

Upvotes: 0

Terry
Terry

Reputation: 66208

Since you have tagged jQuery in the question, we can use it to greatly simplify things.

  1. Bind a click event handler to the clone button, and we can use it to call a method, say clone(), that will handle all the logic of cloning
  2. Define a global variable, say cloneCount, that stores how many clones have been created, so that we can generate unique IDs
  3. Clone your target <div> element.
  4. Modify all IDs in your target element and its children (use .add() to create a superset) by simply appending cloneCount
  5. Append cloned element to the DOM

If you want to limit the number of clones, simply track cloneCount in the method. When it exceeds a certain threshold, return to exit the function.

Here is a proof-of-concept example:

var $div = $('#clonedDiv');
    
var cloneCount = 0,
    maxCloneCount = 5;
    
var clone = function() {

  // Stop execution if we have cloned max number of times
  if (cloneCount >= maxCloneCount)
    return;

  // Construct clone
  var $clone = $div.clone();
  
  // Replace all IDs (of clone and its children) to make sure it is unique
  $clone.add($clone.children()).attr('id', function() {
    return this.id + '_' + cloneCount;
  });
  
  // Append to DOM
  $('body').append($clone);
  
  cloneCount++;
};

$('button').on('click', function(e) {
  e.preventDefault();
  clone();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clonedDiv">
<p>Clone this div</p>
<input type="file" id="clonedInput">
</div>
<br>
<button type="button">Clone me</button>

Upvotes: 0

Related Questions