How to creat copy alerts to many buttons? - javascript

Hey am new to java script But putting my all efforts I have written a javascript to copy a text inside <p></p> But needed a alert text to be visible when the "copy" button is clicked. And mainly I have many buttons.My javascript
function copyToClipboard(var1){
let val = document.getElementById(var1).innerHTML;
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = val;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
}
My html
<div class="englishstatus">
<div class="car">
<div class="latestatus">
<p id="p9">life os good when hou have books</p>
<button class="copystatus btn" onclick="copyToClipboard('p9')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p10">Google is a open source library. It is a open source by lary page and sergy brime</p>
<button class="copystatus btn" onclick="copyToClipboard('p10')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
<div class="car">
<div class="latestatus">
<p id="p11">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p11')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p12">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p12')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
</div>
</div>
The Copied alert in my html code is <span class="copystatusalert">Copied!</span>.I needed this element to be visible for some seconds when I click the respective copy button and be vanished after few seconds. Please help me and thanks in advance.
function copyToClipboard(var1){
let val = document.getElementById(var1).innerHTML;
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = val;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
}
<div class="englishstatus">
<div class="car">
<div class="latestatus">
<p id="p9">life os good when hou have books</p>
<button class="copystatus btn" onclick="copyToClipboard('p9')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p10">Google is a open source library. It is a open source by lary page and sergy brime</p>
<button class="copystatus btn" onclick="copyToClipboard('p10')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
<div class="car">
<div class="latestatus">
<p id="p11">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p11')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
<div class="latestatus">
<p id="p12">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p12')">Copy</button>
<span class="copystatusalert">Copied!</span>
</div>
</div>
</div>
</div>

In the snippet below we:
pass the button where the click occurred
find the span near it
hide it
schedule its showing in a few seconds
design the .invisible class
function copyToClipboard(var1, btn){
let val = document.getElementById(var1).innerHTML;
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = val;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
let item = btn.parentNode.querySelector(".invisible");
if (item) {
item.classList.remove("invisible");
setTimeout(function() {
item.classList.add("invisible");
}, 4000);
}
}
.invisible {
display: none;
}
<div class="englishstatus">
<div class="car">
<div class="latestatus">
<p id="p9">life os good when hou have books</p>
<button class="copystatus btn" onclick="copyToClipboard('p9', this)">Copy</button>
<span class="copystatusalert invisible">Copied!</span>
</div>
<div class="latestatus">
<p id="p10">Google is a open source library. It is a open source by lary page and sergy brime</p>
<button class="copystatus btn" onclick="copyToClipboard('p10', this)">Copy</button>
<span class="copystatusalert invisible">Copied!</span>
</div>
</div>
<div class="car">
<div class="latestatus">
<p id="p11">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p11', this)">Copy</button>
<span class="copystatusalert invisible">Copied!</span>
</div>
<div class="latestatus">
<p id="p12">Cat is better than dog</p>
<button class="copystatus btn" onclick="copyToClipboard('p12', this)">Copy</button>
<span class="copystatusalert invisible">Copied!</span>
</div>
</div>
</div>
</div>

If you refactor your code slightly you can make this all work without needing to use IDs in the calls to the main function and can use an externally registered event handler which, to my mind, is a much cleaner way to approaching this.
document.addEventListener('DOMContentLoaded',()=>{
const createtextbox=function(text){
let el=document.createElement('textarea');
el.style.position = 'fixed';
el.style.left = '0';
el.style.top = '0';
el.style.opacity = '0';
el.value = text;
document.body.appendChild(el);
return el;
};
const shortmessage=function(e,m,t){
let span=e.parentNode.querySelector( 'span' );
span.innerText=m;
setTimeout(()=>{span.innerText=''},1000 * t)
};
const copytoclipboard=function(e){
// create the hidden textarea and add the text from the sibling element
let n=createtextbox( this.parentNode.querySelector('p').innerHTML );
n.focus();
n.select();
document.execCommand('copy');
document.body.removeChild(n);
// flash a message in the SPAN-clear after 2s
shortmessage( this, 'Copied!', 2 );
};
/*
Find a reference to ALL buttons that are used to copy
text from a sibling element and assign an event handler
to process every button click.
*/
document.querySelectorAll('button.copystatus').forEach( bttn=>{
bttn.addEventListener( 'click', copytoclipboard )
});
})
<!--
In many instances there is no need to assign IDs to DOM elements in
order to target them programmatically. There are many methods native
to Javascript to navigate through the DOM - parent/child/sibling
selectors and when used in conjunction with an `Event` you can easily
locate items of interest.
-->
<div class='englishstatus'>
<div class='car'>
<div class='latestatus'>
<p>Life is good when you have books</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
<div class='latestatus'>
<p>Google is a open source library by Larry Page and Sergey Brin!</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
</div>
<div class='car'>
<div class='latestatus'>
<p>Cats are better than dogs.</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
<div class='latestatus'>
<p>Ferrets are better than rats</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
</div>
</div>

Related

How to insert html element inside the index.html from javascript

I want to insert the card into container using javascript. How do I do it. or make those card display in flex. So it's not like shown in below pic. I have used insertAdjancentHTML to insert the data in note class using javascript. However i'm unable to put them in container.
const addBtn = document.getElementById("add");
const addNewNote = (text = "") => {
const note = document.createElement("div");
note.classList.add("note");
const htmlData = `<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-primary">
<i class="bi bi-trash"></i>
</button>
</span>
</div>
<hr />
<p class="card-text">
Some quick example text to build on the card title and make up the
bulk of the card's content.
</p>
</div>
</div>`;
note.insertAdjacentHTML("afterbegin", htmlData);
console.log(note);
document.body.appendChild(note);
};
addBtn.addEventListener("click", () => {
addNewNote();
});
Firstly, just use innerHTML - it's an empty element:
note.innerHTML = htmlData;
Secondly, you need to select the element to append this note to. Add an ID:
<div class="container d-flex" id="noteContainer">
And append it like so:
document.getElementById("noteContainer").appendChild(note);
You can add an identifier to the div an use the appendChild to this div instead of the body of the document
<div id="myDiv" class="container d-flex"></div>
And at the end of your function
document.getElementById("myDiv").appendChild(note);
Working example
const button = document.getElementById("addButton")
const addNote = () => {
const myElement = document.createElement('p')
myElement.innerHTML = "Hello world !"
const div = document.getElementById("myDiv")
div.appendChild(myElement)
}
button.addEventListener("click", addNote)
<button id="addButton">Add element</button>
<div id="myDiv"></div>
Cache the container element.
Return the note HTML from the function (no need to specifically create an element - just wrap the note HTML in a .note container), and then add that HTML to the container.
(In this example I've used unicode for the icons, and a randomiser to provide some text to the note.)
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
function createNote(text = '') {
return`
<div class="note">
<div class="card m-4" style="width: 18rem">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">Card title</h5>
<span class="icons">
<button class="btn btn-primary">🖉</button>
<button class="btn btn-primary">🗑</button>
</span>
</div>
<hr />
<p class="card-text">${text}</p>
</div>
</div>
</div>
`;
};
function rndText() {
const text = ['Hallo world', 'Hovercraft full of eels', 'Two enthusiastic thumbs up', 'Don\'t let yourself get attached to anything you are not willing to walk out on in 30 seconds flat if you feel the heat around the corner'];
const rnd = Math.round(Math.random() * ((text.length - 1) - 0) + 0);
return text[rnd];
}
addBtn.addEventListener('click', () => {
const note = createNote(rndText());
container.insertAdjacentHTML('afterbegin', note);
});
<div>
<button type="button" class="add">Add note</button>
<div class="container"></div>
</div>

Why when I create several html tags with javascript then I can not delete it with the same javascript?

When I create a form with the write () command, then I want to delete it, but I can't. What is the cause of this problem?
In order to do this correctly, what command should I use or what should I change in my code?
var btn = document.querySelector('#btn');
var btn_alert = document.querySelector('#btn-alert');
var content = document.querySelector('.popup-container');
var div1 = document.getElementById('div1');
function message(message, btn) {
document.write('<div id="div1"><div id="content" class="popup-container"><div class="box-item"><div class="icon-success"><span class="span1"></span> <span class="span2"></span><div class="ring"></div></div><h2 class="alert-title">Good job!</h2><div class="alert-content">' + message + '</div><div class="actions-btn"><button onclick="ok()" class="btn-alert" id="btn-alert">' + btn + '</button></div></div></div></div>')
}
function ok() {
div1.removeChild(content);
}
<button class="btn-alert" id="btn">OK</button>
<!-- <div id="content" class="popup-container dis-active">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">is ok.</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">OK</button>
</div>
</div>
</div> -->
<script src="script.js"></script>
<script>
message("خوش اومدی!", "کلیک کن");
</script>
document.write is really outdated. In your script you write the elements to the document after you're trying to retrieve them. That won't work.
Here is an example snippet using insertAdjacentHTML to create a message element with a button to remove it.
It is generally not a good idea to use inline event handlers. The snippet uses event delegation to handle button clicks.
It may be wise to first learn more about html document manipulation or javascript.
document.addEventListener(`click`, handle);
const create = () => message(`خوش اومدی!`,`کلیک کن`);
create();
function handle(evt) {
if (evt.target.id === `btn-alert`) {
document.getElementById('div1').remove();
}
if (evt.target.id === `recreate`) {
create();
}
}
function message(message, btnTxt) {
document.body.insertAdjacentHTML(`beforeEnd`, `
<div id="div1">
<div id="content" class="popup-container">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">${message}</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">${btnTxt}</button>
</div>
</div>
</div>
</div>`);
}
<button id="recreate">(re)create message</button>

How to bind this within js nested object iteration within a function. Jquery

again, probably a terrible title - but what I'm trying to do is to make a simple search feature on my website. You click a nav button, which updates the search bar, whi in turn triggers an onchange event to update the current appended list.
function update() {
var list = $("#comic__modern-list");
list.empty();
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var filter = comics[this].type;
var publisher = comics[this].publisher;
if (search == "") {
if(filter == "modern") {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
} else if (search == publisher) {
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
});
}
The current list is generated by this, which works fine:
$.each(Object.keys(comics), function() {
var currentObject = comics[this];
var currentObject2 = comics[this].type;
console.log(currentObject2);
if (search == "") {
if(currentObject2 == "modern") {
var list = $("#comic__modern-list");
list.append(`
<div class="comic__box">
<div class="comic__image-box">
<img src="${currentObject['data-item-image']}" alt="${currentObject['data-item-description']}" class="img-fluid">
<div class="comic__desc-wrap">
<div class="comic__desc">${currentObject['data-item-description']}, issue #${currentObject['issue']} (${currentObject['year']})</div>
</div>
</div>
<div style="text-align:center; margin-top: 1rem">
<button
class="btn btn-warning snipcart-add-item comic__button"
data-item-id="${currentObject['data-item-id']}"
data-item-price="${currentObject['data-item-price']}"
data-item-url="${currentObject['data-item-url']}"
data-item-description="${currentObject['data-item-description']}"
data-item-image="${currentObject['data-item-image']}"
data-item-name="${currentObject['data-item-name']}">
<div class="comic__desc-desk">£${currentObject['data-item-price']}<br>Add to cart</div><div class="comic__desc-mob">BUY <br> ${currentObject['data-item-description']}, Issue: ${currentObject['issue']} (${currentObject['year']})</div>
</button>
</div>
</div>
`)
}
}
});
From what I can gather, this has to do with the keyword "this" no longer meaning what it did when it was outside of the function, so I'm assuming the fix will be to do with bind(), but I can't make heads nor tails of it.
p.s, if there's an easier/simpler way to set up a search system, please enlighten me!

How to create a span elements itself using javascript?

Hey am new to javascript but putting my all efforts I have written a javascript to copy the text inside <p></p> elements. I have written the code completely but my problem is I have to create span elements repeatedly. So can any one help me. My javascript
document.addEventListener('DOMContentLoaded',()=>{
const createtextbox=function(text){
let el=document.createElement('textarea');
el.style.position = 'fixed';
el.style.left = '0';
el.style.top = '0';
el.style.opacity = '0';
el.value = text;
document.body.appendChild(el);
return el;
};
const shortmessage=function(e,m,t){
let span=e.parentNode.querySelector( 'span' );
span.innerText=m;
setTimeout(()=>{span.innerText=''},700 * t)
span.classList.add("copystatusalert");
setTimeout(function() {span.classList.remove("copystatusalert")},700);
};
const copytoclipboard=function(e){
// create the hidden textarea and add the text from the sibling element
let n=createtextbox( this.parentNode.querySelector('p').innerHTML );
n.focus();
n.select();
document.execCommand('copy');
document.body.removeChild(n);
// flash a message in the SPAN-clear after 2s
shortmessage( this, 'Copied!', 0.7 );
};
/*
Find a reference to ALL buttons that are used to copy
text from a sibling element and assign an event handler
to process every button click.
*/
document.querySelectorAll('button.copystatus').forEach( bttn=>{
bttn.addEventListener( 'click', copytoclipboard )
});
})
My html
<div class='englishstatus'>
<div class='car'>
<div class='latestatus'>
<p>Life is good when you have books</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
<div class='latestatus'>
<p>Google is a open source library by Larry Page and Sergey Brin!</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
</div>
<div class='car'>
<div class='latestatus'>
<p>Cats are better than dogs.</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
<div class='latestatus'>
<p>Ferrets are better than rats</p>
<button class='copystatus btn'>Copy</button>
<span></span>
</div>
</div>
</div>
As you can see I need the span elements to create repeatedly so can anyone help me so that it can create itself a span elements. Thankyou in advance.
I've modified your JS code and put it to the straight point by adding the span elements dynamically. You can refactor it, separate the code snippets into different functions as you want. I just want to make the implementation logic straight forward here.
const buttons = document.querySelectorAll('.copystatus.btn');
buttons.forEach((btn) => {
btn.addEventListener('click', (e) => {
const quote = e.target.previousElementSibling.innerText;
const copyText = document.createElement('textarea');
copyText.value = quote;
document.body.appendChild(copyText);
copyText.select();
document.execCommand('copy');
document.body.removeChild(copyText);
const span = document.createElement('span');
span.textContent = 'copied';
e.target.parentElement.appendChild(span);
setTimeout(()=> {
span.remove();
}, 700)
})
})
<div class='englishstatus'>
<div class='car'>
<div class='latestatus'>
<p>Life is good when you have books</p>
<button class='copystatus btn'>Copy</button>
</div>
<div class='latestatus'>
<p>Google is a open source library by Larry Page and Sergey Brin!</p>
<button class='copystatus btn'>Copy</button>
</div>
</div>
<div class='car'>
<div class='latestatus'>
<p>Cats are better than dogs.</p>
<button class='copystatus btn'>Copy</button>
</div>
<div class='latestatus'>
<p>Ferrets are better than rats</p>
<button class='copystatus btn'>Copy</button>
</div>
</div>
</div>

Display none if child and parent element have the same class

I have these menus around my horizontal scrolling site.
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section
The goal is to filter them based if the button classes have the same class as the ones in the section. If they have the same class (in this example 'fun-stuff') then that button will display:none.
My jQuery. I feel I'm close or totally over-complicating it.
jQuery(document).ready(function($) {
var theList = $('.nav-list button');
var i;
for (i=0; i < theList.length; i++){
var theButtons = '"' + theList[i].className + '"';
var parentClassName = theList[i].closest('section').className;
// tried this one. Was close i believe but no dice
if(theButtons = theList[i].closest('section').hasClass('"' + theButtons + '"') ){
// display that button as none
}
// tried this as well and for each button got 'no' in the console
if( $(theList[i].closest('section') ).hasClass(theButtons) ){
console.log('yes');
} else {
console.log ('no');
}
}
});
Yes you overdid it somewhat
$(function() {
$("button").each(function() {
var $parent = $(this).closest("section"), // the section wrapping the button
same = $parent.hasClass($(this).attr("class")); // parent has this button's class too
$(this).toggle(!same); // hide if the same (show if not)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
If you have more than one class on the button and you want to hide if one of them matches
$(function() {
$("button").each(function() {
var bList = this.classList,
parentList = $(this).closest("section")[0].classList, // the DOM element's classList
same = [...parentList] // convert to iterable
.filter(ele => bList.contains(ele)) // look up parent class in button classList
.length>0; // found?
$(this).toggle(!same);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff bla">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can turn the section classes into a regular array, then filter and hide the buttons.
jQuery(document).ready(function($) {
var classes = $('#slide-1').attr("class").split(/\s+/);
classes.forEach(function (cls) {
$('.nav-list button').filter('.' + cls).hide()
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
You can do this pretty easily with vanilla Javascript:
const classNames = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach((el) => {
if(classNames.contains(el.classList)){
el.style.display = "none";
}
});
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>
Edit: Done with two lines of code:
const classList = document.getElementById("slide-1").classList;
document.querySelectorAll(".nav-list > button").forEach(el => el.style.display = classList.contains(el.classList) ? "none": "initial");
<section class="fun-stuff portfolio-cards" id="slide-1">
<div class="nav-list">
<button class="about">ABOUT</button>
<button class="fun-stuff">FUN STUFF</button>
<button class="home">HOME</button>
<button class="professional">PROFESSIONAL</button>
<button class="contact">CONTACT</button>
</div>
</section>

Categories

Resources