const adder = document.querySelector('.adder')
const gridcont = document.querySelector('.gridbox')
const text = document.querySelector('p')
const button = document.querySelector('.button')
const popup = document.querySelector('.popup-wrapper')
const popuptext = document.querySelector('.popup-content')
const close = document.querySelector('.popup-close')
const notecard = document.querySelector('.card')
const notetext = document.querySelector('.card-text')
const pi = document.querySelector('p')
let counter = 0;
let html;
let note;
let html2
/*close.addEventListener('click', e =>{
popup.style.display ='none'
}) */
popup.addEventListener('click', e=>{
popup.style.display ='none'
})
const template = note =>{
html = `<div class="card">
<div class="card-body">
<h5 class="card-title">Note ${counter}</h5>
<p class="card-text">${note}</p>
<button class="button" type="button">view detail</button>
</div>
</div>`
gridcont.innerHTML += html
}
adder.addEventListener('submit', e =>{
e.preventDefault()
note = adder.add.value
if(note.length){
counter++
template(note)
adder.reset()
}
})
gridcont.addEventListener('click', e =>{
if(e.target.classList.contains('button')){
popup.style.display = 'block'
popuptext.innerHTML = html
}
});
.card{
margin-left: 2rem;
margin-top: 2rem;
}
.form-control{
max-width: 500px;
}
.blu{
color: blue;
}
.gridbox{
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
.button{
color:white;
background-color: rgb(41, 41, 241);
border-color: rgb(41, 41, 241);;
}
.card-text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
.popup-wrapper{
display: none;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.popup{
font-family: arial;
text-align: center;
width: 100%;
max-width: 500px;
margin: 10% auto;
padding: 20px;
background: white;
position: relative;
}
.popup-close{
position: absolute;
top: 5px;
right: 8px;
cursor: pointer;
}
.card-text-show{
overflow: unset;
text-overflow: unset;
max-width: 200px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<title>Note taker</title>
</head>
<body>
<div class="head text-center">
<header>
<h1>Note taker app</h1>
<h8 class="blu">add note:</p>
</header>
<form class="adder">
<input class="form-control m-auto" type="text" name="add" placeholder="Enter your note here">
</form>
</div>
<div class="gridbox">
</div>
<div class="popup-wrapper">
<div class="popup">
<div class="popup-close">x</div>
<div class="popup-content">
<h5 class="card-title"> </h5>
<p class="card-text"> </p>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
im trying to make note taker app and each time i add the note and click the view detail button
it shows me only the content of last item added regardless of which one i press i dont know how to write with loop or forEach method i tried it but i failed can anyone explain what to do here im a begginer JS
const adder = document.querySelector('.adder')
const gridcont = document.querySelector('.gridbox')
const text = document.querySelector('p')
const button = document.querySelector('.button')
const popup = document.querySelector('.popup-wrapper')
const popuptext = document.querySelector('.popup-content')
const close = document.querySelector('.popup-close')
const notecard = document.querySelector('.card')
const notetext = document.querySelector('.card-text')
const pi = document.querySelector('p')
let counter = 0;
let html;
let note;
let html2
/*close.addEventListener('click', e =>{
popup.style.display ='none'
}) */
popup.addEventListener('click', e=>{
popup.style.display ='none'
})
const template = note =>{
html = `<div class="card">
<div class="card-body">
<h5 class="card-title">Note ${counter}</h5>
<p class="card-text">${note}</p>
<button class="button" type="button">view detail</button>
</div>
</div>`
gridcont.innerHTML += html
}
adder.addEventListener('submit', e =>{
e.preventDefault()
note = adder.add.value
if(note.length){
counter++
template(note)
adder.reset()
}
})
gridcont.addEventListener('click', e =>{
if(e.target.classList.contains('button')){
popup.style.display = 'block'
popuptext.innerHTML = html
}
});
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<title>Note taker</title>
</head>
<body>
<div class="head text-center">
<header>
<h1>Note taker app</h1>
<h8 class="blu">add note:</p>
</header>
<form class="adder">
<input class="form-control m-auto" type="text" name="add" placeholder="Enter your note here">
</form>
</div>
<div class="gridbox">
</div>
<div class="popup-wrapper">
<div class="popup">
<div class="popup-close">x</div>
<div class="popup-content">
<h5 class="card-title"> </h5>
<p class="card-text"> </p>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
I dont really know many methods so i just use one way im stuck on this project for 4 days
CSS
.card{
margin-left: 2rem;
margin-top: 2rem;
}
.form-control{
max-width: 500px;
}
.blu{
color: blue;
}
.gridbox{
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
.button{
color:white;
background-color: rgb(41, 41, 241);
border-color: rgb(41, 41, 241);;
}
.card-text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
.popup-wrapper{
display: none;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.popup{
font-family: arial;
text-align: center;
width: 100%;
max-width: 500px;
margin: 10% auto;
padding: 20px;
background: white;
position: relative;
}
.popup-close{
position: absolute;
top: 5px;
right: 8px;
cursor: pointer;
}
.card-text-show{
overflow: unset;
text-overflow: unset;
max-width: 200px;
}
On popuptext.innerHTML = html line you are making the mistake, so what is happening is you are setting the innerHTML of popuptext as variable html, so this line tries find html variable and goes to part of this code,
const template = note =>{
html = `<div class="card">
<div class="card-body">
<h5 class="card-title">Note ${counter}</h5>
<p class="card-text">${note}</p>
<button class="button" type="button">view detail</button>
</div>
</div>`
gridcont.innerHTML += html
}
and then it finds the HTML variable here, however the value of this html variable will be whatever you have set it to earlier, so if you add three notes then the value of the html variable will be innerhtml of the latest/last note that you added.
To fix that I have made a change as popuptext.innerHTML = e.target.parentElement.innerHTML, this line makes sure that whatever element you are clicking that element's associated innerhtml is added to the popup.
const adder = document.querySelector('.adder')
const gridcont = document.querySelector('.gridbox')
const text = document.querySelector('p')
const button = document.querySelector('.button')
const popup = document.querySelector('.popup-wrapper')
const popuptext = document.querySelector('.popup-content')
const close = document.querySelector('.popup-close')
const notecard = document.querySelector('.card')
const notetext = document.querySelector('.card-text')
const pi = document.querySelector('p')
let counter = 0;
let html;
let note;
let html2
/*close.addEventListener('click', e =>{
popup.style.display ='none'
}) */
popup.addEventListener('click', e=>{
popup.style.display ='none'
})
const template = note =>{
html = `<div class="card">
<div class="card-body">
<h5 class="card-title">Note ${counter}</h5>
<p class="card-text">${note.substring(0,6)}...<span class="only-popup">${note}</span></p>
<button class="button" type="button">view detail</button>
</div>
</div>`
gridcont.innerHTML += html
}
adder.addEventListener('submit', e =>{
e.preventDefault()
note = adder.add.value
if(note.length){
counter++
template(note)
adder.reset()
}
})
gridcont.addEventListener('click', e =>{
if(e.target.classList.contains('button')){
popup.style.display = 'block'
let temp = `<div class="card">
<div class="card-body">
<h5 class="card-title">${e.target.parentElement.querySelector('.card-title').innerText}</h5>
<p class="card-text">${e.target.parentElement.querySelector('.only-popup').innerText}</p>
<button class="button" type="button">view detail</button>
</div>
</div>`
popuptext.innerHTML = temp
}
});
.card{
margin-left: 2rem;
margin-top: 2rem;
}
.form-control{
max-width: 500px;
}
.blu{
color: blue;
}
.gridbox{
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
.button{
color:white;
background-color: rgb(41, 41, 241);
border-color: rgb(41, 41, 241);;
}
.card-text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
.popup-wrapper{
display: none;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.popup{
font-family: arial;
text-align: center;
width: 100%;
max-width: 500px;
margin: 10% auto;
padding: 20px;
background: white;
position: relative;
}
.popup-close{
position: absolute;
top: 5px;
right: 8px;
cursor: pointer;
}
.only-popup{
display:none;
}
.card-text-show{
overflow: unset;
text-overflow: unset;
max-width: 200px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<title>Note taker</title>
</head>
<body>
<div class="head text-center">
<header>
<h1>Note taker app</h1>
<h8 class="blu">add note:</p>
</header>
<form class="adder">
<input class="form-control m-auto" type="text" name="add" placeholder="Enter your note here">
</form>
</div>
<div class="gridbox">
</div>
<div class="popup-wrapper">
<div class="popup">
<div class="popup-close">x</div>
<div class="popup-content">
<h5 class="card-title"> </h5>
<p class="card-text"> </p>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
Related
I am trying to make my first web app (a tarot card drawer with meanings, interpretations and symbolism listed). It is based on this other project:
https://github.com/SamJamWillingham/Tarot-Card-Drawer
I am modifying it a bit by loading an external local JSON file instead of keeping a massive object in the JSt is very basic and I am a beginner, so I would appreciate some help.
No matter what I do I keep getting this error:
"Uncaught TypeError: Property 'handleEvent' is not callable"
Whenever I click on the the tarot cards, which should draw another card.
Here is the code:
let carda = document.querySelector("div.carda");
let cardb = document.querySelector("div.cardb");
let cardName = document.querySelector("h3.name");
let moreInfo = document.querySelector("p.about");
async function drawCard(x) {
const birchwood = 'tarotdeck.json';
const request = new Request(birchwood);
const response = await fetch(request);
const cardsArr = await response.json();
const attributesArr = Object.values(cardsArr.cards[x]);
console.log(attributesArr)
return attributesArr;
}
//Making the function syncronous doesn't help
function getRandomNumber(min, max) {
let step1 = max - min + 1;
let step2 = Math.random() * step1;
let result = Math.floor(step2) + min;
return result; //I refuse to rely on hoisting, its like autosave
}
const jackandjill = async() => {
return eval((drawCard(getRandomNumber(0, 78))));
async function changeCard(inputLetter) {
let cardString = eval("card" + inputLetter);
const card = cardString;
const ranIndex = getRandomNumber(0, 78); //obviously this has to match the number of cards.
const cardDrawn = await drawCard(ranIndex); //this too must be async, or else ITS ALWAYS undefined, but the console.log is good enough
cardName.innerHTML = cardDrawn[0];
moreInfo.innerHTML = cardDrawn[1];
function fill(num, dommy) {
return Promise.resolve(drawCard(ranIndex)).then((value) => dommy.innerHTML = (value[num]))
};
fill(1, "name")
carda.classList.remove("default-styling");
cardName.classList.remove("hide");
moreInfo.classList.remove("hide")
}
setTimeout(500);
cardb.addEventListener("click", changeCard("a"));
setTimeout(500);
carda.addEventListener("click", changeCard("b"));
div.app_container {
max-width: 600px;
border-radius: 8px;
margin: 15px auto;
background-image: linear-gradient(-225deg, #e3fdf5 0%, #ffe6fa 100%);
box-shadow: 8px 8px 10px rgba(0, 0, 0, 0.281);
padding: 25px;
}
div.default-styling {
display: block;
margin: 0 auto;
color: #000000;
background-color: aqua; /*Delete me!*/
text-align: center;
border: 1px solid #000000;
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.1);
max-width: 220px;
padding-top: 125px;
padding-bottom: 125px;
}
img.cardImg{
display: block;
margin: 0 auto;
max-width: 189px;
height: 320px;
}
div.newCard, .carda, .cardb{
display: block;
margin: 0 auto;
max-width: 210px;
border: none;
background-color: red; /*Delete me!*/
border-radius: 15px;
}
#cardb{
float: right;
width: 300px;
height: 300px;
}
.cardb{
float: left;
height: 320px;
width: 300px;
}
h1 {
font-family: "cursive";
text-align: center;
}
h3,
p {
font-family: "sans-serif";
text-align: left;
}
small {
display: block;
margin: 0 auto;
text-align: center;
}
.hide {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Daily Tarot</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
</head>
<body>
<div class="app_container">
<h1>Tarot</h1>
<div id=c arda>
<div class="carda default-styling">
</br>
</div>
<div id=c ardb>
<div class="cardb default-styling">
</br>
</div>
<h3 class="name hide">Name of card</h3>
<p class="about hide">About card</p>
<h3 class="arcana hide">arcana card</h3>
<p class="suit hide">suit card</p>
<p class="fortune hide">Fortune telling</p>
<p class="keywords hide"> keywords </p>
<p class="meanings hide"> meanings </p>
<p class="Archetype hide">Archetype </p>
<p class="Hebrew hide">Hebrew Alphabet </p>
<p class="Numerology hide">Numerology </p>
<p class="Elemental hide">Elemental </p>
<p class="Mythic hide">Mythical/Spiritual </p>
<p class="Questions hide"> Questions to Ask </p>
</div>
</div>
</div>
<small>The images and information about each card are from
Tarot.com<br /><a
href="https://github.com/SamJamWillingham/Tarot-Card-Drawer"
>Open course code</a>
</small>
<script src="script.js"></script>
</body>
</html>
This particular question and its answer did not help:
TypeError: Property 'handleEvent' is not callable IN FIREFOX
Thankyou and my apologies if I am doing this (code or posting) all wrong.
I was trying to get the card to change whenever the card on the page is clicked on through a DOM event. But what happens instead is "Uncaught TypeError: Property 'handleEvent' is not callable".
I'm trying to calculate the values that are in my input boxes that's in the middle of the webpage. I thought if i add the class names references in JS within a function that i would get the results or atleast no error messages but now it says "calculate is not defined
at addTotal
at HTMLButtonElement.onclick"
What i am trying to do is Multiply the values by the numbers that's assigns to the boxes and then display the total below the button.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Document</title>
</head>
<body>
<div class="wrapper">
<textarea name="Buy" id="advertise" cols="55" rows="50"></textarea>
<div id="textFields">
<textarea name="" class="center calculate" cols="100" rows="5"></textarea>
<textarea name="" class="center calculate2" cols="100" rows="5"></textarea>
<textarea name="" class="center calculate3" cols="100" rows="5"></textarea>
<div class="buttonClass">
<button class="addTotalButton" onclick="addTotal()">Add Total</button>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
body {
background-color: #434343;
}
#textFields {
display: flex;
flex-direction: column;
margin: 0 auto;
}
.center {
display: block;
text-align: center;
margin-top: 100px;
}
.wrapper {
display: flex;
width: 100%;
height: 100%;
}
/* #inputButton {
display: flex;
flex-direction: column;
background-color: #011526;
color: aliceblue;
text-align: center;
line-height: 30px;
padding: 10px;
flex-basis: 50%;
} */
.buttonClass {
display: flex;
justify-content: center;
}
.addTotalButton {
margin-top: 50px;
}
let addTotal = ()=> {
let answerElement = document.getElementsByClassName("calculate")
answerElement.innerHTML = parseInt(addTotal) * 20;
let quoteElement = document.getElementsByClassName("calculate2")
quoteElement.innerHTML = parseInt(addTotal) * 30;
let timesElement = document.getElementsByClassName("calculate3")
timesElement.innerHTML = parseInt(addTotal) * 50;
return calculate + calculate2 + calculate3;
}
I think you can change several point in your code
use input with type number instead of textarea (you will be able to use element.value to get the value)
document.getElementsByClassName return an array if you just want one element you can access it by index or use querySelector that return you the first element match selector
your function add Total do nothing if you want to set the value of main text area you can use element.value
let addTotal = ()=> {
let answerElement = document.querySelector(".calculate");
let calculate = parseInt(answerElement.value) * 20;
let quoteElement = document.querySelector(".calculate2");
let calculate2 = parseInt(quoteElement.value) * 20;
let timesElement = document.querySelector(".calculate2");
let calculate3 = parseInt(timesElement.value) * 20;
console.log(calculate + calculate2 + calculate3);
document.getElementById('advertise').value = calculate + calculate2 + calculate3;
}
body {
background-color: #434343;
}
#textFields {
display: flex;
flex-direction: column;
margin: 0 auto;
}
.center {
display: block;
text-align: center;
margin-top: 100px;
}
.wrapper {
display: flex;
width: 100%;
height: 100%;
}
/* #inputButton {
display: flex;
flex-direction: column;
background-color: #011526;
color: aliceblue;
text-align: center;
line-height: 30px;
padding: 10px;
flex-basis: 50%;
} */
.buttonClass {
display: flex;
justify-content: center;
}
.addTotalButton {
margin-top: 50px;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Document</title>
</head>
<body>
<div class="wrapper">
<textarea name="Buy" id="advertise" cols="55" rows="50"></textarea>
<div id="textFields">
<input type="number" class="center calculate"/>
<input type="number" class="center calculate2"/>
<input type="number" class="center calculate3"/>
<div class="buttonClass">
<button class="addTotalButton" onclick="addTotal()">Add Total</button>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
I am trying to query a cloned element in my dom and queryselector can not find it. Specifically #reply_form brings up nothing despite the id being used in the template. I've also tried ("#reply_form"+post_id) since I re id it at the bottom before pushing it to the dom and nothing. I'm all out of ideas.
Here is the code:
<template id="reply_template">
<div class="lk">
<img class="profile_image" />
<div>
<div class="user">
<div class="reply_author"></div>
<div class="reply-body"></div>
</div>
<div class="reply">
<div class="d-flex align-items-center">
<i id="upvote" class="fas fa-arrow-up hover"></i>
<span id="upvote_count_badge" class="badge bg-secondary"></span>
<i id="downvote" class="fas fa-arrow-down hover"></i>
</div>
<div class="reply_comment" id="reply">Reply</div>
<div id="post_award_modal" data-bs-toggle="modal" data-bs-target="#siteModal">
<i class="fas fa-award hover"></i>
</div>
</div>
<div id="vl" class="vl"></div>
<form id="reply_form" class="form-hidden">
<img class="profile_image"/>
<input class="cmt-reply" type="text" placeholder="Write a reply2"/>
</form>
<div id="reply_loader"><!--Nested Replies go here--></div>
</div>
</div>
</template>
<script>
function loadReplies(post_id, count) {
var reply_loader = document.querySelector('#reply_loader'+post_id)
var reply_template = document.querySelector('#reply_template');
if (count==0) {
fetch('/_load_replies?f='+post_id).then((response) => {
// Convert the response data to JSON
response.json().then((data) => {
for (var i = 0; i < data.length; i++) {
//add_post(template, counter)
// Clone the HTML template
let template_clone = reply_template.content.cloneNode(true);
// Query & update the template content
let post_id=data[i].post_id;
let post_url=data[i].post_url;
let author=data[i].author;
let author_id=data[i].author_id;
let post_saved=data[i].current_user.post_saved;
let post_upvoted=data[i].current_user.post_upvoted;
let post_downvoted=data[i].current_user.post_downvoted;
let current_user=data[i].current_user.current_user;
let is_moderator=data[i].current_user.is_moderator;
let is_big_top_moderator=data[i].current_user.is_big_top_moderator;
let awards=data[i].awards;
let media_url=data[i].media_url;
let community=data[i].community;
profile_images=template_clone.querySelectorAll(".profile_image");
for(var k=0; k<profile_images.length; k++) {
profile_images[k].src=data[i].post_profile_image;
}
let top=data[i].author;
top+=" "+moment(data[i].timestamp).fromNow();
if (awards) {
top+=' ';
for(var key in awards) {
top+=awards[key]+' '+key;
}
}
if (post_upvoted) {
template_clone.querySelector("#upvote").setAttribute("style", "color: white");
template_clone.querySelector("#downvote").setAttribute("style", "color: gray");
} else if (post_downvoted) {
template_clone.querySelector("#upvote").setAttribute("style", "color: gray");
template_clone.querySelector("#downvote").setAttribute("style", "color: white");
} else {
template_clone.querySelector("#upvote").setAttribute("style", "color: gray");
template_clone.querySelector("#downvote").setAttribute("style", "color: gray");
}
template_clone.querySelector("#upvote").setAttribute("onclick", "vote("+post_id+",1)");
template_clone.querySelector("#downvote").setAttribute("onclick", "vote("+post_id+",0)");
template_clone.querySelector("#post_award_modal").setAttribute("onclick", "build_award_modal("+post_id+")");
template_clone.querySelector(".reply_author").innerHTML=top
template_clone.querySelector(".reply-body").innerHTML=data[i].body;
template_clone.querySelector("#upvote_count_badge").innerHTML=data[i].upvotes-data[i].downvotes;
//it finds #reply no problem
template_clone.querySelector("#reply").addEventListener("click", (e)=>{
e.target.classList.toggle("blue");
//It can not find this at all no matter what. I re id it at the bottom
console.log(template_clone.querySelector("#reply_form"+post_id))
template_clone.querySelector("#reply_form"+post_id).setAttribute("style", "color: blue")
template_clone.querySelector("#vl")
});
//re id
template_clone.querySelector("#upvote").id="upvote"+post_id;
template_clone.querySelector("#upvote_count_badge").id="upvote_count_badge"+post_id;
template_clone.querySelector("#downvote").id="downvote"+post_id;
template_clone.querySelector("#reply_loader").id="reply_loader"+post_id;
template_clone.querySelector("#reply").id="reply"+post_id;
template_clone.querySelector("#reply_form").id="reply_form"+post_id;
template_clone.querySelector("#vl").id="vl"+post_id;
reply_loader.appendChild(template_clone);
}
})
})
}
}
</script>
Here is a code snippet:
function open_form(post_id) {
console.log("reply"+post_id)
document.getElementById("#reply"+post_id).classList.toggle("blue")
document.getElementById("#reply_form"+post_id).classList.toggle("open")
document.getElementsByID("#vl"+post_id).classList.toggle("open");
}
.like-comment, .reply_comment{
cursor: pointer;
}
.vl{
border-left: 1px solid white;
border-bottom: 1px solid white;
border-bottom-left-radius: 30px;
width: 5%;
top: 25px;
position: absolute;
height: 100%;
left: -20px;
display: none;
}
.thumb.open, .vl.open, .form-hidden.open{
display: flex;
}
.form-hidden{
position: relative;
transform: translateX(35px);
display: none;
}
.profile_image{
width: 30px;
height: 30px;
border-radius: 50%;
}
.cmt-reply{
width: 75%;
height: 30px;
padding: 5px;
border-radius: 8px;
border: none;
margin-left: 5px;
}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.5.0/font/bootstrap-icons.css">
<link href="/static/css/style.css" rel="stylesheet">
<script src="https://js.stripe.com/v3/"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body>
<!--Broken Code here-->
<div class="reply_comment" id="reply64" onclick="open_form(64)">Reply</div>
<div id="vl64" class="vl"></div>
<form id="reply_form64" class="form-hidden">
<img class="profile_image" src="/avatars/1be25219994e4ef695e1c6f0d4d128ac_m.png">
<input class="cmt-reply" type="text" placeholder="Write a reply2">
</form>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js" integrity="sha512-LGXaggshOkD/at6PFNcp2V2unf9LzFq6LE+sChH7ceMTDP0g2kn6Vxwgg7wkPP7AAtX+lmPqPdxB47A0Nz0cMQ==" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
</body>
When using getElementById you don't need to pass # in the string. check following snippet.
function open_form(post_id) {
console.log("reply" + post_id)
document.getElementById("reply" + post_id).classList.toggle("blue");
document.getElementById("reply_form" + post_id).classList.toggle("open");
document.getElementById("vl" + post_id).classList.toggle("open");
}
.like-comment,
.reply_comment {
cursor: pointer;
}
.vl {
border-left: 1px solid white;
border-bottom: 1px solid white;
border-bottom-left-radius: 30px;
width: 5%;
top: 25px;
position: absolute;
height: 100%;
left: -20px;
display: none;
}
.thumb.open,
.vl.open,
.form-hidden.open {
display: flex;
}
.form-hidden {
position: relative;
transform: translateX(35px);
display: none;
}
.profile_image {
width: 30px;
height: 30px;
border-radius: 50%;
}
.cmt-reply {
width: 75%;
height: 30px;
padding: 5px;
border-radius: 8px;
border: none;
margin-left: 5px;
}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.5.0/font/bootstrap-icons.css">
<link href="/static/css/style.css" rel="stylesheet">
<script src="https://js.stripe.com/v3/"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body>
<!--Broken Code here-->
<div class="reply_comment" id="reply64" onclick="open_form(64)">Reply</div>
<div id="vl64" class="vl"></div>
<form id="reply_form64" class="form-hidden">
<img class="profile_image" src="/avatars/1be25219994e4ef695e1c6f0d4d128ac_m.png">
<input class="cmt-reply" type="text" placeholder="Write a reply2">
</form>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js" integrity="sha512-LGXaggshOkD/at6PFNcp2V2unf9LzFq6LE+sChH7ceMTDP0g2kn6Vxwgg7wkPP7AAtX+lmPqPdxB47A0Nz0cMQ==" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
</body>
Here is getElementById documentation on mdn.
That is the missalignmentSo, I wanted to program TicTacToe on a Webpage, using plain JavaScript, HTML, and CSS. I've made some logic, so the board can update based on the entries in an array, but when I do that, the buttons aren't in a line anymore, and it looks really bad.
Expected result: Text gets filled into the button, the button remains at its place.
Actual Result: Text gets filled in but the button moves down.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="scripts.js"></script>
<title>My Website</title>
</head>
<body>
<div id="board">
<div id="row1">
<button class="field"> </button>
<button class="field"> </button>
<button class="field"> </button>
</div>
<div id="row2">
<button class="field"> </button>
<button class="field"> </button>
<button class="field"> </button>
</div>
<div id="row3">
<button class="field"> </button>
<button class="field"> </button>
<button class="field"> </button>
</div>
</div>
</body>
</html>
CSS:
.field{
display: inline-block;
border-style: solid;
background-color: white;
height: 100px;
width: 100px;
font-size: 10px;
}
#board {
margin-left: 40%;
margin-top: 20%;
height: 50%;
}
JS:
function game() {
this.board = [
" ", "x ", " ",
" ", " ", " ",
" ", " ", " x"
]
this.printBoard = function(buttons) {
for(i = 0; i < buttons.length; i++) {
buttons[i].innerHTML = this.board[i];
}
}
}
window.onload = function() {
let buttons = document.getElementsByClassName("field");
let myGame = new game();
myGame.printBoard(buttons);
}
You need to have some control at the rows. Try display: flex at the #row1, #row2, #row3
class game {
fig = {x: "⭕", o: "❌"};
board = Array(9).fill("");
el = document.querySelector("#board");
constructor() {
this.printBoard();
}
printBoard(){
this.el.innerHTML = this.board.reduce((h, f) => h + `<button>${this.fig[f]||""}</button>`, "");
}
};
const myGame = new game();
myGame.board[0] = "x";
myGame.board[8] = "o";
myGame.printBoard();
#board {
display: flex;
flex-flow: row wrap;
width: 50vh;
height: 50vh;
}
#board > button {
flex-grow: 1;
--margin: 0vh; /* Set a desired value */
width: calc(33.333% - var(--margin) * 2);
margin: var(--margin);
border: 0;
box-shadow: 0 0 0 0.5px #000;
background-color: white;
font-size: 10vh;
line-height: 0;
cursor: pointer;
transition: background 0.3s;
}
#board > button:hover {
background: #0bf;
}
<div id="board"></div>
Problem: My password generator will not work until I move my slider. However, I would like the value to default to 8. So if someone loads page, and clicks generate PW, a random pw of 8 would populate.
//generate a password function
function passwordGenerator () {
// Length of the password?
var passwordLength = document.getElementById('num').value;
// characters options for PW
const values = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!##$%^&*()";
// defining password
var password = "";
// creating a loop to choose password
for (var i = 1; i <= passwordLength; i++) {
password = password + values.charAt(Math.floor(Math.random() * Math.floor(values.length -1)));
}
// adding the password to the content area
document.getElementById('display').value = password;
}
// adjust value when moving slider
function sliderMove(){
document.getElementById('num').value = document.getElementById('slider1').value;
document.getElementById('num').textContent = document.getElementById('num').value;
}
//copy to clipboard
function selectText() {
const input = document.getElementById('display');
input.focus();
input.select();
document.execCommand('copy')
}
.backgroundWhite {
background-color: white;
border: darkgray 2px solid;
padding-bottom: 25px;
}
.backgroundGray {
background-color: lightgray;
width: 100%;
height: 500%;
}
.passwordBox {
width: 500px;
height: 200px;
text-align: center;
}
body {
height: 100%;
background-color: lightgray;
}
.headText {
padding: 50px;
}
.buttonOnClick {
margin: 20px;
}
.passGenButton {
color: white;
background-color: red;
margin-right: 15%;
height: 40px;
border-radius: 12px;
}
.copyButton {
margin-left: 15%;
background-color: darkgray;
color: white;
height: 40px;
border-radius: 12px;
}
textarea {
padding: 20px;
font-size: 19px;
color: #4f4f4f;
}
.titleClass {
padding-top: 10px;
}
#media (max-width: 537px) {
.passGenButton {
color: white;
background-color: red;
margin-right: 1%;
height: 40px;
border-radius: 12px;
}
.copyButton {
margin-left: 1%;
background-color: darkgray;
color: white;
height: 40px;
border-radius: 12px;
}
.passwordBox {
width: 400px;
height: 200px;
text-align: center;
}
.backgroundWhite {
background-color: white;
border: darkgray 2px solid;
padding-bottom: 25px;
padding-left: 20px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="app.js"></script>
<title>Random Password Generator</title>
</head>
<body>
<div class="conatiner backgroundGray">
<div class="row">
<div class="col-12">
<div class="topText">
<!-- Header -->
<h1 class="text-center text-dark headText">Password Generator</h1>
</div>
<div class="container">
<div class='row'>
<div class="col-lg-12 col-sm-12 text-center">
<div class="content backgroundWhite">
<!-- Sub Header -->
<h4 class="titleClass">Generate a Password</h4>
<br />
<!-- Slider -->
<div class="slidecontainer">
<p>Select PW Length</p>
<input id="slider1" type="range" min="8" max="128" value="8" onchange="sliderMove()"
class="robClass">
<span id="num">8</span>
</div>
<br />
<!-- Password Box -->
<textarea class="passwordBox" type="text" id="display"
placeholder="Your Secure Password"></textarea>
<br />
<button onclick="passwordGenerator()" class="passGenButton buttonOnClick">Generate
Password</button>
<button class="buttonOnClick copyButton" defaultValue="8" onclick="selectText()">Copy to
clipboard</button>
<div id='length'></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I have played with HTML and JS. I have tried to create a var num = 8;
no luck.
Does anyone have any ideas on how I can do this?
At the start of your passwordGenerator function:
var passwordLength = document.getElementById('num').value;
This element (<span id="num">8</span>) doesn't have a value attribute, so your function will try to generate a password with a length equal to undefined.
You should get the value from your slider instead:
var passwordLength = document.getElementById('slider1').value;
You can also simplify your function sliderMove function:
function sliderMove() {
document.getElementById('num').textContent = document.getElementById('slider1').value;
}