1

I'm trying to add a duplicate element with a different class name as javascript won't add a duplicate object.

Expectations - enter image description here

I added a button with an event listener on to grab the parent element html and change the class of it but it changes the class of old element as well. Goal is to get a duplicated element in form if someone got multiple phone no. with button you should get an another input option

Here's my code for, doesn't work as i told

                add_button.addEventListener('click', e=>{
                    const data = e.target.parentElement.parentElement
                    // Grabs the parent element on height 2
                    console.log(data) // Got the expected data
                    // ran_value = Math.floor((Math.random() * 100000) + 1); // Tried this function to generate a random value for class
                    var data_new = data // Created another instance of data
                    data_new.setAttribute('class', '1') //add class name
                    console.log(data_new) // changes the class name
                    // paramsDiv.appendChild(data)
                });

Here's my result which I am getting

enter image description here

While in expected result, it should have changed the class name or added it in 2nd div only so duplicate div element can be appended into form paramsDiv.

Expected result is -> enter image description here

Sid Kaushik
  • 567
  • 4
  • 14
  • Objects (in this case your DOM Element) are [passed by reference](https://stackoverflow.com/questions/29050004/modifying-a-copy-of-a-javascript-object-is-causing-the-original-object-to-change). You're not actually creating a copy. To copy an element you can use the [cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode) method. – Reyno Aug 16 '21 at 13:31
  • 1
    Does this answer your question? [Is it possible to clone html element objects in JavaScript?](https://stackoverflow.com/questions/921290/is-it-possible-to-clone-html-element-objects-in-javascript) – user202729 Aug 16 '21 at 13:32
  • Although in this case it may be easier to just create a new object from scratch – user202729 Aug 16 '21 at 13:32
  • That is in line `var new_data = data`, it should be something like `var new_data = data.cloneNode()` – LuisAFK Aug 16 '21 at 13:32

3 Answers3

2

The reason it happens is because when you assign data to new_data, you are not creating a new object. You are simply telling new_data to point at data. For that reason, when you change new_data, data changes aswell. In order to create a completely new element, try this:

var data_new = data.cloneNode(true);
Sagi Rika
  • 2,839
  • 1
  • 12
  • 32
2

Donot assign with var data_new = data instead clone the node with var data_new = data.cloneNode(true) Reference

Assigning the dom object to a new variable will not create a new independent copy. Instead both variables will point to same location.

If you want to insert the element as the first child, you can make use of Node.insertBefore() Reference

Working Fiddle

const add_button = document.getElementById('add-button');
add_button.addEventListener('click', e => {
  const data = e.target.parentElement.parentElement
  // Grabs the parent element on height 2
  console.log(data) // Got the expected data
  // ran_value = Math.floor((Math.random() * 100000) + 1); // Tried this function to generate a random value for class
  var data_new = data.cloneNode(true); // Created another clone instance of data
  data_new.setAttribute('class', '1') //add class name
  console.log(data_new) // changes the class name
  // paramsDiv.appendChild(data)
});
<div>
  Content
  <button id="add-button">Add</button>
</div>
Nitheesh
  • 19,238
  • 3
  • 22
  • 49
  • It works thanks will accept answer in 6 min. time limit... Is it possible to add this cloned element in mapped objects right after the parent element rather than in bottom of parent div. Right now it adds this new element in bottom of the div.. :( – Sid Kaushik Aug 16 '21 at 13:38
  • @SidKaushik You want this element as the first node of the div? Current implementation will add this as the last element. – Nitheesh Aug 16 '21 at 13:40
  • yup either first node or second node right after the button node. – Sid Kaushik Aug 16 '21 at 13:40
  • @SidKaushik This is possible. Can you create a fiddle with the present status? Just to ensure that we are at the same point. I will check and will update. – Nitheesh Aug 16 '21 at 13:43
  • @SidKaushik If you want to insert the element as the first child, you can make use of `Node.insertBefore()` Fiddle https://jsfiddle.net/ne28xjkw/ – Nitheesh Aug 16 '21 at 13:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236051/discussion-between-sid-kaushik-and-nitheesh). – Sid Kaushik Aug 16 '21 at 14:00
  • @SidKaushik As i mentioned its possible with `Node.insertBefore()` Working Fiddle https://jsfiddle.net/L80wgbce/ If this solved this issue, please considering approving the answer. Happy to have an upvote aswell. – Nitheesh Aug 16 '21 at 14:08
2

I don't know exactly your code but you could try to use nodeClone(), see the documentation: https://developer.mozilla.org/fr/docs/Web/API/Node/cloneNode because the problem you have here is probably the "referencing".

Tell me how it goes.

Angele
  • 31
  • 3