Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
192
rated 0 times [  195] [ 3]  / answers: 1 / hits: 20906  / 10 Years ago, wed, january 14, 2015, 12:00:00

I have a template:




function useIt() {
var content = document.querySelector('template').content;
// Update something in the template DOM.
var span = content.querySelector('span');
span.textContent = parseInt(span.textContent) + 1;
document.querySelector('#container').appendChild(
document.importNode(content, true));
}

<button onclick=useIt()>Use me</button>
<div id=container></div>

<template>
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</template>




You can try the code here.
This code basically copies the template(html5 templates does not render on your screen) into another div. This allows you to reuse the DOM.


Problem: The line "span.textContent = parseInt(span.textContent) + 1;" changes the template code directly. I need to manipulate the content DOM and clone it into the container, without changing the template. This is very important since if I want to reuse the code, I need it to stay the same.


I have tried multiple ways to use jQuery to mimic the above javascript code, but I can't manage to figure it out. It would be better if there is a jQuery way.


More From » jquery

 Answers
12

If you NEED to use the new <template> tag, then you are mildly stuck . . . your cleanest alternative is to use importNode to bring in the content and then modify it after it's been appended.



Assuming that the templated code is realtively small, this should happen fast enough that you would never notice the difference in approach, though, in this specific example, the alert(), would delay the change of the content, so you would see 0, until you clicked Okay, and then it would update to 1.



The code change for that would be:



function useIt() {
var content = document.querySelector('template').content;

var targetContainer = document.querySelector('#container');
targetContainer.appendChild(document.importNode(content, true));

var $span = $(targetContainer).find(div:last-of-type).find(span);
$span.text(parseInt($span.text() + 1));
}


If you are not married to the idea of <templates>, you could use jQuery's clone() method to do what you want to do, very easily . . . but, clone does not see the content of a <template>, due to the special nature of that particular element, so you would have to store the templated code some other way (JS variable, hidden div, etc.).



HOWEVER, this method will not work if you need to clone a script, the way that a <template> will. It will not trigger any script code in the template container element when the cloned version is created or appended. Additionally, if you store it in a hidden <div>, any script code in the template container element will trigger immediately on page load.



A simple version of the code for the clone() approach would look something like this:



function useIt() {
var $content = $(#template).clone();
var $span = $content.find(span);
$span.text(parseInt($span.text()) + 1);

$content.children().each(function() {
$(#container).append($(this));
});
}


Assuming that your template was:



<div id=template style=display: none;>
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</div>


You could also move the <script>alert('Thanks!')</script> out of the template and into the script section (after you completed the append loop), to achive the desired alert functionality, if you wanted to.


[#68211] Monday, January 12, 2015, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
carolyn

Total Points: 618
Total Questions: 119
Total Answers: 86

Location: Saint Pierre and Miquelon
Member since Fri, Jan 28, 2022
2 Years ago
;