I have multiple buttons that when clicked, should copy the text from a specific div. However, because the divs have IDs that are repeated on the page several times (due to being in a loop), I am unable to make sure the text that is copied is from the closest div with that ID.
I am using Clipboard.js, but it is not a requirement if I can get the same functionality with a normal function.
My HTML code looks like this so far... but remember, it's in a dynamically-generated loop. so "shortcodesTable" and each "shortcode1" div will be repeated.
<div id="shortcodesTable">
<h4>Short Codes</h4>
<div>
<h5>Shortcode 1</h5>
<button class="copy-btn" data-clipboard-target="#shortcode1">Copy</button>
<div id="shortcode1"><pre><code> ... ... ... </code></pre></div>
</div>
<div>
<h5>Shortcode 2</h5>
<button class="copy-btn" data-clipboard-target="#shortcode2">Copy</button>
<div id="shortcode2"><pre><code> ... ... ... </code></pre></div>
</div>
and my JS is the basic function from the clipboard.js documentation:
var clipboard = new Clipboard('.copy-btn');
clipboard.on('success', function(e) {
console.info('Copied Text:', e.text);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
For more clarification, my code is looping through an api of credit cards and populating content for each one. This table that needs the copy functionality is within that loop. It looks like this
for (var i = 0; i < arrayLength; i++) {
var 1 = blah;
var 2 = blah2;
$('<div>'+
'<div>'+
var 1 +
'</div>' +
'<div>'+
var 2 +
'</div>' +
'<div id="shortcodesTable">'+
'<h4>Short Codes</h4>'+
'<div>'+
'<h5>Shortcode 1</h5>'+
'<button class="copy-btn" data-clipboard-target="#shortcode1">Copy</button>'+
'<div id="shortcode1"><pre><code> ... ... ... </code></pre></div>'+
'</div>'+
'<div>'+
'<h5>Shortcode 2</h5>'+
'<button class="copy-btn" data-clipboard-target="#shortcode2">Copy</button>'+
'<div id="shortcode2"><pre><code> ... ... ... </code></pre></div>'+
'</div>'+
'</div>'+
'</div>').appendTo('.some-div');
}
You could use a counter variable or simply the index of your loop to give your elements unique ids.
As the W3 states:
The value must be unique amongst all the IDs in the element's home subtree and must contain at least one character. The value must not contain any space characters. https://www.w3.org/TR/html5/dom.html#the-id-attribute
Working example using template strings
function createShortcodeTables(iterations, root) {
let html = ''
for (let i = 0; i < iterations; i++) {
html += `
<div id="shortcodesTable-${i}">
<h4>Short Codes</h4>
<div>
<h5>Shortcode 1</h5>
<button class="copy-btn" data-clipboard-target="#shortcode-${i}">Copy</button>
<div id="shortcode-${i}"><pre><code> Text of shortcode #${i} </code></pre></div>
</div>
<div>
<h5>Shortcode 2</h5>
<button class="copy-btn" data-clipboard-target="#shortcode-${i}-${i}">Copy</button>
<div id="shortcode-${i}-${i}"><pre><code> Text of shortcode #${i}-${i} </code></pre></div>
</div>
</div>
`
}
root.innerHTML = html
}
const rootElement = document.querySelector('.root')
createShortcodeTables(10, rootElement)
const clipboard = new Clipboard('.copy-btn');
clipboard.on('success', function(e) {
console.info('Copied Text:', e.text);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
Edit:
... +
'<button class="copy-btn" data-clipboard-target="#shortcode1">Copy</button>' +
'<div id="shortcode1"><pre><code> ... ... ... </code></pre></div>' + ...
in your data-clipboard-target and the corresponding id attributes you have to add your index variable i. To do that you have to close your string and concatenate your index variable to it, otherwise it would print you the literal character i.
... +
'<button class="copy-btn" data-clipboard-target="#shortcode-' + i + '">Copy</button>' +
'<div id="shortcode-' + i + '"><pre><code> ... ... ... </code></pre></div>' + ...
Note the single quotes I've added inside your HTML attributes to close the string literal.
More conceptual example:
var arr = [1, 2, 3, 4, 5];
for (var index = 0; index < arr.length; index++) {
console.log('<div id="some-id-' + index + '"></div>');
}
Working JSFiddle with string concatenation.