Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Dynamic Layout Cloning

I want to switch between 2 HTML page layouts (layout1 and layout2), whereat layout2 is derived (cloned) from layout1 since they are almost identical. I have simplified my project to this small example which shows my problem: layout1 does not appear again on the 2nd button click. Can someone please give me a hint why this does happen? Thank you very much in advance:

let active_layout = 1;

document.addEventListener('DOMContentLoaded', function () {
    const button = document.getElementById('button');
    const layout1 = document.getElementById('layout1');
    const layout2 = document.getElementById('layout2');

    layout2.classList.add('hidden');

    button.addEventListener('click', function () {
        if (active_layout === 1) {
            let elm_cloned = layout1.cloneNode(true);
            elm_cloned.querySelector('h1').textContent = 'Layout 2';
            elm_cloned.querySelector('p').textContent = 'This is layout 2.';

            layout2.innerHTML = '';
            layout2.appendChild(elm_cloned);

            layout1.classList.add('hidden');
            layout2.classList.remove('hidden');
  } else {
    layout1.classList.remove('hidden');
    layout2.classList.add('hidden');
  }

        active_layout = (active_layout === 1) ? 2 : 1;
    });
});
.layout1,
.layout2 {
    background-color: #f0f0f0;
    padding: 20px;
    margin: 10px;
}
.layout1.hidden,
.layout2.hidden {
    display: none;
}
<div class="layout1" id="layout1">
    <h1>Layout 1</h1>
    <button id="button">Switch Layout</button>
    <p>This is layout 1.</p>
</div>
<!-- Layout 2 -->
<div class="layout2" id="layout2">
    <!-- Content of Layout 2 will be cloned from Layout 1 during runtime -->
</div>

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The problem is that event listeners are not cloned/transferred together with the DOM.

So, if you move button outside of the layout1, it works just fine:

let active_layout = 1;

document.addEventListener('DOMContentLoaded', function () {
    const button = document.getElementById('button');
    const layout1 = document.getElementById('layout1');
    const layout2 = document.getElementById('layout2');

    layout2.classList.add('hidden');

    button.addEventListener('click', function () {
        if (active_layout === 1) {
            let elm_cloned = layout1.cloneNode(true);
            elm_cloned.querySelector('h1').textContent = 'Layout 2';
            elm_cloned.querySelector('p').textContent = 'This is layout 2.';

            layout2.innerHTML = '';
            layout2.appendChild(elm_cloned);

            layout1.classList.add('hidden');
            layout2.classList.remove('hidden');
  } else {
    layout1.classList.remove('hidden');
    layout2.classList.add('hidden');
  }

        active_layout = (active_layout === 1) ? 2 : 1;
    });
});
.layout1,
.layout2 {
    background-color: #f0f0f0;
    padding: 20px;
    margin: 10px;
}
.layout1.hidden,
.layout2.hidden {
    display: none;
}
<button id="button">Switch Layout</button>
<div class="layout1" id="layout1">
    <h1>Layout 1</h1>
    <p>This is layout 1.</p>
</div>
<!-- Layout 2 -->
<div class="layout2" id="layout2">
    <!-- Content of Layout 2 will be cloned from Layout 1 during runtime -->
</div>

Also, you should move adding/removing DOM elements to outside of event listener, and just manipulate style within the listener:

let active_layout = 1;

document.addEventListener('DOMContentLoaded', function () {
    const button = document.getElementById('button');
    const layout1 = document.getElementById('layout1');
    const layout2 = document.getElementById('layout2');

    layout2.classList.add('hidden');

    let elm_cloned = layout1.cloneNode(true);
    elm_cloned.querySelector('h1').textContent = 'Layout 2';
    elm_cloned.querySelector('p').textContent = 'This is layout 2.';

    layout2.innerHTML = '';
    layout2.appendChild(elm_cloned);

    button.addEventListener('click', function () {
      if (active_layout === 1) {
        layout1.classList.add('hidden');
        layout2.classList.remove('hidden');
      } else {
        layout1.classList.remove('hidden');
        layout2.classList.add('hidden');
      }

        active_layout = (active_layout === 1) ? 2 : 1;
    });
});
.layout1,
.layout2 {
    background-color: #f0f0f0;
    padding: 20px;
    margin: 10px;
}
.layout1.hidden,
.layout2.hidden {
    display: none;
}
<button id="button">Switch Layout</button>
<div class="layout1" id="layout1">
    <h1>Layout 1</h1>
    <p>This is layout 1.</p>
</div>
<!-- Layout 2 -->
<div class="layout2" id="layout2">
    <!-- Content of Layout 2 will be cloned from Layout 1 during runtime -->
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading