How to create a span elements itself using javascript? - 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>

Related

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 can I add elements in JS to certain divs

How do I put the created input into the other div in situation I presented below? If I introduce divs in js like this - '<div class="monday_input"><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>' removing the whole element is not working for some reason in this specific case. Answering the question. No I cannot create div in parent in html because input won't magically suit to created div . Please help me somehow, thank you!
HTML:
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus"></i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
JavaScript:
Function to adding:
function add_monday() {
if (monday_sub_count < 5) {
monday_sub_count++;
{
const mon = document.createElement('div');
mon.className = 'subcategory';
mon.innerHTML = '<textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" />';
monday_id_count++;
document.getElementById('mon').appendChild(mon);
}
}
}
Function to removing:
function removeMon(mon) {
document.getElementById('mon').removeChild(mon.parentNode);
monday_sub_count--;
monday_id_count--;
};
with your own HTML
function add_monday() {
var monday_sub_count = 0;
var a;
while (monday_sub_count < 5) {
a = '<div><textarea name="monday'+monday_id_count+'" placeholder="Type anything you want here" class="subcategory_text"></textarea><input type="button" class="remove_button" value="-" onclick="removeMon(this)" /></div>';
monday_sub_count++;
$('#mon').append(a);
}
}
Here is working, "proper" version of your code. I think your problem may come from over-complicating the removal process.
function add_monday()
{
let monday_count = 0;
// Use DocumentFragment for marginal optimizations
let fragment = new DocumentFragment();
while(monday_count < 5)
{
let monday = document.createElement('div');
monday.classList.add('subcategory');
let textarea = document.createElement('textarea');
textarea.classList.add('subcategory_text');
textarea.name = "monday_"+monday_count;
textarea.placeholder = "Type anything you want here";
let removeBtn = document.createElement('input');
removeBtn.type = "button";
removeBtn.classList.add('remove_button');
removeBtn.value = "-";
removeBtn.addEventListener('click', removeMon.bind(null, removeBtn));
monday.append(textarea, removeBtn);
fragment.appendChild(monday);
monday_count++;
}
document.getElementById('mon').appendChild(fragment);
}
function removeMon(button)
{
button.parentElement.remove();
}
I simplified your script a little and changed your name attributes: Instead of assigning individual names I simply gave all textareas the name monday[]. When posting this to a PHP page the values will be pushed into an array with the same name and in case you want to harvest the values with JavaScript, then this can be done easily too.
function add_monday(){
$("#mon").append('<div><textarea name="monday[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/></div>'.repeat(5))
}
$("#mon").on("click","input[type=button]",function(){$(this).parent(). remove()})
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<div class="day">
<div class="day_info">
<p>Monday</p>
</div>
<div class="add">
<div class="button" onclick="add_monday()">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="mon">
<div style="clear:both"></div>
</div>
And here a non-jQuery version:
const ad=document.querySelector(".alldays");
ad.innerHTML=
"Mon,Tues,Wednes,Thurs,Fri,Satur,Sun".split(",").map(d=>`
<div class="day">
<div class="day_info"><p>${d}day</p></div>
<div class="add">
<div class="button">
<i class="fas fa-plus" id="plus">click here to add fields</i>
</div>
</div>
<div style="clear:both"></div>
</div>
<div id="${d.toLowerCase().substr(0,3)}">
<div style="clear:both"></div>
</div>`).join("");
function add2day(el,n){
const wd=el.closest(".day"),
d=wd.querySelector("p").textContent.toLowerCase(),
html=`<textarea name="${d.toLowerCase()}[]" placeholder="Type anything you want here"></textarea><input type="button" value="-"/>`;
while (n--) {
let div= document.createElement("div");
div.innerHTML=html;
wd.nextElementSibling.appendChild(div);
}
}
ad.addEventListener("click",function(ev){
const el=ev.target;
switch(el.tagName){
case "INPUT": // remove field
el.parentNode.remove(); break;
case "I": // add new fields
add2day(el,3); break;
}
})
<div class="alldays"></div>
I extended the second script to make it work for any day of the week.

How to creat copy alerts to many buttons?

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>

Link simillary name classes so that when one is clicked the other is given a class

Basically, I'm asking for a way to optimize this code. I'd like to cut it down to a few lines because it does the same thing for every click bind.
$("#arch-of-triumph-button").click(function(){
$("#arch-of-triumph-info").addClass("active-info")
});
$("#romanian-athenaeum-button").click(function(){
$("#romanian-athenaeum-info").addClass("active-info")
});
$("#palace-of-parliament-button").click(function(){
$("#palace-of-parliament-info").addClass("active-info")
});
Is there a way to maybe store "arch-of-triumph", "romanian-athenaeum", "palace-of-parliament" into an array and pull them out into a click bind? I'm thinking some concatenation maybe?
$("+landmarkName+-button").click(function(){
$("+landmarkName+-info").addClass("active-info")
});
Is something like this even possible?
Thanks in advance for all your answers.
EDIT: Here's the full HTML.
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button"></div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button"></div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Assuming you're not able to modify your HTML markup (in which case with use of CSS classes would be cleaner), a solution to your question would be as shown below:
// Assign same click handler to all buttons
$("#arch-of-triumph-button, #romanian-athenaeum-button, #palace-of-parliament-button")
.click(function() {
// Extract id of clicked button
const id = $(this).attr("id");
// Obtain corresponding info selector from clicked button id by replacing
// last occurrence of "button" pattern with info.
const infoSelector = "#" + id.replace(/button$/gi, "info");
// Add active-info class to selected info element
$(infoSelector).addClass("active-info");
});
Because each .landmark-button looks to be in the same order as its related .landmark-info, you can put both collections into an array, and then when one is clicked, just find the element with the same index in the other array:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
This does not rely on IDs at all - feel free to completely remove those from your HTML to declutter, because they don't serve any purpose now that they aren't being used as selectors.
Live snippet:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
.active-info {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button">click</div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button">click</div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Older answer, without knowing the HTML: You can extract the ID of the clicked button, slice off the button part of it, and then select it concatenated with -info:
$(".landmark-button").click(function() {
const infoSel = this.id.slice(0, this.id.length - 6) + 'info';
$(infoSel).addClass('active-info');
});
A much more elegant solution would probably be possible given the HTML, though.

Jquery throw only one action

I have organized the page this way:
<div class="singlePost">
<div class="post"> </div>
<div class="comments" data-idPost="310"> </div>
<div class="formComment">
<textarea data-idPost="310"></textarea>
<button data-idPost="310">Insert</button>
</div>
</div>
<div class="singlePost">
<div class="post"> </div>
<div class="comments" data-idPost="304"> </div>
<div class="formComment">
<textarea data-idPost="304"></textarea>
<button data-idPost="304">Insert</button>
</div>
</div>
I used html5 data-attributes to distinguish posts and my jquery code is:
$(".formCommento button").click(function() {
idPost=$(this).attr('data-idpost');
text=$('textarea[data-idpost="'+idPost+'"]').val();
noty({text: 'I\'m going to insert '+text});
//and here i make the ajax request
return false;
});
I think this is not the way to organize this kind of stuff. I have the problem that when i click on the button i have multiple actions running together so the same comment is inserted several times. What do you suggest to do?
If you are learning to "organize" as well, I would suggest only to use once your data-, like:
<div class="singlePost" data-postId="310">
<div class="post"> </div>
<div class="comments"> </div>
<div class="formComment">
<textarea></textarea>
<button class="btn-submit">Insert</button>
</div>
</div>
<div class="singlePost" data-postId="311">
<div class="post"> </div>
<div class="comments"> </div>
<div class="formComment">
<textarea></textarea>
<button class="btn-submit">Insert</button>
</div>
</div>
then, fire it for every button:
$(".singlePost .btn-submit").click(function() {
var singlePost = $(this).closest(".singlePost"), // get singlePost block
postId = singlePost.attr("data-postId"), // read data attribute
txt = singlePost.find("textarea").val(); // get it's own textarea value
// do your magic
});
Here's a live example: http://jsbin.com/iyomaj/1/edit
try this, pass related context, by default jQuery uses document as context so it search in whole document
$(".formComment button").click(function() {
var parentdiv = $(this).closest('.formComment');
idPost=$(this).attr('data-idpost');
text=$('textarea[data-idpost="'+idPost+'"]',parentdiv ).val();
noty({text: 'I\'m going to insert '+text});
//and here i make the ajax request
return false;
});

Categories

Resources