text input in html to check for keywords using javascript and return a score - javascript

I have the following html page that seeks to check for keywords in text input and return a score depending on how many keywords are entered. For instance, if two keywords are returned, the score would be 2, and if the answer contains no keywords, then a score of 0 would be returned.
In the example below two accepted keywords have been used (e.g. good and eternal) and therefore the user would receive a score of 2.
I've made an attempt (a beginner to JS) but would appreciate some help.
UPDATE: The javascript i have used nearly works (to search for multiple keywords) but doesnt display the showscore variable correctly each time.
This is what I have so far:
<script>
document.getElementById('longanswer').addEventListener('input', function(e){
let keyword = e.target.value;
document.getElementById('greeting').innerHTML = "Just write this";
});
function displayScore() {
var showscore = 0;
var answer = document.getElementById('longanswer').value;
var keyword1="eternal";
var keyword2="good";
var keyword3="true";
if (answer.indexOf(keyword1)!=-1){
showscore=showscore+1
document.getElementById("displayscore").innerHTML = showscore;
} else if (answer.indexOf(keyword1)!=-1 & answer.indexOf(keyword2)!=-1){
showscore=showscore+2
} else if (answer.indexOf(keyword1)!=-1 & answer.indexOf(keyword2)!=-1 & answer.indexOf(keyword3)!=-1){
showscore=showscore+3
} else {
showscore=0
}
document.getElementById("displayscore").innerHTML = showscore;
}
</script>
The interface is below:
Whole code that can be easily re-created below:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>Long Answer Question & Answers</title>
</head>
<body>
<form>
<h1> Q and A </h1>
<div class="form-group">
<label for="longanswer">What is the meaning of life?:</label><br>
<textarea rows="4" cols="100" id="longanswer">
</textarea>
<br>
<button onclick="displayScore()" type="button" class="btn btn-success">Submit</button>
</div>
</form>
<div class="card border-primary mb-3" style="max-width: 18rem;">
<div class="card-header">Score</div>
<div class="card-body text-primary">
<h5 class="card-title">Generating a score for your answer</h5>
<p class="card-text" id="displayscore">Once you've clicked submit we will display your score for this answer here.</p>
</div>
</div>
<script>
document.getElementById('longanswer').addEventListener('input', function(e){
let keyword = e.target.value;
document.getElementById('greeting').innerHTML = "Just write this";
});
function displayScore() {
var showscore;
var answer = document.getElementById('longanswer').value;
var keyword1="eternal";
var keyword2="good";
if (answer.indexOf(keyword1)!=-1)
{
showscore="found"
}
document.getElementById("displayscore").innerHTML = showscore;
}
</script>

To have it more dynamic, I'd use a new RegExp in which you can check the text; the length of match' result will be the score
let keywords = new RegExp("(" + ["foo", "bar", "baz"].join('|') + ")", 'gi');
document.getElementById('btn').addEventListener('click', e => {
document.getElementById('score').innerHTML =
document.getElementById('foo').value.match(keywords).length;
});
<textarea id="foo"></textarea>
<button id="btn">
Check
</button>
<div id="score">
</div>

Related

input field won't clear up

