1

I'm taking someone else's jquery code and trying to add the functionality into my own application in plain JS. I've encountered something that I can't figure out, it's clearly taking a DOM element, removing it, and cloning it to add back in. The jquery starts with this variable declaration:

const template = $('#template').remove().removeAttr('id').removeAttr('style');

and the element in the html looks like this...

<p id="template" style="display: none;">

when I console log the element in the jquery it gives me an object like this 'w.fn.init [p]', which I'm guessing is just the jquery p element. I'm not sure why the 'removeAttr' are chained on to the initial remove, obvs to turn the display on and off but not sure why this is important if you're removing the element. template.parentNode.removeChild(template) doesn't recreate it.

The template variable is then used in a function in the jquery like this.....

const clone = template.clone();
const input = clone.find('.p-input');

which, obviously, is cloning the element in order to use it. I tried:

let clone = document.getElementById('template').cloneNode();

but that seems to just clone the element without the contents, so when I try and find the '.p-input' I get null. How would I recreate this in plain js?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
bevc
  • 203
  • 3
  • 14

1 Answers1

3

I tried let clone = document.getElementById('template').cloneNode(); but that seems to just clone the element without the contents...

Right. To clone its contents, you pass true into cloneNode.

let template = document.getElementById('template');
template.remove(); // Or on older browsers: template.parentNode.removeChild(template);
template.removeAttribute("id");
template.removeAttribute("style");
// ...
const clone = template.cloneNode(true);
const input = clone.querySelector(".p-input");

But remember that the original code removes the element, which this doesn't. (It's not clear to me why it removes it and then clones it, but...)


You said in a comment that you didn't really understand why it was being removed and then the id and such removed from it. It's a fairly common pattern in pages driven by direct DOM manipulation. The markup for the page includes the #template element, then on DOM load code grabs the #template element from the page, removes it (so it's not in page anymore), and removes the id it used to find it on the page. (The style thing is slightly unusual, but my guess is that it starts out with style="display: none" so it doesn't show during page load.) Then, as necessary, it clones that element and uses the clone on the page.

Here's a simple example of it at work:

let template = document.getElementById('template');
let list = template.parentNode;
template.remove(); // Or on older browsers: template.parentNode.removeChild(template);
template.removeAttribute("id");
template.removeAttribute("style");

document.getElementById("btn-add").addEventListener("click", function() {
    const textField = document.getElementById("new-text");
    const valueField = document.getElementById("new-value");
    const text   = textField.value;
    const value  = valueField.value;
    if (text) {
        const clone = template.cloneNode(true);
        clone.querySelector(".text").textContent = text;
        clone.querySelector(".value").value = value;
        list.appendChild(clone);
        textField.value = "";
        valueField.value = "";
        textField.focus();
    }
});
<div>
    Add an entry:
    <div><label>Text: <input type="text" id="new-text"></label></div>
    <div><label>Value: <input type="text" id="new-value"></label></div>
    <div><input type="button" id="btn-add" value="Add"></div>
</div>
<hr>
<div>
    The list:
    <ul>
        <li id="template" style="display: none">
            <span class="text"></span>
            <input class="value" type="text">
        </li>
    </ul>
</div>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I'm not sure why it's removing it either and then removing attributes and then cloning it, that's one of the things that's throwing me. Thank you very much. – bevc Dec 23 '19 at 14:23
  • @bevc - It's a fairly common pattern for code that does direct DOM manipulation, I've added an explanation and example above. – T.J. Crowder Dec 23 '19 at 14:39