Jquery cloned element is replacing himself - javascript

I have been getting some issue with cloning element, when I am cloning an element and add it to the DOM it work perfectly but when I am trying to clone a second one its replacing the first added clone, do you know where it could come from ?
var clone_count = 1;
var add_row = $('.modeloRowBlock-hidden').clone(true) // clone my div that is hidden
$('.add-modelo-block').on('click', function() { // binded button to add my div
var current_row = add_row.removeClass('modeloRowBlock-hidden hidden').addClass('modeloRowBlock' + ' ' + clone_count++) ;
$('.modeloRowBlock-hidden').before(current_row);
});
Thanks a lot in advance for your help :).
Jonathan.
EDIT : My bad I made it work, actually cloned that way for another reason, and re integrated it in the .on and it worked.

You clone your row only once.
If you're using before on a single element, it will move the elements.
If an element selected this way is inserted into a single location
elsewhere in the DOM, it will be moved before the target (not cloned):
Read more: http://api.jquery.com/before/

Related

.appendChild() an HTML element on click

I wanted to copy an entire row including its' siblings and contents on button click. When I click the button the element, it appears in the console but doesn't append to the page. This is my code:
It doesn't show any error messages. I've tried innerHTML/outerHTML or append() it doesn't work.
$(document).ready(function() {
$('#addSubFBtn').on('click', function() {
var itm = document.getElementById("trFb");
var wrapper = document.createElement('div');
var el = wrapper.appendChild(itm);
document.getElementById("tbFb").append(el);
console.log(el);
});
});
Seems like what you're trying to do is clone the item after you get it from your document. W3schools website explains how to accomplish this. Check out the link: https://www.w3schools.com/jsref/met_node_clonenode.asp
Once you clone the node, [appendchild] should work as intended
Not sure (as said without seeing related HTML) but i see flaw in your logic:
var itm = document.getElementById("trFb");
still exist on the document(so in the page) so you've to retrieve it before you want to add/move it to another place.
using .removeElement will return you removed element(or null if no element matche the selector) so correct script should be:
var itm=document.getElementById("trFb").parentNode.removeChild(document.getElementById("trFb"));
as shown here to remove element you've to use method on to parent element.
So you can add it to any other element existing.
For more specific use or element created in global JS variable (such an createElement not yet appended) you can see :document.createDocumentFragment(); as explained here https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment

Assign java scripts to cloned HTML element

I have a html div and I clone it using Jquery. That div contains labels and text fields. ids of all of them generated and assigned dynamically. I have no problem with that.
A java script is assigned to a text field of original div. The cloned text fields does not have the javascript assigned to it.
the script I need to assign:
<script>
$(function() {
$("#datepick_onBooking,#datepick_Pay1,#datepick_Pay2,#datepick_totPay,#datepick_deedFees").datepicker();
});
</script>
the script I use to make clones:
<script>
var i = 3;
//When DOM loaded we attach click event to button
$(document).ready(function() {
$('#addAnotherPayment').click(function() {
var cloned = $('.PayDiv0').first().clone();
var noOfDivs = $('.PayDiv0').length+2;
cloned.insertBefore("#totPayForm");
// append count to the ids
cloned.attr('id', 'PayDiv' + noOfDivs);
cloned.find('label').attr('id', 'PayLbl' + noOfDivs);
cloned.find('input[type="text"]').attr('id', 'datepick_Pay'+ noOfDivs);
cloned.find('input[type="number"]').attr('id', 'amount_Pay'+ noOfDivs);
cloned.find('.PayLbl2').html("Payment No " + i++ + ':');
});
});
</script>
datepick_Pay1, datepick_Pay2, datepick_totPay, datepick_deedFees are static elements and they have been assigned to the script. I create text fields using cloning as datepick_Pay3,datepick_Pay4, and so on.
I cannot figure out how to dynamically assign the script to that newly created elements.How can I do that?
A Boolean indicating whether event handlers and data should be copied along with the elements.
change this line.
var cloned = $('.PayDiv0').first().clone(true);
when you clone something especially elements which having events
use parameter as
clone(true)
But this will be harmfull based on how event is attached on the actual element when copying the events to the cloned element may affect the actual.
You need to clone with events. http://api.jquery.com/clone/
var cloned = $('.PayDiv0').first().clone(true);
Then your script needs to be changed to work for dynamic elements. Here as soon as input elements gets focus, asssign the datepicker based on wild card id selector, if it doesn't already have one.
$(function() {
$('body').on('focus',"input[id^=datepick_]", function(){
if(!$(this).hasClass('.hasdatepicker'))
{
$(this).datepicker();
}
});
});

Javascript Sections