I can't clear up my input field even tho i followed a tutorial step by step , i'm making this to do list and I want the input field to be clear anytime i submit a new to do . so what is wrong with my code ?
ps : i tried to clear the cache and nothing
let addButton=document.getElementById('addButton');
let toDoContainer = document.getElementById('ToDoContainer');
let inputField = document.getElementById('text');
//event listeners
addButton.addEventListener('click',addTodo);
//functions
function addTodo(event,title){
event.preventDefault();
//create the to do
let toDoDiv = document.createElement('div');
toDoDiv.classList.add('todo');
const newToDo =document.createElement('p');
newToDo.innerHTML=inputField.value;
newToDo.classList.add('todo-item');
toDoDiv.appendChild(newToDo);
toDoContainer.appendChild(toDoDiv);
//check mark button
const completedButton = document.createElement('button');
completedButton.innerHTML="success";
completedButton.classList.add("complete-btn");
toDoDiv.appendChild(completedButton);
//check delete button
const trashButton = document.createElement('button');
trashButton.innerHTML="delete";
trashButton.classList.add("complete-btn");
toDoDiv.appendChild(trashButton);
//append todo
toDoContainer.appendChild(tododiv);
inputField.value= "";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>to do list </title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<header>
<h1>This is your to do list </h1>
<div class="input">
<input type="text" placeholder="what to do ...?" id="text">
<input type="button" value="add" id="addButton">
</div>
</header>
<div id="ToDoContainer">
</div>
</div>
<script src="./script.js"></script>
</body>
</html>
here is a screenshot
sonEtLumiere is right, you have a typo. It should be:
toDoContainer.appendChild(toDoDiv);
Your variable is called toDoDiv, you have an error in this line (penultimate line):
toDoContainer.appendChild(tododiv);
This will work:
toDoContainer.appendChild(toDoDiv);

LocalStorage removes the wrong value

I keep having the same issue again and again : When I add a task, it gets added to the localStorage correctly. But once I have multiple tasks and I click complete on a random one, sometimes it happens that the LocalStorage removes the task before it or after it. I can't figure out a way how to let it work.
let addBtn = document.getElementById("addButton");
let textInput = document.getElementById("textInput");
let mainList = document.getElementById("mainList");
let storage = JSON.parse(localStorage.getItem("toDos")) || [];
if (storage.length != 0){
for (let i=0; i<storage.length;i++){
addTask(mainList, storage[i]);
};
};
function addTask(list,task){
var newTask = document.createElement("li");
newTask.textContent=task
newTask.className="task d-flex justify-content-between list-group-item bg-primary mt-2";
addCompleteBtn(newTask);
list.appendChild(newTask);
}
function addCompleteBtn (newTask){
let completeBtn = document.createElement("button");
completeBtn.className="btn btn-success completeBtn";
completeBtn.textContent="Completed";
newTask.appendChild(completeBtn);
};
addBtn.addEventListener("click", ()=>{
if(textInput.value === ""){
alert("Error: The field is either empty or you entered more than 100 characters!");
}else{
storage.push(textInput.value);
addTask(mainList, textInput.value);
textInput.value="";
localStorage.setItem("toDos",JSON.stringify(storage));
};
});
mainList.addEventListener("click",(evt)=>{
if (evt.target.className==="btn btn-success completeBtn") {
let listItem = evt.target.parentNode;
let mainUl = listItem.parentNode;
let toBeRemoved = listItem.textContent;
storage.splice(storage.indexOf(toBeRemoved),1);
mainUl.removeChild(listItem);
localStorage.setItem("toDos",JSON.stringify(storage));
};
});
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<title>To-do-list App</title>
</head>
<body>
<div class="jumbotron bg-info">
<div class="container">
<h1 class="display-4 text-center">Task List</h1>
<p class="lead text-center">Click on the Add button to add a task</p>
</div>
</div>
<div class="container">
<div class="firstInput input-group mb-5">
<div class="input-group-prepend">
<button class="btn btn-primary" type="button" id="addButton">Add Task</button>
</div>
<input type="text" title='Enter a Task' class="form-control" id="textInput" maxlength="200">
</div>
</div>
<ul class='tasksList container' id="mainList">
</ul>
<script src="script.js"></script>
</body>
</html>
Shows all the values in the LocalStorage
Once task 2 is removed, task 3 is removed from the Storage instead
this is the specific part that causes me issues :
mainList.addEventListener("click",(evt)=>{
if (evt.target.className==="btn btn-success completeBtn") {
let listItem = evt.target.parentNode;
let mainUl = listItem.parentNode;
let toBeRemoved = listItem.textContent;
/* This is the part of code causing me issues
storage.splice(storage.indexOf(toBeRemoved),1);
*/
mainUl.removeChild(listItem);
localStorage.setItem("toDos",JSON.stringify(storage));
};
});
The problem is here let toBeRemoved = listItem.textContent;,this will return the text content of all elements inside that li. So if you add a task named 'Task 1', when you press Completed the value of toBeRemoved will be Task 1Completed since this will return the text of the button as well since your button is a child of the li.
So change let toBeRemoved = listItem.textContent; to let toBeRemoved = listItem.childNodes[0].nodeValue; and you should be fine, this will get the text of the li only.

Removing all white space from an input box, es6

I am trying to remove any white space while a user in entering something into the input box. I tried having three separate methods at first: regex to remove spaces when text is pasted, one for when the space bar is pressed, and a simple trim. NOTE: it is required that I use class to call methods. Not sure where to go from here... I appreciate the help!
(function () {
class Digit {
// when user enters keys, do not allow spaces
method2(userInput) {
console.log({userInput});
console.log("formatInput");
const input = userInput.target.value;
console.log(input.length);
if (!input.length) return;
if (userInput.which === 32) { // 32 is space key
console.log("this is a space");
userInput.value = this.method1();
}
}
method1() {
console.log("trimthis input");
return userInput.trim();
}
// when user pastes input remove spaces
method3() {
console.log("formatPaste");
const reg = new RegExp(/\s+/, "");
console.log(this.userInput);
return this.userInput.replace(reg, "");
}
}
const userInput = document.querySelector("#inputNumber");
console.log("User inputs", {userInput});
const digitObject = new Digit();
console.log(digitObject);
userInput.addEventListener("keyup", function() { digitObject.method2(); }, false);
digitObject.method3();
}());
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Numbers App</title>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,500" rel="stylesheet">
<!-- CSS -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- ASSIGNMENT: create page where user can type/save numbers only, css grid -->
<div class="wrapper">
<!-- simple form with number input and submit function, auto trim spaces -->
<form>
<div class="form">
<div>
<input class="input--number has-float-label go-bottom Digit" id="inputNumber" placeholder="Enter Number" type="text" required />
<label for="inputNumber">Input</label>
</div>
<div class="btn--group">
<input type="button" value="Post" class="btn post" title="Post">
<input type="button" value="Clear" class="btn clear" title="Clear">
</div>
</div>
</form>
<!-- saved numbers table with date submitted -->
<!---->
</div> <!-- end wrapper -->
<!-- footer -->
<!-- Javascript -->
<script src="script.js"></script>
</body>
</html>
Use the event input to capture every kind of changes and the following regexp / /g
document.getElementById('textfield').addEventListener('input', function() {
this.value = this.value.replace(/ /g, '');
});
<input id='textfield'>

Javascript - looping through data with each click

I'm fairly new to Javascript I have been playing with some data fetching for the past few days. I created this very simple program (if you can even call it that), where if you click a button, it will generate a div with a random user (using jsonplaceholder API). My issue is, that whenever the button is clicked, it gives me all 10 users at once. I'd like it to give me one user with each click instead. As I said, I am fairly new to JS so I'm not sure how to aproach this (I guess some sort of a loop would be involved?). Any sort of advice, tips or anything would be welcomed ! Thank you !
Here is my code (Using Bootstrap 4 for styling and Axios for data fetching):
const mainButton = document.getElementById('mainButton');
const targetDiv = document.getElementById("targetDiv");
mainButton.addEventListener('click', () => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(function(response) {
let ourRequest = response;
renderData(ourRequest.data);
})
.catch(function(error) {
console.log(error);
});
function renderData(data) {
var stringHTML = "";
for (i = 0; i < data.length; i++) {
stringHTML += `
<div class="col-md-4">
<div class="card">
<div class="card-header">
User ID: #${data[i].id}
</div>
<div class="card-body">
<h4 class="card-title">${data[i].name}</h4>
<p class="card-text">Email - <em>${data[i].email}</em></p>
<p class="card-text">Phone - <em>${data[i].phone}</em></p>
<p class="card-text">Address - <em>${data[i].address.street}, ${data[i].address.city}, ${data[i].address.zipcode}</em></p>
</div>
</div>
</div>
`;
}
targetDiv.insertAdjacentHTML("beforeend", stringHTML);
}
});
<!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="main.css">
<title>JSON Users</title>
</head>
<body>
<div class="container">
<div class="text-center my-5">
<h1 class="display-4">Random JSON Users</h1>
<p>This is a random user generator, click the below button to get a
random person!</p>
<button id="mainButton" class="btn btn-primary">Get User!</button>
</div>
<!-- Users -->
<div id="targetDiv" class="row">
</div>
</div>
<!-- JavaScript -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>
If I get it right that your GET method is asking for users, so response contains more that one user. This response you send to renderData method and there you generate your div for each user from response. I supouse to change your GET method to get only one user or send only one user to renderData method like ourRequest.data[0] from your current solution.

