Hey am new web developer and am working on a quote website project.
I have created a Html page in which there are some quotes with a copy button below all quotes.
You can visit my CodePen to understand the question clearly https://codepen.io/Akash11166666/pen/JjRzqzp
(I have displayed copy buttons and quotes from Javascript so you cannot find the elements in HTML.)
As you can see my CodePen they work perfectly but we cannot know if the text is copied or not. So I need a <span>Copied</span>
to be visible when each copy button is clicked without inserting the <span>Copied</span>
to HTML directly, that is from javascript same as copy button was created. They should be so dynamic that for respective copy button thespan
element should be visible and invisible after some seconds.
I have tried numerous way to solve this problem but know of them work although am new to javascript and I don't know much about it.
My CodePen project for reference
const resultEl = document.querySelector('.allquotes');
const pageSize = document.querySelector('select[name="page-size"]');
const pageCurr = document.querySelector('input[name="page-curr"]')
const resultCount = document.querySelector('.result-count')
const pageNoCurr = document.querySelector('.page-no-curr');
const pageNoCount = document.querySelector('.page-no-count')
const btnFirst = document.querySelector('.page-btn-first');
const btnPrev = document.querySelector('.page-btn-prev');
const btnNext = document.querySelector('.page-btn-next');
const btnLast = document.querySelector('.page-btn-last');
let results = [];
const getResultCount = () => results.length;
const getPageSize = () => +pageSize.value;
const getCurrPage = () => +pageCurr.value;
const getPageCount = () => Math.ceil(getResultCount() / getPageSize());
const pageResponse = (records, pageSize, page) =>
(start => records.slice(start, Math.min(records.length, start + pageSize)))
(pageSize * (page - 1));
const main = async () => {
btnFirst.addEventListener('click', navFirst);
btnPrev.addEventListener('click', navPrev);
btnNext.addEventListener('click', navNext);
btnLast.addEventListener('click', navLast);
pageSize.addEventListener('change', changeCount);
results = await retrieveAllQuotes();
updatePager(results);
redraw();
};
const redraw = () => {
resultEl.innerHTML = '';
const paged = pageResponse(results, getPageSize(), getCurrPage());
const contents = document.createElement('div');
contents.innerHTML = paged.map(record => `<div class='latestatus'><p class='copytxt'>${record.quotes}</p><div> <button class="copystatus btn">Copy</button></div></div>`).join('');
resultEl.append(contents);
};
const navFirst = (e) => {
pageNoCurr.textContent = 1;
pageCurr.value = 1;
redraw();
}
const navPrev = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const prevPage = curr > 1 ? curr - 1 : curr;
pageCurr.value = prevPage;
pageNoCurr.textContent = prevPage;
redraw();
}
const navNext = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const nextPage = curr < pages ? curr + 1 : curr;
pageCurr.value = nextPage;
pageNoCurr.textContent = nextPage;
redraw();
}
const navLast = (e) => {
pageNoCurr.textContent = getPageCount();
pageCurr.value = getPageCount();
redraw();
}
const changeCount = () => {
updatePager();
redraw();
};
const updatePager = () => {
const count = getPageCount();
const curr = getCurrPage();
pageCurr.value = curr > count ? 1 : curr;
pageNoCurr.textContent = curr > count ? 1 : curr;
pageNoCount.textContent = count;
resultCount.textContent = getResultCount();
};
const retrieveAllQuotes = async function () {
// write your asynchronous fetching here
return [{
quotes: "1The cat is better than dog."
},
{
quotes: "2Google is a open source library."
},
{
quotes: "3Cats are better than ferrets."
},
{
quotes: "4Love books."
},
{
quotes: "5Life is short make it possible."
},
{
quotes: "6The cat is better than dog"
},
{
quotes: "7Google is a open source library."
},
{
quotes: "8Cats are better than ferrets."
},
{
quotes: "9Love books."
},
{
quotes: "10Life is short make it possible."
},
];
}
document.querySelector('.allquotes').addEventListener(
'click',
function (e) {
e.preventDefault();
if (e.target && e.target.matches('.copystatus')) {
const quote = e.target.parentNode.closest('.latestatus')
.childNodes[0].textContent;
const textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('Copy');
textArea.remove();
}
},
false
);
main();
.mainStatus {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
padding-bottom: 5px;
margin: 10px;
margin-top: 10px;
max-width: 95%;
width: 95%;
height: auto;
border-radius: 20px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
}
.statusHeading {
text-align: center;
background-color: #18b495;
color: #ffffff;
padding: 10px 10px 10px 10px;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
font-weight: 300;
font-size: 20px;
}
.latestatus {
display: grid;
height: auto;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
padding: 10px 20px 10px 20px;
border-radius: 30px;
margin: 10px 10px 10px 10px;
width: 445px;
min-height: 130px;
font-size: 15px;
}
.allStatus {
display: flex;
}
.latestatus p {
width: auto;
position: relative;
}
.copystatus {
font-weight: 500;
text-transform: uppercase;
width: 100px;
height: 40px;
}
.pagable {
display: flex;
flex-direction: column;
border: var(--pageable-border);
background: var(--pageable-background);
}
.pagable .pagable-results {
display: flex;
flex-direction: column;
flex: 1;
padding: 0.25em;
}
.pagable .pagable-status {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0.25em;
background: var(--pageable-status-background);
}
.pagable .pagable-actions {
display: grid;
grid-auto-flow: column;
grid-gap: 0.25em;
}
.pagable .pagable-actions input[name="page-curr"] {
width: 3em;
}
<!DOCTYPE html>
<html>
<head>
<style>
/* Main Status */
</style>
</head>
<body>
<a href="hindinj.html">caeman</a>
<div class="mainStatus">
<h2 class="statusHeading">Latest English Status</h2>
<div class="allquotes"></div>
<div class="pagable-status">
<label>Page <span class="page-no-curr">1</span> of <span class="page-no-count">1</span></label>
<div class="pagable-actions">
<button class="page-btn-first">≪</button>
<button class="page-btn-prev"><</button>
<input type="number" name="page-curr" min="1" value="1" />
<button class="page-btn-next">></button>
<button class="page-btn-last">≫</button>
<select name="page-size">
<option>20</option>
<option>10</option>
<option>20</option>
</select>
</div>
<label>(<span class="result-count"></span> items)</label>
</div>
<script>
</script>
</body>
</html>
Again I would tell my problem that, I need a <span>Copied</span>
to be visible when each copy button is clicked without inserting the <span>Copied</span>
to HTML directly, that is from javascript same as copy button was created.
I hartley thanks for those who answer this question.
You can do this by calling a function right after your call to
document.execCommand('Copy')
. Check my snippet below forshowCopied
and CSS classhasCopied
. This should temporarily show the span and using asetTimeout
it can be removed after some given time in milliseconds (2000 = 2 seconds).