Clone DIV and its contents with new ids [duplicate] - javascript

This question already has answers here:
Clone <div> and change id
(4 answers)
Closed 9 years ago.
I'm trying to clone a div and the input elements inside it. When I clone it, I would like all the ids to increment by one. I've made a fiddle to show you what I'm doing.
$("#add").click(function (e) {
var amount = $('div.classes').length;
var new_amount = amount + 1;
var cloned_div = $('#class-' + amount);
$(cloned_div).clone().attr('id', 'class-' + new_amount).insertAfter('#class-' + amount);
});
jsFiddle
So far I've cloned the whole div itself and the ids increment but the elements inside remain the same. How would I get all elements inside the div to increment by one?

You have cloned the entire div without modifying it's contents. Try something like:
$("#add").click(function (e) {
var amount = $('div.classes').length;
var new_amount = amount + 1;
var cloned_div = $('#class-' + amount);
$(cloned_div).clone().attr('id', 'class-' + new_amount).insertAfter('#class-' + amount).find('input').each(function (i, e) {
$(e).attr('id', $(e).attr('id').replace(amount, new_amount));
});
});
DEMO

You can recursively replace all id's using find / replace:
$("#add").click(function (e) {
var amount = $('div.classes').length;
var new_amount = amount + 1;
var cloned_div = $('#class-' + amount).clone();
cloned_div.insertAfter('#class-' + amount);
cloned_div.find('[id$="-' + amount + '"]').andSelf().each(function(index, child) {
child.id = child.id.replace("-" + amount, "-" + new_amount);
});
});
See jsFiddle
cloned_div.find('[id$="-' + amount + '"]') will search for all child elements having an id attribute ending on "-" + amount, .andSelf() will include the cloned div as you want to change the id there also. Then simply replace the number part in the id of each child (and self).

Try adding this:
$('#class-' + new_amount + ' input:nth-child(1)').attr('id', 'name-class-' + new_amount);
$('#class-' + new_amount + ' input:nth-child(2)').attr('id', 'number-class-' + new_amount);
$('#class-' + new_amount + ' input:nth-child(3)').attr('id', 'book-class-' + new_amount);
just below your $(cloned_div).clone() statement.
See it in action:
http://jsfiddle.net/ZHHcA/1/

These other answers are close, but the problem with their solutions is the original ID prefixes are being lost: number-class-1 is becoming class-1 which is not ideal.
Here is a better option:
$("#add").click(function (e) {
var amount = $('div.classes').length;
var new_amount = amount + 1;
var cloned_div = $('#class-' + amount);
var $cloned = $(cloned_div).clone().attr('id', 'class-' + new_amount).insertAfter('#class-' + amount);
$cloned.children().each(function(){
var $child = $(this);
var oldID = $child.attr('id');
var newID = oldID.replace(/[0-9]+$/, new_amount); // replace just the number, leave the rest of the ID name in tact
$child.attr('id', newID);
})
});
And a working example

Related

Find the last element that has appeared DOM html

I have a code that puts images on a table(html), and I want to focus on the image that has just appeared.
I know that i have to use $(this) but i don't know how, here is my code
function positioning(year, mon) {
$('#' + year + ' .' + mon).prepend('<img class="black_point" src="./images/circle.png"/>');//that adds the image
var table = document.getElementById("table");
var images = table.getElementsByTagName("img");
//here I need the current image I had just add to send to that function
function connect(images) {
var tabBcr = table.getBoundingClientRect();
var imgBcr = image.getBoundingClientRect();
x = imgBcr.left + (imgBcr.width / 2) - tabBcr.left;
y = imgBcr.top + (imgBcr.height / 2) - tabBcr.top;
}
}
I hope I have explained well .
I think it will work, add this where you want to get that img element:
var imgelem=$('#' + year + ' .' + mon).find("img:first");

Remove "comma" separator after last element

I have the below code.
$(document).ready(function(){
$('input[type="checkbox"]').click(function(){
elem = $(this);
part = $(this).attr("data-part-name");
//alert(part);
selected_options = "";
$('.' + part).each(function () {
if ($(this).is(":checked")) {
selected_options += $(this).attr("data-option-name") + ' <b>,</b> '
}
});
$("#part_child_" + elem.attr("data-part-id")).html(selected_options);
});
});
If you see I am adding a "comma" to selected options.
Now problem is it adds comma even after the last element.
How can I remove the last comma
.map() will a perfect fit for this. Also you can filter the checked items using :checked and filter
$(document).ready(function () {
$('input[type="checkbox"]').click(function () {
var elem = $(this);
var part = $(this).attr("data-part-name");
//alert(part);
var selected_options = $('.' + part).filter(':checked').map(function () {
return '<b>' + $(this).attr("data-option-name") + '</b>'
}).get();
$("#part_child_" + elem.attr("data-part-id")).html(selected_options.join(', '));
});
});
You can use the index of iteration to compare with length of parts element and do the decision whether a comma needs to be added or not.Modify the code to:
var totalparts=$('.' + part).length;
$('.' + part).each(function (i) {
if ($(this).is(":checked")) {
selected_options += $(this).attr("data-option-name") + totalparts!=(i+1) ?' <b>,</b> ':'';
}});
Just remove last , substring from the string,
if(selected_options.length > 0){
selected_options = selected_options.slice(0,-1)
}
$("#part_child_" + elem.attr("data-part-id")).html(selected_options);
replace this line
$("#part_child_" + elem.attr("data-part-id")).html(selected_options.replace(/[\<\>\,b\/\s]+$/,''));

Append increasing number on click

