This question already has answers here:
Javascript's .includes function not working correctly with array of objects [duplicate]
(2 answers)
How to determine if Javascript array contains an object with an attribute that equals a given value?
(27 answers)
Closed 4 months ago.
I'm trying to make an online library arrary that gets inputs for the value of a "book" object from a user form.
The problem is I made an if function to check if the currently submitted inputs match an already existing "book" object. Yet the function passes every input I make no matter if it's exactly the same.
Here is the Js
const submit = document.getElementById("submit");
const cardbox = document.getElementById("cardBox");
class Library {
constructor() {
this.books = [];
}
}
const myLibrary = new Library();
class Book {
constructor(title, author, pageCount, haveRead) {
this.title = title;
this.author = author;
this.pageCount = pageCount;
this.haveRead = haveRead;
}
}
function getBook() {
const book = new Book();
book.title = document.getElementById('title').value
book.author = document.getElementById('author').value
book.pageCount = document.getElementById('pageCount').value
book.haveRead = document.getElementById('haveRead').checked
function addBook() {
if (!myLibrary.books.includes(book)) {
myLibrary.books.push(book);
return makeCard(book);
}
else {
alert("Error: This book is already in library, pls reload and try again");
stop();
}
}
function makeCard() {
const card = document.createElement("div");
const titleCard = document.createElement("p");
const authorCard = document.createElement("p");
const pageCountCard = document.createElement("p");
titleCard.textContent = "Title: " + book.title;
authorCard.textContent = "Author: " + book.author;
pageCountCard.textContent = "Page Count: " + book.pageCount;
card.style.backgroundColor = "red";
card.style.fontSize = "20px"
cardbox.style.display = "flex"
card.appendChild(titleCard);
card.appendChild(authorCard);
card.appendChild(pageCountCard);
cardbox.appendChild(card);
return card;
}
addBook(book);
return book;
}
submit.addEventListener("click", function() {
getBook();
})
<!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="styles.css">
</head>
<body>
<div id="entry">
<form action="#" method="post">
<label for="title">Book title:</label>
<input type="text" id="title" name="book title" placeholder="insert book title here"><br>
<label for="author">Author:</label>
<input type="text" id="author" name="book author" placeholder="insert book author here"><br>
<label for="pageCount">How many pages is it?</label>
<input type="text" id="pageCount" name="pageCount" placeholder="insert page count here"><br>
<label for="read">Have you read already?</label>
<input type="checkbox" id="haveRead" name="read" placeholder="insert read status here">
</form>
<button type="submit" id="submit">Submit</button>
<div id="cardBox"></div>
</div>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
And there is the HTML for good measure. What am I missing here?
Related
e.g. if a user submits "tacos" twice, instead of having two lines, each containing "tacos", I want to have one line with "tacos x 2". Question 2 - is it possible to create a variable that selects every item in an array except another variable? e.g.
for (let i = 0; i < items.length; i++)
{let j = !i;
}
(I am aware the above code is incorrect, I included it only to illustrate my question)
Thank you in advance.
// key function out of context
if (!items.includes(item.text)) {
items.push(item);
} else {
items.item.number =+1
}
//entire html file with script including key function in context
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocalStorage</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>
<form class="add-items" autocomplete="off">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">
</form>
<button type="reset" value="reset"">clear all</button>
<button class="select">Select all</button>
</div>
<script>
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const selectAll = document.querySelector('.select');
const items = [];
const mySet = new Set();
const userInput = document.querySelector('[type="text"]');
// add items to list
// populate list with html
function add(e) {
e.preventDefault();
console.dir(e.currentTarget)
const text = e.currentTarget.item.value;
const item = {
text,
done:false,
number: 1,
};
console.dir(item)
if (!items.includes(item.text)) {
items.push(item);
} else {
items.item.number =+1
}
e.currentTarget.reset();
itemsList.dispatchEvent(new CustomEvent('itemsUpdated'))
}
function displayItems(item, i) {
const html = items.map((item, i) => `
<li>
<input type="checkbox">
<label name="${item}" id="${i}"><strong>${item.text}</strong> x${item.number} </label>
</li>`).join('');
itemsList.innerHTML = html;
};
addItems.addEventListener('submit', add)
itemsList.addEventListener('itemsUpdated', displayItems)
</script>
</body>
</html>
The problem lies with how you're checking if your item object is in the items array.
Since the elements of your array are objects, you would need to modify that checkup - includes and indexOf won't work.
What you would need to do is:
let indx = items.findIndex(element => element.text === item.text);
array.findIndex will let you find an element within an array which satisfies the given condition. In this case, you want to find a specific product by name. That's why we're doing the element.text === item.text comparison.
Check the updated example below, to see it in action.
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const selectAll = document.querySelector('.select');
const items = [];
const mySet = new Set();
const userInput = document.querySelector('[type="text"]');
// add items to list
// populate list with html
function add(e) {
e.preventDefault();
const text = e.currentTarget.item.value;
const item = {
text,
done:false,
number: 1,
};
/* these are the key changes */
let indx = items.findIndex(element => element.text === item.text);
if (indx < 0) {
items.push(item);
} else {
items[indx].number += 1;
}
/* */
e.currentTarget.reset();
itemsList.dispatchEvent(new CustomEvent('itemsUpdated'))
}
function displayItems(item, i) {
const html = items.map((item, i) => `
<li>
<input type="checkbox">
<label name="${item}" id="${i}"><strong>${item.text}</strong> x${item.number}</label>
</li>
`).join('');
itemsList.innerHTML = html;
};
addItems.addEventListener('submit', add)
itemsList.addEventListener('itemsUpdated', displayItems)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocalStorage</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>
<form class="add-items" autocomplete="off">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">
</form>
<button type="reset" value="reset">clear all</button>
<button class="select">Select all</button>
</div>
</body>
</html>
EDIT There were also minor syntax error edits:
in your original code, your reset button had this as its value - value="reset"". I've removed the extra quote.
your initial incrementing of item.number was also erroneous - instead of items.item.number =+1 it should have been (as it is now) items[indx].number += 1. Note that it's += and not =+.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 days ago.
Improve this question
I am new to javascript. I am working on a login form with CryptoJS. I have three functions in total. They are onsubmit function, checkLogin function and encrytion function. I have to use the onsubmit function to call the checkLogin function to validate user input but I don't know how to do so. Besides, I have to use the encrytion function to turn user input to another string, then use the checkLogin function to call the encryption function and get the string. The checkLogin function and encryption function should not directly access DOM. Finally both functions will be used for Jasmine testing but I don't need to do it right now. I just want to make my form works normally. I don't know how to exactly modify my onsubmit function and checkLogin function to make it works.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Login Page</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="script.js"></script>
<script src="Jasmine/lib/md5.js"></script>
</head>
<body>
<header>
<h1>Login Page</h1>
</header>
<section id="form" class="form">
<form name="submitForm" action="#" method="POST">
<fieldset class="form__field">
<legend>User Authentication</legend>
<p><label for="in_username" class="form__username" >Username:</label>
<input type="text" name="username" id="in_username"/></p>
<p><label for="in_password" class="form__password">Password:</label>
<input type="password" name="password" id="in_password"/></p>
<input type="submit" value="Log in" class="form__submit" />
</fieldset>
</form>
</section>
<!-- output message -->
<section id="output" class="output">
</section>
</body>
</html>
Encryption function is confirmed to be ok.
function md5Encrypt(stringIn) {
"use strict";
var md5string = new CryptoJS.MD5(stringIn);
return md5string.toString();
}
What I want to do is to output the result in the same page and this is my current code.
How to use checkLogin function to call encryption function and return true when username is abc and password is 123123? After I output a variable, how do I use the onsubmit function to take the variable? Thank you!
window.onload = function () {
"use strict";
var myLogin = document.forms.submitForm;
var myMessage = document.getElementById("output");
myMessage.classList.add("displaynone");
myLogin.onsubmit = processForm;
function processForm() {
var inName = document.getElementById("in_username");
var inPassword = document.getElementById("in_password");
checkLogin(inName, inPassword);
myMessage.classList.add("displayblock");
myMessage.innerHTML = output;
return false;
}
function checkLogin(inName, inPassword){
var myName = "abc";
var myPassword = "123123";
var output = "";
var noName = "No username entered";
var noPassword = "No password entered"
var valid = "Welcome back!";
var invalid = "Invalid Username or Password";
if(inName.value(myName) && inPassword.value(myPassword)){
output = valid;
} else if (inName.value("")){
output = noName;
} else if(inPassword.value("")){
output = noPassword;
} else {
output = invalid;
}
return output;
}
};
Sorry for the little explanation. So i have already done my chrome extension and i already have a save data in my localstorage which is FirstName. so now the getElementById is the one suppose to web scape my current page that i am on to fill up the form when i click START which is button1 Hopefully these clear things
i have also provided my index.html where if i click start it should execute injector.js
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<style>
html,
body {
height: 200px;
width: 400px;
}
</style>
</head>
<body>
<h1>Adidas ACO</h1>
<h2>Select your choice</h2>
<button>Go for Setup</button>
<button id="buttonstart"><script src="injector.js"></script>
</script>START</button>
<!-- <br>
<br>
<label for="Title">Title</label>
<input type="text" id="firstnametitle" name="title" size="50" value=""/> -->
<!--<script scr="injector.js"></script>-->
<!--<button onclick="fillforms(fillup)">Start</button>-->
</body>
</html>
injector.js
// Get my button and localstorage data
var button1 = document.getElementById("buttonstart");
var firstName = localStorage.getItem('First Name');
var lastName = localStorage.getItem('Last Name');
var address1 = localStorage.getItem('Address 1');
var address2 = localStorage.getItem('Address 2');
var email = localStorage.getItem('Email');
var phoneNumber = localStorage.getItem('Phone Number');
/// When button is click, it will webscape and fill up
button1.onclick = function(){
var firstName = localStorage.getItem('First Name');
var field1 = document.getElementsByClassName("shippingAddress-firstName");
fillField(field1, firstName);
console.log(field1)
console.log(firstName)
}
function fillField(field1, value){
if(field1){
field1.value = value;
}
}
Picture to my console values
Declare the variables firstname and field1 at the start of the file.You have to do it because in your code you can only use those variables inside the button1.onclick function since you have declared them there.
Here is my code!!!
I have one input field And
One of the array
I'm matching Input field entered value with arrray's list.
Prob : Unable to match capital value with array's list.
e.g if user enter one10 value so this one should be match or if user enter ONE10 in capital letter then this value should be match too.
function myFunctiontwo(){
var good = [
"one10",
"two10",
"three10"
];
var a = document.getElementById("code").value.split(' ');
var foundPresent = a.some(elem => good.indexOf(elem) > -1);
if(foundPresent === true){
alert("correct");
}else {
alert("wrong");
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<input name="code" id="code" placeholder="code" required>
<button id="submit" id="sumbit" onclick="myFunctiontwo()">GO</button>
</body>
</html>
You can use the toLowerCase() method here. Assuming all your elements in good are lowercase you can just do elem.toLowerCase()
var foundPresent = a.some(elem => good.indexOf(elem.toLowerCase()) > -1);
When not you also should convert the array elements toLowerCase()
good = good.map(x => x.toLowerCase());
In the snippet below I added the element "FOur20" to the array.
As you can see four20 will give you the message correct
function myFunctiontwo(){
var good = [
"one10",
"two10",
"three10",
"FOur20"
];
good = good.map(x => x.toLowerCase());
console.log(good);
var a = document.getElementById("code").value.split(' ');
var foundPresent = a.some(elem => good.indexOf(elem.toLowerCase()) > -1);
if(foundPresent === true){
alert("correct");
}else {
alert("wrong");
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<input name="code" id="code" placeholder="code" required>
<button id="submit" id="sumbit" onclick="myFunctiontwo()">GO</button>
</body>
</html>
Let's first make sure the good array is all lowercase:
good = good.map(word => word.toLowerCase());
Then, you can always convert to lowercase and check if it exists in the good array
var foundPresent = a.some(elem => good.contains(elem.toLowerCase()));
if(foundPresent === true) {
alert("correct");
}
else {
alert("wrong");
}
I'm currently working on an application that counts the number of books as well as putting the book numbers from lowest to greatest. I have a user input box and I'm trying to figure out how to clear it after the user puts a book number in. I've tried $('#input').val(' '); However, this doesn't allow me to put in numbers of two digits like "23".
My Code:
// global variables
var array = new Array();
$(document).ready(function() {
// on enter submit values
$(document).on('keypress', function(e) {
if (e.which == 13) {
// grabs user's input
var $input = $('#input').val();
// stores in the array and sorts from lowest to highest
array.push(parseInt($input));
array.sort(function(a, b) {
return a - b
});
// displays user's inputs
$('#output').text(array.join(", "));
}
// to prevent refresh on enter for forms
$(function() {
$("form").submit(function() {
return false;
});
});
// display values in js console
console.log(array);
// counter for number of books
$('#numOfBooks').text(array.length);
// clears input field
// $('#input').prop("selected", false);
});
// on click submit values
$('#btn').on('click', function() {
// grabs user's input
var $input = $('#input').val();
// stores in the array and sorts from lowest to highest
array.push(parseInt($input));
array.sort(function(a, b) {
return a - b
});
// displays user's inputs
$('#output').text(array.join(", "));
// display values in js console
console.log(array);
// counter for number of books
$('#numOfBooks').text(array.length);
// clears input field
// $('#input').prop("selected", false);
});
// reset
$("#resetButton").on("click", function() {
setTimeout(function() {
location.reload();
}, 300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="header"> Sort Your Books </h1>
<form id="wrapper">
<span> Enter Book Numbers: </span> <input type="text" id="input" placeholder="Enter a Number...">
<input type="button" id="btn" value="Enter">
</form>
<div class="flex_NumOfBooks">
<h2 id="header_NumOfBooks"> Number of Books: </h2>
<div id="numOfBooks"> </div>
</div>
<div id="wrapper1">
<h2 id="header-books"> Book Numbers: </h2>
<div id="output"></div>
</div>
<button id="resetButton"> Reset </button>
please don't use jq. :)
<!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">
<title>App</title>
</head>
<body>
<div class="userGetBookID">
<div class="inputGroup">
<label>Input book id:</label>
<input type="text" class="bookID" placeholder="e.g. esbn-123-abfgd">
<input type="button" class="addBookByID" value="add">
</div>
</div>
<div class="books">
<div class="listGroup">
<p class="books__list-header">list:</p>
<div class="books__list"></div>
</div>
<div class="amountGroup">
<p class="books__amount-header"> amount: </p>
<p class="books__amount"> 0 </p>
</div>
<button class="listReset"> reset </button>
</div>
<script>
const userInput = document.querySelector('.bookID')
const userList = document.querySelector('.books__list')
const userSubmit = document.querySelector('.addBookByID')
const userReset = document.querySelector('.listReset')
const userListAmount = document.querySelector('.books__amount')
const getUserInput = () => userInput.value
const getUserList = () => userList.innerText.split(', ')
const resetUserInput = () => userInput.value = ""
const resetUserList = () => userList.innerText = ""
const addToUserList = (value) => getUserList()[0] == ""
? userList.innerText += value
: userList.innerText += (', ' + value)
const getUserListLength = () => getUserList()[0] == ""
? 0
: getUserList().length
const updateUserListAmount = () => userListAmount.innerText = getUserListLength()
userSubmit.addEventListener('click', (event) => {
addToUserList(getUserInput())
resetUserInput()
updateUserListAmount()
event.preventDefault()
})
userReset.addEventListener('click', (event) => {
resetUserList()
updateUserListAmount()
})
</script>
</body>
</html>