I am trying to copy a value into clipboard:
/**
* If not direct clipboard manipulation supported from browser, use a alternate approach
* It is used upon copyTextToClipboard function.
*
* Function was seen in: https://stackoverflow.com/a/30810322/4706711
*
* @param {String} text
*/
function fallbackCopyTextToClipboard(text, callback) {
var textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
if (successful) {
callback(null, text);
} else {
callback("Usucessfull copying of the value", text);
}
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
callback(err, text);
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
/**
* Copy text into clipboard.
*
* Function from: https://stackoverflow.com/a/30810322/4706711
*
* @param {String} text
*/
function copyTextToClipboard(text, callback) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
callback(null, text);
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
callback(err, text);
console.error('Async: Could not copy text: ', err);
});
}
$(document).ready(() => {
$(".btn-copy").on("click", (e) => {
const element = e.target;
const text = $(element).data('val');
copyTextToClipboard(text, (err, text) => {
alert(`Copied value ${text}`)
//Display a popover here
});
});
})
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<button class="btn btn-primary btn-copy" data-val="Copy">
Copy Value
</button>
But In my case Instead of alert I want to display a bootstrap5.3 Popover once copied. How I can do that? I want the popover to be displayed dynamically with a dynamic content. Is there a way to do this?
The bootstrap version is 5.3.
In order to acheive that you need to render the popover as follows:
/**
* If not direct clipboard manipulation supported from browser, use a alternate approach
* It is used upon copyTextToClipboard function.
*
* Function was seen in: https://stackoverflow.com/a/30810322/4706711
*
* @param {String} text
*/
function fallbackCopyTextToClipboard(text, callback) {
var textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
if (successful) {
callback(null, text);
} else {
callback("Usucessfull copying of the value", text);
}
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
callback(err, text);
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
/**
* Copy text into clipboard.
*
* Function from: https://stackoverflow.com/a/30810322/4706711
*
* @param {String} text
*/
function copyTextToClipboard(text, callback) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
callback(null, text);
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
callback(err, text);
console.error('Async: Could not copy text: ', err);
});
}
$(document).ready(() => {
$(".btn-copy").on("click", (e) => {
const element = e.target;
const text = $(element).data('val');
copyTextToClipboard(text, (err, text) => {
const popover = new bootstrap.Popover(element, {
content: `Copied value ${text}`,
delay: {
"hide": 500
},
'placement': "bottom"
});
popover.show();
setTimeout(() => {
popover.hide()
}, 1000);
});
});
})
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<button class="btn btn-primary btn-copy" data-val="Copy">
Copy Value
</button>
Pay attetnion into this section in code above:
const popover = new bootstrap.Popover(element, {
content: `Copied value ${text}`,
'placement': "bottom"
});
popover.show();
setTimeout(() => {
popover.hide()
}, 1000);
What I do is I place the popover's content into content
setting whereas I use setTimeout
and its callback to hide it.