I'm trying to append an increasing number to elements on click. I can't seem to make it work.
My code:
$('#on').click(function() {
$("b").click(function(e) {
var numCount = ($("[span class='num'>").length + 1);
var element = $("<span class='num'>" + numCount + "'>" + numCount + "</span>");
$(this).append(element);
});
});
I think It's a simple syntax error in my code, but I'm learning here so I could be completely wrong. It's important for the class to be added too.
Here's a Fiddle
Change
var numCount = ($("[span class='num'>").length + 1);
to
var numCount = ($(".num").length + 1);
You need to find .num elements, not create new ones.
In addition, your element line doesn't create valid HTML either. Try the following:
var element = $("<span class='num'>" + numCount + "</span>");

Jquery .each() giving me values of all elements with the same class

Please go to: www.designedbychristian.com/template_2
(so far being tested in chrome)
When you click design a bunch of thumbnails appear.
I am trying to use the .each selector to get the src of the image. I want to take that value and apply it to a div that will appear when clicked. (I know how to program that part)
My problem is when I click the thumb nail my alert is giving me the value of all of the thumbnails.
my code is this:
function spawnImages() {
N = 1
for (i = 1; i <= 9; i++) {
var gal = document.getElementById('gallary')
var newDIV = '<img onclick="imageView()" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
$('.gallary').prepend(newDIV)
var min = 3;
var max = 70;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' +N)).css("left", s + "%")
var min = 3;
var max = $(this).height();
var max = 70;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' + N)).css("top", s + "%")
var min = -45;
var max = 45;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' + N)).css("-webkit-transform", "rotate(" + s + "deg)")
var test = $(('.imageNumber' + N)).css("transform", "rotate(" + s + "deg)")
var test = $(('.imageNumber' + N)).css("-ms-transform", "rotate(" + s + "deg)")
N++
}
}
function imageView() {
$(".thumb-nail").each(function () {
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
})
};
Just use jquery event handlers, get rid of the onclick call in your html and just add this in your javascript.
$(".thumb-nail").on('click', function(){
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
});
EDIT: didn't think about the images being created dynamically, Popnoodles answer is the right one
pass clicked element reference like this:
var newDIV = '<img onclick="imageView(this)" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
Function:
function imageView(element) {
var imageSrc = $(element).attr('src');
alert($(element).attr('src'));
}
This is exactly how the jQuery API describes the .each() method:
Iterate over a jQuery object, executing a function for each matched element.
When you called $('.thumb-nail') it returned ALL of the elements with the class thumb-nail in a jQuery object. Then when you called .each( function() {} ) on that object, the loop iterated over all of the returned elements.
The easiest way to handle click events in jQuery, is to use the .on() method, as others have pointed out in their answers.
Also, as #Popnoodles mentioned, since these elements are created dynamically, you may need to run your $().on() call explicitly after these elements are created. For that reason, you might wrap it into your spawnImages() function, rather than putting it inside $() as #Popnoodles indicates (i.e. not $( $(element).on('click',function(){}), as $( ) is equivalent to $(document).ready.
The simplest change is this
// send this element to the function
var newDIV = '<img onclick="imageView(this)" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
function imageView(el) {
var imageSrc = $(el).attr('src');
alert($(el).attr('src'));
};
But it's nice to do things in a more standard fashion...
First get rid of this onclick="imageView()"
var newDIV = '<img src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
Since these elements are created dynamically you will need to bind the click event to document or another ancestor that exists, and delegate to each ".thumb-nail".
You also need to run this procedure only when dom is ready ($(function(){...});).
$(function(){
$(document).on('click', ".thumb-nail", function () {
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
});
});

Is it possible to use cloneNode to clone multiple divs?

I'm trying to clone to divs in and append them to to other divs (their parents). I'm using clonenode for this but it doesn't seem to work. It clones the div in the first function and appends it to the parent of the div in the second function! Not sure what I'm doing wrong.
Here's the code (*EDIT:*var added):
function cloneQ() {
//Cloning questions and shit
cloneQ.id = (cloneQ.id || 0) + 1;
var question = document.getElementById("question");
var clone = question.cloneNode(true);
var numberOfQuestions = $('.question').length;
var id = "questioncon" + cloneQ.id;
clone.id = id;
question.parentNode.appendChild(clone);
var inid = "question" + cloneQ.id;
var optionid = "optionsdiv" + cloneQ.id;
$('#' + id + ' ' + '.' + 'questionin').attr('id', inid);
$('#' + id + ' ' + '.' + 'options').attr('id', optionid);
$('#' + id + ' h2').html('Question ' + cloneQ.id);
//Question Cloned
}
function cloneforPrint() {
cloneforPrint.id = (cloneforPrint.id || 0) + 1;
var questionprint = document.getElementById("questionprint");
var cloneprint = questionprint.cloneNode(true);
var printid = "questionprint" + cloneforPrint.id;
cloneprint.id = printid;
questionprint.parentNode.appendChild(clone);
var printinid = "thequestionprint" + cloneforPrint.id;
$('#' + printid + ' ' + '.' + 'thequestionprint').attr('id', printinid);
}
LIVE here: http://bit.ly/R8hB2m
Edit : Global vars are the problem.
You aren't putting var in front of your variables, making them global. The cloneForPrint function is picking up vars defined in cloneQ.
Init all the variables properly and you'll get some errors indicating where the problems are.
CloneQ is indeed appending to questions parent, but cloneForPrint then moves it somewhere else.
-- Old answer --
There's not enough here to work out what the problem is. My 1st guess is that the question element has the same parent as the questionprint element.
Based on the code given, cloneQ should definitely append to questions parent. So to give the appearance you've specified the DOM probably doesn't look like what you expect.

Categories

Resources