I have a website I want to take that always has the same section with the same id with all the content I want to display. I'm not very amazing at javascript and I'm wondering how I could remove everything but a specific section.
Would the best approach be to just do a loop that goes through all the elements in the DOM and remove everything but the section with the id I want to keep? If I go that approach how do I keep it from removing all the elements inside that section?
Perhaps another way to do this more efficiently would be:
document.body.innerHTML = document.getElementById( 'saveContentId' ).innerHTML
Removing one node includes all its children, so you won't need to loop over all elements in the whole document. I see two possibilities:
get the section, remove all its siblings in the current parent, and then walk up the DOM tree until document.body, while removing all siblings.
get the section and detach it from the document. Then clear document.body and re-attach the section there
The first solution seems cleaner to me, so here some sample code:
function removeEverythingBut(el) {
while (el != document.body) {
var par = el.parentNode;
for (var i=par.childNodes.length-1; i>=0; i--)
if (par.childNodes[i] != el)
par.removeChild(par.childNodes[i]);
el = par;
}
}
// usage:
removeEverythingBut(document.getElementById("my-section"));
you can save only the element you want and delete all other elements. Also I recommend using Jquery

Getting the source of a click in jquery?

var currentImageBox;
$('.newImage').bind('click', function() {
currentImageBox = this;
currentImageBox.unbind('click');
});
Im trying to set currentImageBox to the div that was clicked (a number of divs on the page have the newImage class). But to no avail, where am I going wrong?
The code is correct, the this is the element clicked. But to use unbind, you need to wrap the element with jQuery since this (and therefore currentImageBox) is the DOM element and not a jQuery object.
$(currentImageBox).unbind('click');

JQuery Event Listeners in a For Loop

I am trying to create some basic button rollover functionality using Jquery and toggleClass. I am building a list of elements by cloning a DIV from my HTML and duplicating it multiple times (its populating a list of data from a database). To do this I am using a for loop. Here is the currently working code.
var displayNode = document.getElementById('phoneDisplayContainer');
for(var i=0; i<length; i++) {
//Clone the original container display.
var clonedDisplay = displayNode.cloneNode(true);
clonedDisplay.setAttribute('id', 'phoneDisplayContainer' + i);
//Remove hidden class from cloned Element. NOT CROSS BROWSER!
clonedDisplay.classList.remove('hidden');
var children = clonedDisplay.getElementsByTagName('div');
//Fill new nodes children containers with data.
children[1].innerHTML = contact.phone[i].type;
children[2].innerHTML = contact.phone[i].number;
children[3].setAttribute('onclick', 'PhoneUtility.edit(' + i + ');');
children[3].setAttribute('id', 'phoneEditDisplay' + i);
children[4].setAttribute('onclick', 'PhoneUtility.remove(' + i + ');');
//Hidden elements
var hidden = new Array(children[3], children[4]);
//Set rollover events.
clonedDisplay.setAttribute('onmouseover', '$("#' + children[3].id + '").toggleClass("hidden");');
clonedDisplay.setAttribute('onmouseout', '$("#' + children[3].id + '").toggleClass("hidden");');
//Append the new node to the display container
phoneContainer.appendChild(clonedDisplay);
}
}
Is there a way to use Jquery event listeners instead of having to set onmouseover and onmouseout directly on the element?
I tried this:
$(clonedDisplay).mouseover(function() {
$(children[3]).toggleClass('hidden');
});
With no luck. It just displays performs the rollover effect on the last element in the list. This is actually my first attempt at using jQuery so any other suggestions to ways I could jQuery inside the code would be helpful too.
EDIT: I'd also like to toggle multiple children from the arraylist mentioned in the for loop. How would I set this up? I can't seem to pass an array to the jquery command without getting errors.
The following code after your for loop should let you assign all the mouseover and mouseout handlers in one go to apply to all the clones:
$('div[id^="phoneDisplayContainer"]').mouseover(function() {
$(this).find("div").eq(3).toggleClass("hidden");
}).mouseout(function() {
$(this).find("div").eq(3).toggleClass("hidden");
});
// or, given that both handlers do the same thing:
$('div[id^="phoneDisplayContainer"]').on("mouseover mouseout", function() {
$(this).find("div").eq(3).toggleClass("hidden");
})
(If you're using jQuery older than 1.7 use .bind() instead of .on().)
The above says to find all the divs with an id beginning with "phoneDisplayContainer" and assign event handlers. Within the handler, find the fourth descendant div and toggle the class.
You don't show your HTML or CSS, but you could do this all in your CSS if you like. Assuming you can assign a common class ("parentDiv") to the divs that you want to trap the hover event on, and a common class ("childDiv") to their child div (the one to be hidden), you can do this:
.parentDiv .childDiv { visibility: hidden; }
.parentDiv:hover .childDiv { visibility: visible; }
(Obviously you can give more meaningful class names to fit your structure.)
Otherwise, again if you can assign those classes to the appropriate divs then after your loop you can do this with jQuery:
$(".parentDiv").on("mouseover mouseout", function() {
$(this).find(".childDiv").toggleClass('hidden');
});
Basically the same as what I said initially, but using classes for selectors. If you feel like I'm pushing a class-based solution on you that's because I am: it tends to make this sort of thing much easier.

Categories