uriah
uriah

Reputation: 2583

How to clone an element and insert it multiple times in one go?

How can I clone an element and insert it 5 times right after each other? This of course is the base statement:

$('.col').clone().insertAfter('.col');

Here's what I need to get:

<div class="col" id="original"> </div>
<div class="col"> </div>
<div class="col"> </div>
<div class="col"> </div>
<div class="col"> </div>
<div class="col"> </div>

The selector doesn't need to be using an unique id, it can also be a class selector.

I could just repeat the base statement four times but there must be a more elegant way?

Upvotes: 12

Views: 27616

Answers (6)

Nagibaba
Nagibaba

Reputation: 5368

You might want to clone fields when the document is ready against cloning any changes made by client. This is mostly active issue with inputs. Then you should:

  1. Clone the element on document ready: var elementClone = $('#element').clone()

  2. on click clone the cloned element again and add elementClone.clone().insertAfter(element)

Upvotes: 0

Gerard Duffy
Gerard Duffy

Reputation: 27

$(document).ready(function() {
    var e = $('.col');
    for (var i = 0; i < 5; i++) {
      e.clone().insertAfter(e);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="col">clone me...</div>

`

Upvotes: 1

lvalencia
lvalencia

Reputation: 1

Javascript Array has a fill function:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

So you could write something like this

 $(
   new Array(copies).fill(function () { 
     return $(this).clone(); 
   }.bind(el))
   .map(function (el) {
     return el();
   })
 ).map(function() { return this.toArray(); }); //Turn into jQuery

and if you wanted it as a jQuery function that you could re-use you could write something like this

$.fn.multiply = function(amount) {
   var cloneFunction = (function() {
     return $(this).clone();
   }).bind(this);

   return $(
      new Array(amount).fill(cloneFunction).map(function(el) {
         return el();
      });
   ).map(function() { return this.toArray(); }); //Turn into jQuery
}

this gives you the flexibility to separate the function call of clone from being evaluated only when you need it. So if you wanted to you could split up the call and evaluate later.

meaning this is the promise (it returns functions with bound context to this that when called will clone)

new Array(amount).fill(cloneFunction);

and this is the resolution

.map(function(el) { return el(); })

and this little last bit handles the fact that I created an array of jQuery objects but really I want a jQuery collection

.map(function() { return this.toArray(); }); //Turn into jQuery

but at any rate your final solution would look something like this, if you go this route.

$(el).multiply(amount).insertAfter(anotherEl);

cheers

Upvotes: 0

Alex W
Alex W

Reputation: 38253

I wrote a jQuery plug-in:

$.fn.multiply = function(numCopies) {
    var newElements = this.clone();
    for(var i = 1; i < numCopies; i++)
    {
        newElements = newElements.add(this.clone());
    }
    return newElements;
};

This code snippet builds the elements as a jQuery set, instead of adding to the DOM multiple times which can be slow.

Usage:

var li = $('<li>Test</li>');
$('ul').append(li.multiply(4));

So, for your example:

$('.col').multiply(5).insertAfter('.col');

Upvotes: 1

Guffa
Guffa

Reputation: 700630

Use a loop, like this:

$(document).ready(function() {
    var e = $('.col');
    for (var i = 0; i < 5; i++) {
      e.clone().insertAfter(e);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="col">clone me...</div>


Put the element in a variable before the loop, otherwise you will run into problems when you get several elements with the same id were your selector to be based on an id (e.g. $("#col1")).

If your selector is using a class, it doesn't cause the same conflicts as duplicate id's, but you should still put the element in a variable before the loop, otherwise you will end up with a lot more elements than you want.

Upvotes: 27

arun
arun

Reputation: 3677

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script>
<script type="text/javascript">
 $(document).ready(function() {
    $('.col').each(function(){
        $(this).clone().insertAfter(this);
    }); 
  });  
</script>
 <div class="col">First div </div>
 <div class="col">2nd </div>
 <div class="col">3rd </div>
 <div class="col">4th </div>
 <div class="col">5th </div>

is this you looking for?

Upvotes: 1

Related Questions