i need to have my onclick event display multiple things

I am wondering how can I have my onclick event display multiple this. I want to to be so that once I click on the button, it display new student info each time i click on it. I will only have 3 students info to display. Below is my javascript code and the html that it is linked to. Any help would be great. Right now my onclick event only display one students info.
(function(){
console.log('******Objects of Student Information Below!******');
//Student Information in An Object
var studentInfo=[{name1: 'Sabrina Hill', address1:{address1:'172 Brushcreek Dr', city1:'Sanford',state1:'FL'},gpa1:[3.2,3.7,4.0]},{name2: 'JoelOsteen', address2:{address2:'3226 Lilac Dr', city2:'Portsmouth',state2:'VA'},gpa2:[3.0,2.7,2.0]}];
console.log('Name:',studentInfo[0].name1);
console.log('Address:',studentInfo[0].address1.address1,studentInfo[0].address1.city1,studentInfo[0].address1.state1);
console.log('GPA:',studentInfo[0].gpa1[0]+',',studentInfo[0].gpa1[1]+',',studentInfo[0].gpa1[2]);
console.log('Name:',studentInfo[1].name2);
console.log('Address:',studentInfo[1].address2.address2,studentInfo[1].address2.city2,studentInfo[1].address2.state2);
console.log('GPA:',studentInfo[1].gpa2[1]+',',studentInfo[1].gpa2[1]+',',studentInfo[1].gpa2[1]);
function displayInfo(){
document.getElementById('name').innerHTML='Name: '+ (studentInfo[0].name1);
document.getElementById('address').innerHTML='Address: '+(studentInfo[0].address1.address1+ ' '+studentInfo[0].address1.city1+' '+studentInfo[0].address1.state1);
document.getElementById('gpa').innerHTML='GPA: '+studentInfo[0].gpa1[0]+' ,'+studentInfo[0].gpa1[1]+' ,'+studentInfo[0].gpa1[2];
}
document.getElementById('info_btn').onclick = function(){
displayInfo()
};
console.log('******Added Information******');
console.log('Name:',studentInfo[0].name1);
console.log('Address:',studentInfo[0].address1.address1,studentInfo[0].address1.city1,studentInfo[0].address1.state1);
console.log('GPA:',studentInfo[0].gpa1[0]+',',studentInfo[0].gpa1[1]+',',studentInfo[0].gpa1[2]);
console.log('Name:',studentInfo[1].name2);
console.log('Address:',studentInfo[1].address2.address2,studentInfo[1].address2.city2,studentInfo[1].address2.state2);
console.log('GPA:',studentInfo[1].gpa2[1]+',',studentInfo[1].gpa2[1]+',',studentInfo[1].gpa2[1]);
function modifyStudent(studentObj,name,address,city,state,gpa){
studentObj.name=name;
studentObj.address = {
address:address,
city:city,
state:state
};
studentObj.gpa = gpa;
}
var newStudentInfo = [{
name:"Test",
address:{
address:"No where",
city:"Chicago",
state:"IL",
},
gpa:[]
}];
modifyStudent(newStudentInfo[0],'Super Man', '123 Test Dr', 'Orlando', 'Florida', [3.2, 4.0, 2.2]);
console.log('Name:',newStudentInfo[0].name);
console.log('Address:',newStudentInfo[0].address.address,newStudentInfo[0].address.city,newStudentInfo[0].address.state);
console.log('GPA:',newStudentInfo[0].gpa);
})();
Here is the HTML it is linked to :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Students info</title>
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="form_box">
<div id="contact-form">
<p class="heading">Display Students Information Below:</p>
<div id="form-box">
<div id="output">
<div id="name">
<p></p>
</div>
<div id="address">
<p></p>
</div>
<div id="gpa">
<p></p>
</div>
<div id="date">
<p></p>
</div>
<div id="gpaavg">
<p></p>
</div>
<div id="phone">
<p></p>
</div>
<!-- <div class="clear"></div> -->
</div>
<div id="info_box">
<div id="info_btn">
<h4 id="round" class="heading">Click To See Next Student</h4>
Next
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
LIVE DEMO
(function(){
var c = 0; // "current" Array index pointer
var studentInfo=[
{
name: 'Sabrina Hill',
address:{street:'172 Brushcreek Dr',city:'Sanford',state:'FL'},
gpa:[3.2,3.7,4.0]
},{
name: 'JoelOsteen',
address:{street:'3226 Lilac Dr', city:'Portsmouth',state:'VA'},
gpa:[3.0,2.7,2.0]
}
];
function el(id){ return document.querySelector(id); }
function displayInfo(){
var st = studentInfo[c];
el('#name').innerHTML = 'Name: '+ (st.name);
el('#address').innerHTML = 'Address: '+(st.address.street+' '+st.address.city+' '+st.address.state);
el('#gpa').innerHTML='GPA: '+st.gpa[0]+' ,'+st.gpa[1]+' ,'+st.gpa[2];
}
el('#info_btn').addEventListener('click', function(){
displayInfo();
c = ++c % studentInfo.length; // Increase Array pointer and loop
}, false);
})();
Explanation
Important note: look at the changes I did to your studentInfo property names. I removed the unnecessary numbers at the end of each.
Set a variable c (current array index pointer)
After every button click, get the values from your current object and increase the current value.
Also using the Reminder Operator (%) make sure to loop the pointer value back to 0 if exceeded.
The interesting part is the variable var st = studentInfo[c]; inside the function displayInfo() that takes out of the students object the needed Student array index.

Categories

Resources