I'm trying to use the value that each book has on its "status" and make the function "changeStatus()" run but "book.status" is defined inside a function, how can I get it? or is there any other way i can change the button behavior on click? I tried using a querySelector but it only allows me to click one button per refresh
let books = [];
const $name = document.querySelector("#name");
const $author = document.querySelector("#author");
const $status = document.querySelector("#status");
const $pages = document.querySelector("#pages");
const $tableBody = document.querySelector("#book-table-body");
function addBookToTable() {
// checkLocalStorage();
$tableBody.innerHTML = "";
books.forEach((book) => {
const htmlBook = `
<tr>
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.pages}</td>
<td><button class="status-button" onclick="changeStatus()">${book.status}</button></td>
<td><button class="delete">delete</button></td>
</tr>
`;
$tableBody.insertAdjacentHTML("afterbegin", htmlBook);
});
}
function changeStatus(){
}
const addBook = (event) => {
event.preventDefault();
let book = {
title: $("#title").val(),
author: $("#author").val(),
pages: $("#pages").val(),
status: $("#status").val(),
};
const cb = document.querySelector("#status");
if (cb.checked === true) {
book.status = "read";
} else {
book.status = "not read";
}
books.push(book);
document.forms[0].reset();
// Update DOM
addBookToTable(book);
const deleteBtn = document.querySelector(".delete");
deleteBtn.addEventListener("click", function deleteBook(){
books.splice(books.indexOf(book), 1);
addBookToTable(book);
})
// const myBtn = document.querySelector(".status-button");
// myBtn.addEventListener('click', function changeStatus(){
// if (book.status === "read"){
// myBtn.innerHTML="not read"
// book.status = "not read"
// }
// else if(book.status === "not read"){
// myBtn.innerHTML = "read";
// book.status = "read"
// }
// }
// );
localStorage.setItem("myMangaList", JSON.stringify(books));
};
function popForm() {
$("#popup").removeClass("hide");
}
function minimizeForm(){
$("#popup").addClass("hide");
}
function hideForm() {
$("#popup").addClass("hide");
$("#main-page").removeClass("hide");
}
function toggle() {
$("#main-page").addClass("hide");
}
* {
font-family: 'Lato', sans-serif;
text-align: center;
/* background-image: url(./images/image.jpg);
background-position: bottom;
background-size: cover; */
}
.hide {
display: none;
}
.hide-form {
background-color: transparent;
color: white;
border: none;
cursor: pointer;
font-size: 1.5rem;
margin-top: 20px;
margin-right: 15px;
position: absolute;
top: 0;
right: 0;
}
h1 {
font-size: 2.5rem;
font-weight: 900;
font-family: 'Work Sans', sans-serif;
}
h1 span {
color: #48abe0;
}
table {
border-collapse: collapse;
width: 100%;
}
td,
th {
/* border: 1px solid #dddddd; */
text-align: center;
padding: 8px;
}
#main-page {
margin-right: 80px;
margin-left: 80px;
}
#addBook {
border-radius: 70%;
background-color: #48abe0;
color: white;
border: none;
padding: 5px;
font-size: 31px;
height: 65px;
width: 65px;
box-shadow: 0 2px 4px darkslategray;
cursor: pointer;
transition: all 0.2s ease;
position: fixed;
bottom: 25px;
right: 25px;
}
#popup {
/* display: flex; */
justify-content: center;
align-items: center;
flex-direction: column;
gap: 30px;
padding-top: 50px;
padding-bottom: 50px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
background: #48abe0;
border-radius: 10px;
}
#popup input {
width: 80%;
padding: 15px;
margin-top: 25px;
border: 1px solid;
border-radius: 5px;
outline: none;
color: white;
font-weight: bold;
font-size: 1em;
background: #48abe0;
}
.status-box {
margin-top: 25px;
}
<!DOCTYPE html>
<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">
<!-- Stylesheet -->
<link rel="stylesheet" href="style.css">
<!-- fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Edu+NSW+ACT+Foundation:wght#500&family=Edu+QLD+Beginner:wght#400;600;700&family=Edu+TAS+Beginner:wght#700&family=Josefin+Sans:wght#300&family=Lato&family=Montserrat:wght#100;600&family=Mouse+Memoirs&family=Poppins:ital,wght#0,500;1,200&family=Quicksand:wght#300&family=Ubuntu:wght#300&family=Work+Sans:wght#200&display=swap"
rel="stylesheet">
<title>Library</title>
</head>
<body>
<h1>My <span>Manga</span> Library</h1>
<div id="popup" class="hide">
<form>
<button class="hide-form" onclick=" minimizeForm()">X</button>
<!-- <label for="title">Manga Title:</label> -->
<input type="text" id="title" placeholder="Title eg: One Piece"> <br>
<!-- <label for="author">Author:</label> -->
<input type="text" id="author" placeholder="Author eg: Eichiro Oda"><br>
<!-- <label for="pages">Pages:</label> -->
<input type="text" id="pages" placeholder="Pages eg: 2000"><br>
<div class="status-box">
<label for="status">Read the book</label>
<input type="checkbox" id="status" name="status" value="">
</div>
<button type="submit" id="submit" onclick="addBook(event); hideForm()">Submit</button>
</form>
</div>
<!-- onclick="addBook() -->
<div id="main-page">
<h1>list</h1>
<div id="books-grid">
<table id="di-books">
<tr>
<th>Name</th>
<th>Author</th>
<th>Pages</th>
<th>Status</th>
<th></th>
</tr>
<tbody id="book-table-body"></tbody>
</table>
</div>
<button id="addBook" onclick="popForm(); toggle()">+</button>
</div>
<!-- JQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="app.js"></script>
</body>
</html>
If you want to update the status of a book, you need a way to identify each book uniquely. Although it is possible to do this based on e.g. title or author, the reality is that those fields are not guaranteed to be unique.
Typically, you'd use the Id number of a database entry, but since you're using mock data that isn't realy an option here. We could e.g. use a UUID though:
let book = {
title: $("#title").val(),
author: $("#author").val(),
pages: $("#pages").val(),
status: $("#status").val(),
id: self.crypto.randomUUID() //Warning: might only work with HTTPS sites. Implement your own unique id in any way you please.
};
Now we have a unique id, we can use it to couple each status button with a unique book entry. Lets adjust the HTML:
const htmlBook = `
<tr>
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.pages}</td>
<td><button class="status-button" onclick="changeStatus('${book.id}')">${book.status}</button></td>
<td><button class="delete">delete</button></td>
</tr>
`;
and lets write the update function:
function changeStatus(id){
//step 1: find our book with the matching unique id
let book = books.filter(book => book.id === id)[0];
//Step 2: update the book its status
if (book.status === "read"){
book.status = "not read";
}
else if(book.status === "not read"){
book.status = "read"
}
//Step 3: update our table with the new data.
addBookToTable();
};
And voila, we're able to switch the status of any book!
I tried to stick as close to your code as possible so you'd better understand it, but a lot more improvements can be implemented, such as event listeners instead of explicitly calling the changeStatus function, but I'll leave that as an exercise to you.
Full working example:
codepen
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 am trying to make a simple To-Do like application. I want the "Tasks" which I add to remain even after closing the window or at least after refreshing. I tried to achieve that using MongoDB but I couldn't.
I think a simpler way to achieve this is by using arrays but I am not able to understand how to do that.
Please suggest me some way to achieve the above results....
let div = document.getElementById('tasks');
let add = document.getElementById('add');
let newTask = document.getElementById('newTask');
let c = 0;
add.addEventListener("click", function () {
let cbox = document.createElement("input");
let d = document.createElement("div");
let newt = newTask.value;
newTask.value = null;
cbox.type = "checkbox";
cbox.id = "check";
div.append(d);
d.id = "nd";
d.append(cbox);
d.append(newt);
c += 1;
if (c === 12) {
add.disabled = true;
newTask.value = "Stack Overflow";
}
});
/* body {
background-color: #42f5f5
} */
.card {
margin: 0 auto;
float: none;
/* margin-bottom: 10px; */
/* border: none; */
/* background-color: rgb(248, 179, 88); */
}
.container {
margin-top: 2.5rem;
}
#title {
width: 200px;
border: none;
font-size: larger;
font-weight: bold;
}
#newTask {
width: 200px;
}
#add {
margin-top: 1rem;
}
#newTask {
margin-top: 1rem;
}
#plus {
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
}
#nd {
font-size: 20px;
margin-top: 5px;
margin-bottom: 10px;
}
#check {
margin-left: 20px;
height: 15px;
width: 15px;
margin-right: 10px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="ToDo.css" rel="stylesheet">
<title>To-Do</title>
</head>
<body>
<div class="container">
<div class="card" style="width: 35rem;height: 42rem;">
<div class="card-body">
<p style="font-size: 2rem;font-weight: bold;">
<input type="text" class="form-control" id="title" placeholder="Title">
</p>
<p id="main">
<div id="tasks">
</div>
<form class="form-inline">
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" id="newTask" autocomplete="off"
placeholder="Enter new task">
</div>
<button type="button" class="btn btn-primary mb-2" id="add">Add Task</button>
</form>
</p>
</div>
</div>
</div>
<script src="ToDo.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.12.9/dist/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
You can use localStorage to save data in browser storage.
here's link to documentation for localStorage .
//to set data in local storage
localStorage.setItem('myCat', 'Tom')
//to get data from localStorage
const cat = localStorage.getItem('myCat');
//to remove data from localStorage
localStorage.removeItem('myCat');
//for object you can stringify them
var myObj = [{name:"test", time:"Date 2017-02-03T08:38:04.449Z"}];
localStorage.setItem('item', JSON.stringify(myObj));
//Then when you want to retrieve data, you need to parse the string to object again.
var getObj = JSON.parse(localStorage.getItem('item'));
I'm working on my first ever JavaScript project (a palindrome checker) and I'm kind of getting stuck. I've learned about localStorage() but I can't seem to implement it in my own project. It'd be awesome if someone could point me in the right direction, or write pseudo code as to what I should do to get it to work. I really want to solve it myself, but a little help is much needed here. Thanks :). My JavaScript code (and HTML and CSS for reference:
Edit: I want to show the results (each on a separate line) on the screen using localStorage() and use it again to enable the user to delete the results when clicking on the button.
const checkBtn = document.getElementById("check-word");
const clearBtn = document.getElementById("clear-history");
const outputField = document.getElementById("word-checked");
let array = [];
checkBtn.addEventListener("click", () => {
const str = document.getElementById("input").value;
array = [...array, str];
console.log(array);
palindrome(str);
renderResult();
function palindrome(str) {
const lettersOnly = str.toLowerCase().match(/[a-z0-9]/g);
return lettersOnly.join("") === lettersOnly.reverse().join("");
}
renderResult();
function renderResult() {
if (palindrome(str) === true) {
outputMessage = `︎✔︎ '${str}' is a palindrome!`
} else {
outputMessage = `𐄂 '${str}' is not a palindrome!`
}
outputField.textContent = outputMessage;
}
document.getElementById("input").value = ""; // clear input field after clicking on checkBtn
})
// clearBtn.addEventListener("click", () => {
// localStorage.clear();
// array = [];
// // render again!
// })
* {
background-color: #121212;
font-size: 16px;
margin: 0;
padding: 0;
}
h1 {
font-family: "VT323", monospace;
font-size: 5rem;
color: #CE1212;
text-align: center;
margin-top: 50px;
}
.container {
font-family: "Nanum Gothic Coding", monospace;
color: white;
width: 75%;
height: 62.5vh;
margin: 25px auto 25px auto;
/* border: 2.5px solid; */
border-color: white;
padding: 15px;
}
.input {
margin-left: 25px;
}
.input-field {
margin-left: 25px;
margin-top: 12.5px;
padding: 7.5px;
font-family: "Nanum Gothic Coding", monospace;
color: white;
border: 1px solid;
}
.input-field:focus::placeholder {
color: transparent;
}
.check-word, .clear-history {
padding: 7.5px;
font-family: "Nanum Gothic Coding", monospace;
color: white;
border: 1px solid;
border-color: white;
cursor: pointer;
}
.check-word:hover, .clear-history:hover {
color: #CE1212;
}
.child-1 {
margin-top: 50px;
margin-left: 25px;
/* border: 1px solid; */
padding: 15px;
}
#word-checked {
margin-top: 15px;
}
.footer {
font-family: "Nanum Gothic coding", monospace;
color: white;
text-align: center;
margin-bottom: 25px;
}
a:link, a:visited {
color: white;
text-decoration: none;
}
a:hover, a:active {
color: #CE1212;
text-decoration: underline;
}
/*
top, right, bottom, left
*/
<!DOCTYPE html>
<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">
<title>Palindrome Checker</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nanum+Gothic+Coding&family=VT323&display=swap" rel="stylesheet">
<link rel="stylesheet" href="index.css">
</head>
<body>
<main>
<h1>🌮 Palindrome Checker 🐱</h1>
<div class="container">
<label for="input" class="input">Type a word or phrase</label>
<br>
<input type="text" name="input" class="input-field" id="input" placeholder="Type something...">
<button type="button" class="check-word" id="check-word">Check word</button>
<button type="button" class="clear-history" id="clear-history">Clear history</button>
<div class="child-1">
<p id="word-checked">Results will be shown here!</p>
</div>
</div>
</main>
<footer class="footer">
<p>Built by Yin Chu</p>
</footer>
<script src="index.js"></script>
</body>
</html>
It's really easy. (At least much easier than cookies)
localStorage.setItem('key', 'value'); // to store data
var myData = localStorage.getItem('key') // to get data
localStorage.removeItem('key') // to remove one data
localStorage.clear() // to remove all data
Replace key and value with the data key and the data to store respectively.
So I have created a table using HTML which contains data about the students like name,degree,profession. So to find the information about a particular student there is search bar through which you can find the information about a specific student by just typing the name of that student.
So I am successfully able to retrieve the row of information about that specific student. But if that student is not mentioned in the table I have to show the user a message "Result not found."
I have tried and put the error Message also, but the 1st problem that I am facing is that even after typing the first letter of the student name the error message pops-up , and 2nd problem is that even after writing the right Name which is mentioned in the table still the error message pops-up.So what I want to achieve is that the error message should only pop-up only if the Name is not mentioned in the table.
let inputValue;
let input = document.getElementById("myInput");
// function that will work when event happens
const search = (e) => {
inputValue = input.value.toUpperCase();
// console.log(inputValue);
let tableEl = document.getElementsByTagName("table");
let tr = tableEl[0].getElementsByTagName("tr");
// let th = document.getElementsByTagName("th");
let th = document.getElementById("header")
let no_result = document.getElementById("no_result");
let container = document.querySelector(".container"); // used to access hidden class
for (let i = 1; i < tr.length; i++) {
let dataValue = tr[i].getElementsByTagName("td")[0].textContent.toUpperCase(); // Fetching each rows name value
if (dataValue.includes(inputValue)) {
console.log(inputValue);
tr[i].style.display = ""; // Display whole rows details
}
else if(inputValue.textContent !== dataValue){
no_result.style.display="block"
tr[i].style.display = "none";
}
}
};
input.addEventListener("keyup", function (e) {
search(e);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
width: 100vw;
height: 100vh;
/* display: grid;
place-items: center; */
/* margin: 0 auto; */
/* background-color: black; */
text-align: center;
display: flex;
flex-direction: column;
}
table,
th,
td {
background-color: rgb(235, 139, 215);
border: 1px solid black;
border-collapse: collapse;
font-size: 20px;
text-align: center;
padding: 20px;
margin: 30px auto;
}
th {
font-family: "Courier New", Courier, monospace;
}
tr,
td {
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
}
input {
width: 400px;
padding: 20px;
font-size: 20px;
margin-top: 50px;
border: 2px solid black;
outline: none;
}
input:focus {
outline: 2px solid gray;
}
.hidden {
display: none;
}
#no_result{
width: 200px;
height: 50px;
align-self: center;
display: none;
}
<!DOCTYPE html>
<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" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="main">
<div>
<input
type="text"
placeholder="Enter your name"
id="myInput"
/>
</div>
<table id="myTable">
<span id="no_result">
<h2>No result found!!</h2>
</span>
<tr id="header">
<th>Name</th>
<th>Degree</th>
<th>Profession</th>
</tr>
<tr>
<td>John</td>
<td>BSC-IT</td>
<td>Full stack developer</td>
</tr>
<tr>
<td>Tom</td>
<td>BSC-IT</td>
<td>Data Scientist</td>
</tr>
<tr>
<td>Jerry</td>
<td>Graphic Design</td>
<td>Graphic Designer and animation</td>
</tr>
<tr>
<td>James</td>
<td>MCA</td>
<td>Project Manager</td>
</tr>
<tr>
<td>Roger</td>
<td>BSC-IT</td>
<td>Teacher</td>
</tr>
</table>
<div id="error4">
</div>
<!-- <div class="container hidden">
<h1 ">Not found</h1>
</div> -->
</div>
<script src="script.js"></script>
</body>
</html>
Below I am mentioning the important parts of my code regarding my problem which are also mentioned in the above snippet
HTML
<span id="no_result">
<h2>No result found!!</h2>
</span>
CSS
#no_result{
width: 200px;
height: 50px;
align-self: center;
display: none;
}
JAVASCRIPT
Here I have displayed that errorMessage.
else if(inputValue.textContent !== dataValue){
no_result.style.display="block"
tr[i].style.display = "none";
Help Would be appreciated!!
Here is a simplified script
Note I added thead and tbody and use hidden instead of display
let inputValue;
let input = document.getElementById("myInput");
// function that will work when event happens
const search = (e) => {
inputValue = input.value.toUpperCase();
// console.log(inputValue);
let tableEl = document.querySelector("table tbody");
let tr = tableEl.querySelectorAll("tr");
// let th = document.getElementsByTagName("th");
let th = document.getElementById("header")
let no_result = document.getElementById("no_result");
let container = document.querySelector(".container"); // used to access hidden class
tr.forEach(tr => { // Fetching each rows name value
let dataValue = tr.querySelector("td").textContent.toUpperCase();
tr.hidden = !dataValue.includes(inputValue)
})
no_result.hidden = tableEl.querySelectorAll("tr[hidden]").length != tr.length;
};
input.addEventListener("keyup", function(e) {
search(e);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
width: 100vw;
height: 100vh;
/* display: grid;
place-items: center; */
/* margin: 0 auto; */
/* background-color: black; */
text-align: center;
display: flex;
flex-direction: column;
}
table,
th,
td {
background-color: rgb(235, 139, 215);
border: 1px solid black;
border-collapse: collapse;
font-size: 20px;
text-align: center;
padding: 20px;
margin: 30px auto;
}
th {
font-family: "Courier New", Courier, monospace;
}
tr,
td {
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande", "Lucida Sans Unicode", Geneva, Verdana, sans-serif;
}
input {
width: 400px;
padding: 20px;
font-size: 20px;
margin-top: 50px;
border: 2px solid black;
outline: none;
}
input:focus {
outline: 2px solid gray;
}
#no_result {
width: 200px;
height: 50px;
align-self: center;
}
<!DOCTYPE html>
<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" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="main">
<div>
<input type="text" placeholder="Enter your name" id="myInput" autocomplete="off" />
</div>
<table id="myTable">
<thead>
<tr id="header">
<th>Name</th>
<th>Degree</th>
<th>Profession</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>BSC-IT</td>
<td>Full stack developer</td>
</tr>
<tr>
<td>Tom</td>
<td>BSC-IT</td>
<td>Data Scientist</td>
</tr>
<tr>
<td>Jerry</td>
<td>Graphic Design</td>
<td>Graphic Designer and animation</td>
</tr>
<tr>
<td>James</td>
<td>MCA</td>
<td>Project Manager</td>
</tr>
<tr>
<td>Roger</td>
<td>BSC-IT</td>
<td>Teacher</td>
</tr>
</tbody>
</table><span id="no_result" hidden>
<h2>No result found!!</h2>
</span>
<div id="error4">
</div>
<!-- <div class="container hidden">
<h1 ">Not found</h1>
</div> -->
</div>
<script src="script.js"></script>
</body>
</html>
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;
}