i need to have my onclick event display multiple things - javascript

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.

Related

Making 2+ Text areas reflect each other

I am making a note-taking app and I want 2 text areas to when you type in one the other changes to
what you are doing in one. I want so when I change the title of the page it will change in other places on the page. I'll provide my current code what my page looks like (I want the change to be with my Unititled and an area next to the dropdown arrow) and what I want it to do, I've tried change and input events and I can't seem to figure it out.[My Current Site][1]
What I Want - https://share.vidyard.com/watch/Wj6uTmEiB9LR8iiZy7sVf9
[1]: https://i.stack.imgur.com/3vzEB.png
<!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>Study App</title>
<link rel="stylesheet" href="study.css" />
<link href="https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/5.15.1/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" charset="utf-
8"></script>
</head>
<body>
<script src="study.js"></script>
<div class="dropdown">
<nav><label for="touch"><span>Settings</span></label>
<input type="checkbox" id="touch" />
<ul class="slide">
<li><a>
<div class="dark"><button onclick="myFunction()">
<input class="toggle" type="checkbox" /></button></div>
</a></li>
<li></li>
</ul>
</nav>
</div>
</div>
<div class="arrowdown">
<input type="checkbox" id="myCheckbox" onchange="rotateElem()" checked><i class="fas fa-angle-
right dropdown"></i></button>
<div class="pages">
Add Page
</div>
</div>
</div>
<script type="text/javascript">
var checkBox = document.getElementById("myCheckbox");
function rotateElem() {
if (checkBox.checked == false) {
document.querySelector('.fas.fa-angle-right.dropdown').style.transform = 'rotate(90deg)';
} else {
document.querySelector('.fas.fa-angle-right.dropdown').style.transform = 'rotate(0deg)';
}
}
</script>
<div class="tabs"></div>
<div class="sidebar">
<div class="sidebar-top">
<h1><span class="study">Study</span><span class="app">App</span></h1>
</div>
<div class="title">
<textarea id="shortInput" spellcheck="true" placeholder="Untitled" cols="30" rows="1">
</textarea>
</div>
<div class="textbox">
<textarea id="longInput" spellcheck="true" placeholder="Start typing..." cols="30" rows="10"></textarea>
</div>
<script type="text/javascript">
$('.pages').hide();
$(document).ready(function() {
$('input').click(function() {
$('.pages').slideToggle();
});
});
</script>
<script src="study.js"></script>
</body>
</html>
One possible approach would be to store the synchronised value in a variable, and add event listeners to each element for any changes. Then update the value of each element with the new value when the change occurs.
// Store the synchronised content
let value = ''
// Add change listeners to each element
const elements = document.querySelectorAll('.synced')
for (let i = 0; i < elements.length; i++) {
// Different browsers will work better with different events
// but there's no problem with listening for multiple
elements[i].addEventListener('change', handleChange)
elements[i].addEventListener('input', handleChange)
elements[i].addEventListener('keyup', handleChange)
}
// When a change occurs, set the value of all the synchronised elements
function handleChange(e) {
value = e.target.value
for (let i = 0; i < elements.length; i++) {
elements[i].value = value
}
}
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
jQuery version:
// Store the synchronised content
let value = ''
// Get all the of the relevant elements
const elements = $('.synced')
// Different browsers will work better with different events
// but there's no problem with listening for multiple
elements.on('change input keyup', function() {
value = $(this).val()
elements.val(value)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>

how do i connect event listener to textarea element?

I really struggling with this.
I need to basically make it so whatever is written in a newly created textbox is stored in local storage.
// TODO: Q1(c)(iii)
// Make an event listener to save text when it changes:
// ...get the textarea element's current value
// ...make a text item using the value
// ...store the item in local storage using the given key
// Connect the event listener to the textarea element
var item, data, key;
var textareaElement = document.createElement("TEXTAREA");
textareaElement.addEventListener("change", function(event) {
var myText = document.getElementById("textareaElement").value;
localStorage.setItem("text", myText);
item = makeItem ("text", myText);
});
-- HTML --
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Erehwon Diary ds22368</title>
<meta name="author" content="Stephen Rice" />
<!-- Set viewport to ensure this page scales correctly on mobile devices -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="tma03.css" />
<!-- Set demo data -->
<script src="tma03-demo.js"></script>
<!-- Start TMA03 application -->
<script src="tma03.js"></script>
</head>
<body>
<h1>My Erehwon Diary ds22368</h1>
<main>
<section id="text" class="button">
<button type="button">Add entry</button>
</section>
<section id="image" class="button">
<button type="button">Add photo</button>
<input type="file" accept="image/*" />
</section>
</main>
</body>
</html>
The questions for each line are the comments above, and below them is what I've tried so far.
var item, data, key;
var textareaElement = document.createElement("TEXTAREA");
document.body.appendChild(textareaElement); //Add the element to the document
textareaElement.addEventListener("change", function(event) {
var mytext = textareaElement.value; //You already have the element as a variable
localStorage.setItem("text", myText);
item = makeItem("text", myText);
});
function makeItem() { //Don't forget to define makeItem
//code
}
Create an input like this in your HTML
<textarea id=‘textarea’ onchange=‘save()’ />
In JS:
const textarea = document.querySelector(‘#textarea’)
function save() {
localStorage.setItem("text", textarea.value);
}

Using checkboxes to render selected items to <div>

I have a populated table of JSON data with a checkbox next to each---I want it so that when a checkbox is selected it pushes that selected item into an array (in this case the div myFave.hs-gc-header).
When I console.log(arr) it just shows a bunch of empty arrays (I believe one for each of the list items). Not sure why this is--if anyone could shed light on this that would be great.
I think the problem lies with the populateArr() block, but I can't say for sure.
JS:
loadTableData() {
let tableRes = redactedName.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
// "FileName": obj.FileLeafRef,
// "Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name
}
});
let allTitles = tableRes;
for (var i = 0; i < allTitles.length; i++) {
let tr = $("<tr/>");
$(tr).append("<td> </td>");
$(tr).append("<td>" + allTitles[i].Titles + "</td>");
$(tr).append("<input type='checkbox'/>").addClass("checkbox").val("val");
/* ---------- */
function populateArr() {
let arr = [];
$(".checkbox input[type='checkbox']:checked").each(function() {
arr.push($(this).val());
});
return arr;
}
$("#myFave.hs-gc-header").click(function() {
populateArr();
})
};
HTML snippet
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1, shrink-to-fit=no">
<meta name="description" content="description here">
<meta name="keywords" content="keywords,here">
<!------------------------------->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.2/core.min.js"></script>
<script
type="text/javascript"
src="dist/js/jquery_wrapper.min.js"></script>
</head>
<body>
<script src="./bundle.js"></script>
<div class="km-div-container">
<div class="col-md-2"> <!-- Left -->
<div class="form-group">
<input
type="search"
class="form-control"
id="searchbar"
placeholder="Search All Documents...">
</div>
<div id="myFave.hs-gc-header">
<p>My Favorites:</p>
</div>
</div>
</div> <!-- km -->
</body>
</html>
I don't think this will work, I had a similar problem while using vanilla JavaScript.
When you append to the dom like below, you won't be able to add event listeners to the html tags.
$(tr).append("<input type='checkbox'/>").addClass("checkbox").val("val");
You should do this in your for loop when you filter for the .checkbox with attribute check it should work.
// convert code to jquery
let checkbox = document.createElement('checkbox');
check.setAttribute('type', 'checkbox');
checkbox.className = 'checkbox';
tr.appendChild(checkbox);

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

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>

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.

Categories

Resources