Can anyone help me pass this data? ;) - javascript

I am new to development. There of course are a few fundamentals I am struggling with. If anyone could help me and give a little explanation I would greatly appreciate it.
I am creating a synth using the tone.js library. I understand how to create the synth passing it one "Instrument", but I am having an issue doing it dynamically and I am digging myself a hole.
Here's the code:
//instruments
const synth = new Tone.Synth().toDestination();
const amSynth = new Tone.AMSynth().toDestination();
const duoSynth = new Tone.DuoSynth().toDestination();
const fmSynth = new Tone.FMSynth().toDestination();
const membraneSynth = new Tone.MembraneSynth().toDestination();
const metalSynth = new Tone.MetalSynth().toDestination();
const monoSynth = new Tone.MonoSynth({
oscillator: {
type: "square"
},
envelope: {
attack: 0.1
}
}).toDestination();
const noiseSynth = new Tone.NoiseSynth().toDestination();
const pluckSynth = new Tone.PluckSynth().toDestination();
const polySynth = new Tone.PolySynth().toDestination();
const sampler = new Tone.Sampler({
urls: {
A1: "A1.mp3",
A2: "A2.mp3",
},
baseUrl: "https://tonejs.github.io/audio/casio/",
onload: () => {
sampler.triggerAttackRelease(["C1", "E1", "G1", "B1"], 0.5);
}
}).toDestination();
//effects
const distortion = new Tone.Distortion(0.4).toDestination();
const vibrato = new Tone.Vibrato(0.4).toDestination();
const pingPong = new Tone.PingPongDelay("4n", 0.2).toDestination()
const autoWah = new Tone.AutoWah(50, 6, -30).toDestination();
const cheby = new Tone.Chebyshev(50).toDestination();
const autoFilter = new Tone.AutoFilter("4n").toDestination()
const autoPanner = new Tone.AutoPanner("4n").toDestination();
const crusher = new Tone.BitCrusher(4).toDestination();
const chorus = new Tone.Chorus(4, 2.5, 0.5).toDestination();
const feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toDestination();
const freeverb = new Tone.Freeverb().toDestination();
freeverb.dampening = 1000;
const shift = new Tone.FrequencyShifter(42).toDestination();
const reverb = new Tone.JCReverb(0.4).toDestination();
const phaser = new Tone.Phaser({
frequency: 15,
octaves: 5,
baseFrequency: 1000
}).toDestination();
const tremolo = new Tone.Tremolo(9, 0.75).toDestination();
//array of notes --- we add the sharps in the function
var notes = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
var html = '';
for (var octave = 0; octave < 2; octave++) {
for (var i = 0; i < notes.length; i++) {
var hasSharp = true;
var note = notes[i]
if (note == 'E' || note == 'B')
hasSharp = false;
//white keys with one octive
html += `<div class='whitenote play' onmousedown='noteDown(this)' data-note='${note + (octave + 4)}'>`;
//black keys with one octive
if (hasSharp) {
html += `<div class='blacknote play' onmousedown='noteDown(this)' data-note='${note + '#' + (octave + 4)}'></div>`;
}
html += '</div>'
}
}
$('container').innerHTML = html;
$(".play").click(function(elem) {
var note = elem.dataset.note;
var synth = getSynth(elem.data("synth"));
synth.connect(phaser);
synth.connect(autoWah);
synth.triggerAttackRelease(note, "16n");
event.stopPropagation();
});
function getSynth(name) {
switch (name) {
case "Synth":
return synth;
case "AM":
return amSynth;
case "Duo":
return duoSynth;
case "FM":
return fmSynth;
case "Membrane":
return membraneSynth;
case "Metal":
return metalSynth;
case "Mono":
return monoSynth;
case "Noise":
return noiseSynth;
case "Pluck":
return pluckSynth;
case "Poly":
return polySynth;
}
}
#container {
position: absolute;
height: 200px;
border: 2px solid black;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
white-space: nowrap;
display: block;
white-space: inherit;
overflow: hidden;
}
.whitenote {
height: 100%;
width: 50px;
background: white;
float: left;
border-right: 1px solid black;
position: relative;
}
.blacknote {
position: absolute;
height: 65%;
width: 55%;
z-index: 1;
background: #777;
left: 68%;
}
.instrument-button {
background: orangered;
border: none;
color: white;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
}
.effect-button {
background: blue;
border: none;
color: white;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
}
.effect-button-padding {
padding-top: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.26/Tone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.26/Tone.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src='node_modules\tone\build\Tone.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.26/Tone.js.map'></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
</head>
<body style="align-items: center;">
<div>
<h1>Synth AF</h1>
</div>
<div>
<h4>Intruments</h4>
<button class="btn instrument-button" data-synth="Synth" id="synth-button">Synth</button>
<button class="btn instrument-button" data-synth="AM" id="amSynth-button">AM</button>
<button class="btn instrument-button" data-synth="Duo" id="duoSynth-button">Duo</button>
<button class="btn instrument-button" data-synth="FM" id="fmSynth-button">FM</button>
<button class="btn instrument-button" data-synth="Membrane" id="membraneSynth-button">Drums</button>
<button class="btn instrument-button" data-synth="Metal" id="metalSynth-button">Metal</button>
<button class="btn instrument-button" data-synth="Mono" id="monoSynth-button">Mono</button>
<button class="btn instrument-button" data-synth="Noise" id="noiseSynth-button">Noise</button>
<button class="btn instrument-button" data-synth="Pluck" id="pluckSynth-button">Plucky</button>
<button class="btn instrument-button" data-synth="Poly" id="polySynth-button">Poly</button>
</div>
<div class="effect-button-padding">
<h4>Effects</h4>
<button class='btn effect-button' id="distortion-button">Distortion</button>
<button class='btn effect-button' id="vibrato-button">Vibrato</button>
<button class='btn effect-button' id="pingPong-button">PingPong</button>
<button class='btn effect-button' id="autoWah-button">Wah</button>
<button class='btn effect-button' id="crusher-button">BitCrusher</button>
<button class='btn effect-button' id="phaser-button">Phaser</button>
<button class='btn effect-button' id="reverb-button">Reverb</button>
<button class='btn effect-button' id="autoFilter-button">Auto Filter</button>
<button class='btn effect-button' id="feedbackDelay-button">Feedback</button>
<button class='btn effect-button' id="cheby-button">Chebyshev</button>
</div>
<div class="" id="container">
</div>
</body>
</html>
Here is the UI. (Haven't designed it yet...don't judge)
UI Photo
The idea is to use one of the new instruments created in the one constants by passing it through a button click, to a switch statement and then to the output. I apologize if I didn't explain anything clearly or used the wrong terminology.
I would very much appreciate your help.
Thank you for reading,
FandopTheNoob

// this will be the "state" of the synthesiser
const synthSetup = {
instrument: "",
effects: [],
}
// this is the list of instruments
const instruments = [{
synth: "Synth",
id: "synth-button",
text: "Synth",
tone: new Tone.Synth().toDestination(),
},
{
synth: "AM",
id: "amSynth-button",
text: "AM",
tone: new Tone.AMSynth().toDestination(),
},
]
// this is the list of effects
const effects = [{
id: "distortion-button",
text: "Distortion",
tone: new Tone.Distortion(0.4).toDestination(),
},
{
id: "vibrator-button",
text: "Vibrato",
tone: new Tone.Vibrato(0.4).toDestination(),
},
]
// setting up the instruments & effects buttons
const instrumentsHtml = (instruments) => {
return instruments.map(({
synth,
id,
text
}) => {
return `
<button class="btn instrument-button" data-synth=${synth} id="${id}">${text}</button>
`
}).join('')
}
const effectsHtml = (effects) => {
return effects.map(({
id,
text
}) => {
return `
<button class="btn effect-button" id="${id}">${text}</button>
`
}).join('')
}
const instrumentsContainer = document.getElementById("btn-group-instruments")
instrumentsContainer.innerHTML = instrumentsHtml(instruments)
const effectsContainer = document.getElementById("btn-group-effects")
effectsContainer.innerHTML = effectsHtml(effects)
// setting up click handlers on the instruments & effects buttons
$("body").on("click", ".instrument-button", function() {
// setting up synthSetup.instrument:
synthSetup.instrument = $(this).data("synth")
})
$("body").on("click", ".effect-button", function() {
// setting up synthSetup.effects:
synthSetup.effects = [...new Set([...synthSetup.effects, $(this).attr("id")])]
})
//array of notes --- we add the sharps in the function
var notes = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
var html = '';
for (var octave = 0; octave < 2; octave++) {
for (var i = 0; i < notes.length; i++) {
var hasSharp = true;
var note = notes[i]
if (note == 'E' || note == 'B')
hasSharp = false;
//white keys with one octave
html += `<div class='whitenote play' data-note='${note + (octave + 4)}'>`;
//black keys with one octave
if (hasSharp) {
html += `<div class='blacknote play' data-note='${note + '#' + (octave + 4)}'></div>`;
}
html += '</div>'
}
}
const container = document.getElementById("container")
container.innerHTML = html;
$("body").on("click", ".play", function() {
if (!synthSetup.instrument) {
alert("Choose an instrument first!")
} else {
const {
tone: synth
} = instruments.find(({
synth
}) => synth === synthSetup.instrument)
const note = $(this).data("note")
// connecting the effects
synthSetup.effects.forEach(e => {
const effect = effects.find(({
id
}) => e)
synth.connect(effect.tone)
})
const now = Tone.now()
synth.triggerAttackRelease(note, "2n", now)
}
})
html,
body {
height: 100%;
position: relative;
}
#container {
position: absolute;
height: 200px;
border: 2px solid black;
left: 50%;
bottom: 0;
transform: translateX(-50%);
white-space: nowrap;
display: block;
white-space: inherit;
overflow: hidden;
}
.whitenote {
height: 100%;
width: 50px;
background: white;
float: left;
border-right: 1px solid black;
position: relative;
}
.blacknote {
position: absolute;
height: 65%;
width: 55%;
z-index: 1;
background: #777;
left: 68%;
}
.instrument-button {
background: orangered;
border: none;
color: white;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
}
.effect-button {
background: blue;
border: none;
color: white;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
}
.effect-button-padding {
padding-top: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.26/Tone.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.26/Tone.js.map'></script>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div>
<h1>Synth AF</h1>
</div>
<div>
<h4>Intruments</h4>
<div id="btn-group-instruments"></div>
</div>
<div class="effect-button-padding">
<h4>Effects</h4>
<div id="btn-group-effects"></div>
</div>
<div class="" id="container">
</div>
So, here's the next step for this synthesizer:
the current state of the synthesizer is kept in synthSetup
the instruments are stored as an array of objects
the effects are stored as an array of objects
instruments & effects are put to the DOM dynamically
on clicking any white or black button the synthSetup (state) is read & the note is played (chosen instrument & the list of effects)
Issues:
you cannot remove an effect from the list of effects (it could be handled in the click handler of the effect buttons)

Related

How to select and manipulate the dynamically created html element with javascript?

I am pretty new to js, and I am building a color scheme generator as a solo project.
I am now stuck on select the html element that created from dynamically.
I tried to select both label and input element below, using document.getElementByClassName but it gives me 'undefined'
I wanna select both label and input elements and add an click eventListner so that they can copy the result color code from that elements.
<label for='${resultColor}' class='copy-label'>Click to copy!</label>
<input class='result-code' id='${resultColor}' type="text" value='${resultColor}'/>`
const colorPickerModes = [ 'monochrome', 'monochrome-dark', 'monochrome-light', 'analogic', 'complement', 'analogic-complement', 'triad quad']
const colorPickerForm = document.getElementById("colorPick-form");
const colorPickerInput = document.getElementById("colorPicker");
const colorPickerModeDropDown = document.getElementById("colorPick-mode");
const resultColorDiv = document.getElementById("result-color-div");
const resultColorCodeDiv = document.getElementById("result-code-div");
let colorPicked = "";
let modePicked = "";
let resultColorDivHtml =''
let resultCodeDivHtml=''
let colorSchemeSetStrings = [];
let resultColorSchemeSet = [];
fetchToRender()
renderDropDownList();
//listen when user change the color input and save that data in global variable
colorPickerInput.addEventListener(
"change",
(event) => {
//to remove # from the color hex code data we got from the user
colorPicked = event.target.value.slice(1, 7);
},
false
);
//listen when user change the scheme mode dropdownlist value and save that data in global variable
colorPickerModeDropDown.addEventListener('change', (event)=>{
modePicked =
colorPickerModeDropDown.options[colorPickerModeDropDown.selectedIndex].text;
})
//whe user click submit btn get data from user's input
colorPickerForm.addEventListener("submit", (event) => {
event.preventDefault();
// To get options in dropdown list
modePicked =
colorPickerModeDropDown.options[colorPickerModeDropDown.selectedIndex].text;
fetchToRender()
});
//when first load, and when user request a new set of color scheme
function fetchToRender(){
if (!colorPicked) {
//initialize the color and mode value if user is not selected anything
colorPicked = colorPickerInput.value.slice(1, 7);
modePicked = colorPickerModes[0]
}
fetch(
`https://www.thecolorapi.com/scheme?hex=${colorPicked}&mode=${modePicked}`
)
.then((res) => res.json())
.then((data) => {
let colorSchemeSetArray = data.colors;
for (let i = 0; i < 5; i++) {
colorSchemeSetStrings.push(colorSchemeSetArray[i]);
}
// to store each object's hex value
for (let i = 0; i < colorSchemeSetStrings.length; i++) {
resultColorSchemeSet.push(colorSchemeSetStrings[i].hex.value);
}
renderColor();
colorSchemeSetStrings = []
resultColorSchemeSet = [];
});
}
function renderColor(){
//to store result of color scheme set object
resultColorDivHtml = resultColorSchemeSet.map((resultColorItem) => {
return `<div class="result-color"
style="background-color: ${resultColorItem};"></div>`;
}).join('')
resultCodeDivHtml = resultColorSchemeSet
.map((resultColor) => {
return `
<label for='${resultColor}' class='copy-label'>
Click to copy!</label>
<input class='result-code' id='${resultColor}'
type="text" value='${resultColor}'/>`;
})
.join("");
resultColorDiv.innerHTML = resultColorDivHtml;
resultColorCodeDiv.innerHTML = resultCodeDivHtml;
}
function renderDropDownList() {
const colorPickerModeOptionsHtml = colorPickerModes
.map((colorPickerMode) => {
return `<option class='colorSchemeOptions' value="#">${colorPickerMode}</option>`;
})
.join("");
colorPickerModeDropDown.innerHTML = colorPickerModeOptionsHtml;
}
* {
box-sizing: border-box;
}
body {
font-size: 1.1rem;
font-family: "Ubuntu", sans-serif;
text-align: center;
margin: 0;
}
/*------Layout------*/
#container {
margin: 0 auto;
width: 80%;
}
#form-div {
width: 100%;
height:10vh;
margin: 0 auto;
}
#colorPick-form {
display: flex;
width: 100%;
height:6vh;
justify-content: space-between;
}
#colorPick-form > * {
margin: 1rem;
height: inherit;
border: 1px lightgray solid;
font-family: "Ubuntu", sans-serif;
}
#colorPick-form > #colorPicker {
width: 14%;
height: inherit;
}
#colorPick-form > #colorPick-mode {
width: 45%;
padding-left: 0.5rem;
}
#colorPick-form > #btn-getNewScheme {
width: 26%;
}
#main {
display: flex;
flex-direction:column;
width:100%;
margin: .8em auto 0;
height: 75vh;
border:lightgray 1px solid;
}
#result-color-div {
width:100%;
height:90%;
display:flex;
}
#result-color-div > *{
width:calc(100%/5);
}
#result-code-div {
width:100%;
height:10%;
display:flex;
}
.copy-label{
width:10%;
display:flex;
padding:0.5em;
font-size:0.8rem;
align-items: center;
cursor: pointer;
background-color: #4CAF50;
color: white;
}
#result-code-div .result-code{
width:calc(90%/5);
text-align: center;
border:none;
cursor: pointer;
}
.result-code:hover, .result-code:focus, .copy-label:hover, .copy-label:focus{
font-weight:700;
}
/*------Button------*/
#btn-getNewScheme {
background-image: linear-gradient(
to right,
#614385 0%,
#516395 51%,
#614385 100%
);
}
#btn-getNewScheme {
padding:0.8rem 1.5rem;
transition: 0.5s;
font-weight: 700;
background-size: 200% auto;
color: white;
box-shadow: 0 0 20px #eee;
border-radius: 5px;
display: block;
cursor: pointer;
}
#btn-getNewScheme:hover,
#btn-getNewScheme:focus {
background-position: right center; /* change the direction of the change here */
color: #fff;
text-decoration: 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" />
<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=Ubuntu:wght#300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="index.css">
<title>Color Scheme Generator</title>
</head>
<body>
<div id="container">
<div>
<header><h1 class="site-title">🦎 Color Scheme Generator 🦎</h1></header>
</div>
<div id="form-div">
<form id="colorPick-form" method="get" >
<input id="colorPicker" type="color" />
<select name="colorPick-mode" id="colorPick-mode">
</select>
<button type='submit' id="btn-getNewScheme">Get Color Scheme</button>
</form>
</div>
<div id="main">
<div id="result-color-div">
</div>
<div id="result-code-div">
</div>
</div>
<script src="index.js" type="module"></script>
</body>
</html>
I think the problem is rendering timing. So you need to add event listener below the code where set innerHTML.
function renderColor() {
// to store result of color scheme set object
resultColorDivHtml = resultColorSchemeSet
.map((resultColorItem) => {
return `<div class="result-color" style="background-color: ${resultColorItem};"></div>`;
})
.join("");
resultCodeDivHtml = resultColorSchemeSet
.map((resultColor) => {
return `
<label for='${resultColor}' class='copy-label'>Click to copy!</label>
<input class='result-code' id='${resultColor}' type="text" value='${resultColor}'/>
`;
})
.join("");
resultColorDiv.innerHTML = resultColorDivHtml;
resultColorCodeDiv.innerHTML = resultCodeDivHtml;
// here! add event listener
const labels = document.getElementsByClassName("result-code");
Object.entries(labels).forEach(([key, label]) => {
label.addEventListener("click", (event) =>
alert(`copy color: ${event.target.value}`)
);
});
}
const resultColorCodeDiv=document.getElementById("resultColorCodeDiv")
const resultColorDiv=document.getElementById("resultColorDiv")
resultColorSchemeSet=[
{color:"red", code: "#ff0000"},
{color:"green", code: "#00ff00"},
{color:"blue", code: "#0000ff"}]
function renderColor(){
//to store result of color scheme set object
resultColorDivHtml = resultColorSchemeSet.map((resultColorItem) => {
return `<div class="result-color" style="background-color: ${resultColorItem.color};"></div>`
}).join('')
resultCodeDivHtml = resultColorSchemeSet
.map((resultColor) => {
return `
<label for='${resultColor.code}' class='copy-label'>Click to copy!</label>
<input class='result-code' id='${resultColor.code}' type="text" value='${resultColor.code}'/>`
})
.join("")
resultColorDiv.innerHTML = resultColorDivHtml
resultColorCodeDiv.innerHTML = resultCodeDivHtml
addListener(document.querySelectorAll(".result-color"))
addListener(document.querySelectorAll(".result-code"))
}
renderColor()
function addListener(elements){
for(const element of elements){
element.addEventListener("click" , ()=>{
// add copy logic here
console.log("hello")
})
}
}
<body>
<div id="resultColorDiv"></div>
<div id="resultColorCodeDiv"></div>
</body>

How to remove an object from an array in local storage

I am trying to remove a note from local storage by identifying its
title. I checked w3schools and this forum for info. I am able to save
the array but, I can't remove a specific note.
I tried, no change, an example of what I am trying to achieve,
This is my local storage before removing:
[{title: "Laundry", content: "Fold Clothes"}, {title: "Cook", content:
"Buy Food"}, {title: "Read", content: "Go to the library"}] 0: {title:
"Laundry", content: "Fold Clothes"} 1: {title: "Cook", content: "Buy
Food"} 2: {title: "Read", content: "Go to the library"}
My desired output after removing:
[{title: "Laundry", content: "Fold Clothes"}, {title: "Cook", content:
"Buy Food"}] 0: {title: "Laundry", content: "Fold Clothes"} 1: {title:
"Cook", content: "Buy Food"}
I want to be able to remove an item based on its title Read
const editNote = (e) => {
saveContent.addEventListener('click', (e) => {
e.preventDefault()
let notes = []
let note = {
title: noteTitle.value,
content: noteContent.value
}
// Parse the serialized data back into an aray of objects
notes = JSON.parse(localStorage.getItem('items')) || [];
// Push the new data (whether it be an object or anything else) onto the array
notes.push(note);
// Re-serialize the array back into a string and store it in localStorage
localStorage.setItem('items', JSON.stringify(notes));
// input.textContent = note.title
//remove notes by id
const removeNote = () => {
let title = noteTitle
const index = notes.findIndex((note) => note.title === title)
if (index > -1) {
notes.splice(index,1);
}
}
delNote.addEventListener('click', (e) => {
removeNote()
e.preventDefault()
// window.location.href='index.html'
})
})
}
editNote()
You need to set item into local storage after you update your data
const removeNote = () => {
let title = noteTitle
const index = notes.findIndex((note) => note.title === title)
if (index > -1) {
notes.splice(index,1);
localStorage.setItem('items', JSON.stringify(notes))
}
}
localStorage.removeItem('ITEM TO REMOVE');
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Storage/removeItem
I eventually figured it out. Thank you all for replying and providing guidelines.
let input = document.querySelector('.input-bar')
let addItem = document.querySelector('.submit-btn')
let clearAll = document.querySelector('.clear-btn')
// pay attension to indentation and ele location it will determine success
addItem.addEventListener('click', (e) => {
e.preventDefault()
// Parse the serialized data back into an aray of objects
items = JSON.parse(localStorage.getItem('items')) || [];
// Push the new data (whether it be an object or anything else) onto the array
items.push(input.value);
item = input.value
// Re-serialize the array back into a string and store it in localStorage
localStorage.setItem('items', JSON.stringify(items));
var clear = document.createElement('button')
clear.innerHTML= '<i class="fa fa-trash" style="font-size:20px ;color: #ac2412"></i>'
let itemsEl = document.getElementById('items')
let para = document.createElement("P");
var t = document.createTextNode(`${input.value}`);
para.appendChild(t);
para.appendChild(clear)
itemsEl.appendChild(para);
input.value = ''
clear.addEventListener('click', (e) => {
itemsEl.removeChild(para)
e.preventDefault()
for (let index = 0; index < items.length; index++) {
if (items[index] === para.textContent) {
items.splice(index, 1)
localStorage.setItem('items', JSON.stringify(items));
}
}
})
})
clearAll.addEventListener('click', (e) => {
document.getElementById('items').innerHTML = ''
localStorage.clear()
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
color: white;
background-color: black;
margin: 40px 0px;
text-align: center;
}
input {
width: 300px;
height: 46px;
outline: none;
background: transparent;
border-color: silver;
border-radius: 0;
color: var(--mainWhite);
font-size: 1.7rem;
}
h1 {
margin: 20px 0px;
}
.submit-btn {
margin: 0px 5px;
width: 50px;
height: 50px;
outline: none;
/* color: white; */
background-color: rgb(21, 96, 194);
color: white;
font-size: 1.7rem;
}
.items-list {
list-style-type: none;
}
li {
display: inline-flex;
border: 1px solid slategrey;
font-size: 22px;
margin: 20px 0px 0px 0px;
}
button {
outline: none;
margin: 0px 0px 0px 200px;
}
.clear-btn {
width: 100px;
height: 40px;
margin: 30px;
outline: none;
background-color: rgb(21, 96, 194);
color: white;
font-size: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<title>Groceries</title>
</head>
<body>
<h1>Grocery List</h1>
<div>
<input class="input-bar" type="text">
<span>
<button class="submit-btn">
<i class="fa fa-pencil" aria-hidden="true"></i>
</button>
</span>
<ul class="items-list" id="items"></ul>
</div>
<button class="clear-btn">Clear</button>
<script src="index.js"></script>
</body>
</html>

Javascript global variable inside class function

I'm not really used to es5, so i'm having a bit of trouble since i'm forced to use es5 in my case. the problem is when I do, updateScoreboard({"name":"foo","bgColor":{"r":47.0,"b":79.0,"a":255.0,"g":79.0}})
to create a new panel on the scoreboard, my isPlayerInScoreboard function is returning false because playerName2 is somehow a global variable and not bound to the function PlayerPanel, you can see what I mean by invoking updateScoreboard({"name":"foo","bgColor":{"r":47.0,"b":79.0,"a":255.0,"g":79.0}})
and then logging out "playerName2", which I don't think should be a global variable but somehow is
edit: also when I do this
updateScoreboard({"name":"foo","bgColor":{"r":47.0,"b":79.0,"a":255.0,"g":79.0}})
updateScoreboard({"name":"bar","bgColor":{"r":47.0,"b":79.0,"a":255.0,"g":79.0}})
in my panels array, all the object's getPlayerName method returns the last inputted name, so in this case if I did panels[0].getPlayerName() it'd return "bar" which is should return "foo"
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: rgba(25, 25, 25, 0.50);
font-family: "Arial";
}
.tab {
margin: 1px auto;
width: 95%;
height: 30px;
background-color: white;
}
#title-header {
/*display:inline-block;*/
/*color: white;*/
font-size: 25px;
color: white;
/*border-top: 1px solid white;*/
/*border-bottom: 1px solid white;*/
margin:0 auto;
/*vertical-align: middle;*/
text-align:center;
/*white-space: nowrap;*/
}
.player-img {
display: inline-block;
/*width: 50px;*/
}
.player-name {
display: inline-block;
position: relative;
bottom: 10px;
color: white;
}
</style>
</head>
<body>
<div id="title-header">
<h1>SleekRP</h1>
</div>
<div class="main-scoreboard">
<div class="tab">
<div class="player-img">
<img src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg">
</div>
<p class="player-name">test</p>
</div>
<!-- <div class="tab"></div>
<div class="tab"></div>
<div class="tab"></div>
<div class="tab"></div> -->
</div>
<script>
var panels = [];
function setTitle(title){
document.getElementById("title-header").innerText = title
}
function isPlayerInScoreboard(name){
for (var i=0; i<panels.length; i++){
if (panels[i].getPlayerName() == name) {
return true
}
}
return false
}
function updateScoreboard(plyInfo){
if (!isPlayerInScoreboard(plyInfo.name)) {
PlayerPanel(plyInfo)
}
}
function PlayerPanel(plyInfo){
// Create element
var mainPanel = document.createElement('div')
mainPanel.className = "tab"
mainPanel.style.backgroundColor = "rgba(" + plyInfo.bgColor.r + ", " + plyInfo.bgColor.g + ", " + plyInfo.bgColor.b + ", 0.50)"
document.getElementsByClassName("main-scoreboard")[0].appendChild(mainPanel)
this.playerName2 = document.createElement('p')
this.playerName2.innerText = plyInfo.name
this.playerName2.className = "player-name"
mainPanel.appendChild(this.playerName2)
this.setPlayerName = function(name) {
this.playerName2.innerText = name
}
this.updatebGColor = function(bgColor){
mainPanel.style.backgroundColor = "rgba(" + bgColor.r + ", " + bgColor.g + ", " + bgColor.b + ", 0.50)"
}
this.getPlayerName = function() {
return this.playerName2.innerText
}
panels.push(this)
}
</script>
</body>
</html>
You should call your PlayerPanel with "new" when you are using "this" in it.
function updateScoreboard(plyInfo){
if (!isPlayerInScoreboard(plyInfo.name)) {
new PlayerPanel(plyInfo)
}
}

How to show specific message when user presses submit on form?

I am making a javascript form that includes a question being answered with only the number 1-6 (multiple choice) when the user finishes the form, there will be a result showing a chart (ChartJS). I've made that, but I want to show the user below the chart as following. If statement 1 is 1 and If statement 2 is 3 and If statement 3 is 4 then show .... . Here is my code:
/*-----------------------------------------------------
REQUIRE
-------------------------------------------------------*/
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var minixhr = require('minixhr')
var chart = require('chart.js')
/*-----------------------------------------------------
THEME
-------------------------------------------------------*/
var font = 'Montserrat'
var yellow = 'hsla(52,35%,63%,1)'
var white = 'hsla(120,24%,96%,1)'
var violet = 'hsla(329,25%,45%,1)'
var lightBrown = 'hsla(29,21%,67%,1)'
var darkBrown = 'hsla(13,19%,45%,1)'
/*-----------------------------------------------------------------------------
LOADING FONT
-----------------------------------------------------------------------------*/
var links = ['https://fonts.googleapis.com/css?family=Montserrat']
var font = yo`<link href=${links[0]} rel='stylesheet' type='text/css'>`
document.head.appendChild(font)
/*-----------------------------------------------------------------------------
LOADING DATA
-----------------------------------------------------------------------------*/
var questions = [
`
Statement #1:
The next social network I build,
will definitely be for animals.
`,
`
Statement #2:
I really like to do my hobby
`,
`
Statement #3:
My friends say, my middle name should be "Halo".
`,
`
Statement #4:
Rhoma Irama is definitely one of my
favourite artists
`,
`
Statement #5:
I think I could spend all day just
sleeping at my couch
`,
`
Statement #6:
I have a really strong desire to succeed
`
]
var i = 0
var question = questions[i]
var results = []
var answerOptions = [1,2,3,4,5,6]
/*-----------------------------------------------------------------------------
QUIZ
-----------------------------------------------------------------------------*/
function quizComponent () {
var css = csjs`
.quiz {
background-color: ${yellow};
text-align: center;
font-family: 'Montserrat';
padding-bottom: 200px;
}
.welcome {
font-size: 4em;
padding: 50px;
color: ${darkBrown}
}
.question {
font-size: 2em;
color: ${white};
padding: 40px;
margin: 0 5%;
}
.answers {
display: flex;
justify-content: center;
flex-wrap: wrap;
margin: 0 5%;
}
.answer {
background-color: ${violet};
padding: 15px;
margin: 5px;
border: 2px solid ${white};
border-radius: 30%;
}
.answer:hover {
background-color: ${lightBrown};
cursor: pointer;
}
.instruction {
color: ${violet};
font-size: 1em;
margin: 0 15%;
padding: 20px;
}
.results {
background-color: ${white};
text-align: center;
font-family: 'Montserrat', cursive;
padding-bottom: 200px;
}
.resultTitle{
font-size: 4em;
padding: 50px;
color: ${darkBrown}
}
.back {
display: flex;
justify-content: center;
}
.backImg {
height: 30px;
padding: 5px;
}
.backText {
color: ${white};
font-size: 25px;
}
.showChart {
font-size: 2em;
color: ${violet};
margin: 35px;
}
.showChart:hover {
color: ${yellow};
cursor: pointer;
}
.myChart {
width: 300px;
height: 300px;
}
`
function template () {
return yo`
<div class="${css.quiz}">
<div class="${css.welcome}">
IQ Test
</div>
<div class="${css.question}">
${question}
</div>
<div class="${css.answers}">
${answerOptions.map(x=>yo`<div class="${css.answer}" onclick=${nextQuestion(x)}>${x}</div>`)}
</div>
<div class="${css.instruction}">
Choose how strongly do you agree with the statement<br>
(1 - don't agree at all, 6 - completely agree)
</div>
<div class="${css.back}" onclick=${back}>
<img src="http://i.imgur.com/L6kXXEi.png" class="${css.backImg}">
<div class="${css.backText}">Back</div>
</div>
</div>
`
}
var element = template()
document.body.appendChild(element)
return element
function nextQuestion(id) {
return function () {
if (i < (questions.length-1)) {
results[i] = id
i = i+1
question = questions[i]
yo.update(element, template())
} else {
results[i] = id
sendData(results)
yo.update(element, seeResults(results))
}
}
}
function seeResults(data) {
var ctx = yo`<canvas class="${css.myChart}"></canvas>`
return yo`
<div class="${css.results}">
<div class="${css.resultTitle}">
Your Result
</div>
<div class="${css.showChart}" onclick=${function(){createChart(ctx, data)}}>
Click to see the chart
</div>
${ctx}
</div>
`
}
function back() {
if (i > 0) {
i = i-1
question = questions[i]
yo.update(element, template())
}
}
function sendData(results) {
var request = {
url : 'https://cobatest-964fd.firebaseio.com/results.json',
method : 'POST',
data : JSON.stringify(results)
}
minixhr(request)
}
function createChart(ctx, myData) {
minixhr('https://cobatest-964fd.firebaseio.com/results.json', responseHandler)
function responseHandler (data, response, xhr, header) {
var data = JSON.parse(data)
var keys = Object.keys(data)
var arrayOfAnswers = keys.map(x=>data[x])
var stats = arrayOfAnswers.reduce(function(currentResult,answer,i) {
var newResult=currentResult.map((x,count)=>(x*(i+1)+answer[count])/(i+2))
return newResult
}, myData)
var data = {
labels: [
"Caring", "Eager", "Pessimist",
"Hard-headed", "Lazy", "Ambitious"
],
datasets: [
{
label: "My score",
backgroundColor: "rgba(179,181,198,0.2)",
borderColor: "rgba(179,181,198,1)",
pointBackgroundColor: "rgba(179,181,198,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(179,181,198,1)",
data: myData
},
]
}
var myChart = new Chart(ctx, {
type: 'radar',
data: data,
options: {
scale: {
scale: [1,2,3,4,5,6],
ticks: {
beginAtZero: true
}
}
}
})
}
}
}
quizComponent()
Please do help! thank you
Just like onclick is an event, onsubmit is one too.
From w3schools:
in HTML: <element onsubmit="myScript">
in JS: object.onsubmit = function(){myScript};
in JS with eventListener:object.addEventListener("submit", myScript);
You can check it out on w3 schools:
onsubmit event
onsubmit attribute
more

How can I dynamically create HTML DOM base on my JSON data?

I have an accordion
Click on View Report, it expands
All data on this accordion, table, and piechart came from 1 object of my JSON Ajax call.
if I have 3, 5, or 10 objects, I want to dynamically create my accordions.
How do I do something like that ?
HTML
<br><br>
<div class="row student-accordion ">
<div class="col-md-12">
<div class="panel-group" id="accordion">
<div class="panel">
<div class="row panel-heading">
<div class="col-xs-1 col-sm-1 sa-section" >
<span class="sa-h5" id="as-report-type-car"></span> <br>
<span class="sa-h1" id="as-section-num" class="section-num"></span><br>
<span class="sa-h5" id="as-report-type-cdr"></span>
<!-- <span class="as-cb-div"><span id="as-section-num"></span></span> -->
</div>
<!-- Title -->
<div class="col-xs-6 col-sm-6 col-lg-6">
<span class="sa-h3" id="as-report-type-title" >
<span id="as-section-num"></span>
</span>
<br>
<span class="sa-h5" id="as-assignment" ></span> <br>
<span class="sa-h4" id="as-date"></span>
</div>
<!-- Answers -->
<div class="sa-right-items text-center">
<span class="sa-answer"><br>
<span> <span class="sa-h2">
<span id="as-correct-num" ></span>/<span id="as-correct-total-num"></span>
</span> <br> <span class="sa-h6">ITEMS ANSWERED <br> CORRECTLY</span> </span>
</span>
<!-- Score -->
<span class="sa-score">
<span class="sa-h2" id="as-avgscore"></span>% <br>
<span class="sa-h6">SCORE</span>
</span>
<!-- Review -->
<span class="sa-review">
<img width="40px" src="/BIM/resources/images/icons-report/review_white.png"><br>
<span> <span class="sa-h6">REVIEW</span> </span>
</span>
<!-- Report -->
<span class="sa-report" data-toggle="collapse" data-parent="#accordion" href="#as-collapse-1" aria-expanded="true" class="pull-right">
<img class="sa-report-btn" width="35px" src="/BIM/resources/images/icons-report/report_white.png"><br>
<span><span id="view-report-btn" class="sa-h6 sa-report-btn">VIEW REPORT</span></span>
</span>
<!-- Hide -->
<span class="sa-hide hidden" data-toggle="collapse" data-parent="#accordion" href="#sa-collapse" aria-expanded="false" class="pull-right">
<img class="sa-hide-btn" width="35px" src="/BIM/resources/images/icons-report/hidedetails_white.png"><br>
<span><span class="sa-h6 sa-hide-btn">HIDE DETAILS</span></span>
</span>
</div>
</div>
</div>
<div id="as-collapse-1" class="panel-collapse collapse">
<div class="panel-body">
<!-- percent-item -->
<%# include file="../../components/teacher/percent-item.jsp" %>
<div class="report-grid-area"></div>
</div>
</div>
</div>
</div>
</div>
CSS
.student-accordion .panel {
border-radius: 0px !important;
box-shadow: none;
margin-left: 25px;
margin-right: 25px;
}
.student-accordion .panel-heading {
height: 110px;
background-color: #4D8FCB;
border-radius: 0px;
color: white;
padding: 10px 0px;
}
.student-accordion .panel-body {
background-color: white;
}
.student-accordion .panel-group .panel-heading + .panel-collapse > .panel-body,
.student-accordion .panel-group .panel-heading + .panel-collapse > .list-group {
border-top: none;
}
.student-accordion .sa-h1 {
color: white;
font-size: 39px;
font-weight: bold;
font-style: normal;
font-family: "adelle-sans", sans-serif;
text-align: center;
}
.student-accordion .sa-h2 {
font-size: 28px;
padding-left: 3px;
font-family: "adelle-sans", sans-serif;
font-style: normal;
}
.student-accordion .sa-h3 {
font-size: 16px;
text-transform: capitalize;
font-weight: bold;
font-family: "adelle-sans", sans-serif;
font-style: normal;
}
.student-accordion .sa-h4 {
font-size: 14px;
font-family: "adelle-sans", sans-serif;
font-weight: normal;
font-style: normal;
}
.student-accordion .sa-h5 {
font-size: 12px;
text-transform: uppercase;
font-weight: bold;
font-family: "adelle-sans", sans-serif;
font-style: normal;
}
.student-accordion .sa-h6 {
font-size: 10px;
font-family: "adelle-sans", sans-serif;
font-weight: bold;
font-style: normal;
}
.student-accordion .sa-right-items {
float: left;
margin: -20px 0px;
}
.student-accordion .sa-answer,
.student-accordion .sa-score,
.student-accordion .sa-review,
.student-accordion .sa-report,
.student-accordion .sa-hide {
vertical-align: middle;
display: inline-block;
padding: 0px 22px;
}
.student-accordion .sa-report,
.student-accordion .sa-hide {
cursor: pointer;
}
.student-accordion .sa-hide-btn,
.student-accordion .sa-report-btn {
cursor: pointer;
}
.student-accordion .sa-section {
text-align: center;
}
.student-accordion .sa-section:after {
content: "";
border-right: 2px solid white;
display: block;
width: 1px;
position: absolute;
left: 96px;
top: -10px;
height: 110px;
overflow: hidden;
}
JS
'use strict';
define(['jquery', 'moment'], function($, moment) {
$(function() {
// Teacher Report
var report_type_car = $('#as-report-type-car');
var report_type_cdr = $('#as-report-type-cdr');
var report_type_title = $('#as-report-type-title');
var section_num = $('#as-section-num');
var problem_set = $('#as-problem-set');
var start_time = $('#as-start-time');
var due_time = $('#as-due-time');
var submit_am = $('#as-submit-am');
var submit_total = $('#as-submit-total');
var avg_score = $('#as-avgscore');
var danger = $('.pc-danger');
var warning = $('.pc-warning');
var success = $('.pc-success');
var danger_list = $('.pc-danger-list');
var warning_list = $('.pc-warning-list');
var success_list = $('.pc-success-list');
var student_am = $('#as-student-am');
var student_total = $('#as-student-total');
// Student Accordion
var assignment = $('#as-assignment');
var date = $('#as-date');
var correct_num = $('#as-correct-num');
var correct_total_num = $('#as-correct-total-num');
// Assignment SUmmary
var students_div = $('.as-students-div');
var student_div = $('.as-student-div');
// Student Report
var student_name = $('#as-student-name');
//SE Report Nav
var btn_ap = $('#btn-ap');
var btn_rmd = $('#btn-rmd');
// Percent Piechart
var percent_item = $('.percent-item');
var percent_skill = $('.percent-skill');
// Set this temporary until the BE for it is ready
var beTeacherNotDone = ['student', 'standard'];
var beStudentNotDone = ['section-exercise', 'course-benchmark', 'chapter-quiz', 'chapter-test', 'practice-test'];
function getReportTitle() {
var segmentArray = window.location.pathname.split('/');
var segment_4 = segmentArray[4];
var segment4Array = segment_4.split('-');
var newTitle = segment4Array[0] + " " + segment4Array[1];
return newTitle;
}
getReportTitle();
function updateReportHeaderBaseOnURL() {
if (lastSegment === 'student') {
btn_ap.addClass("hidden");
btn_rmd.addClass("hidden");
percent_skill.detach();
student_div.show();
students_div.hide();
} else if (lastSegment === 'assignment') {
btn_ap.removeClass("hidden");
btn_rmd.removeClass("hidden");
btn_ap.addClass("rn-btn-active");
percent_skill.detach();
student_div.hide();
students_div.show();
} else if ( $.inArray(lastSegment, beStudentNotDone) ) {
percent_skill.detach();
} else {
btn_ap.removeClass("hidden");
btn_rmd.removeClass("hidden");
btn_rmd.addClass("rn-btn-active");
percent_item.detach();
student_div.hide();
students_div.show();
}
}
updateReportHeaderBaseOnURL();
// console.log(window.rel_path+"teacher/report/"+lastSegment+"/"+lastSegment);
btn_ap.click(function() {
// btn_ap.href(href);
});
btn_rmd.click(function() {
// btn_rmd.href(href);
});
function parseUrl(url) {
var urlParamSplit = url.split("?");
if (urlParamSplit.length !== 2) {
return "InvalidUrlNoParamsSet";
}
var paramsList = urlParamSplit[1].split("&");
if (paramsList.length < 1) {
return "InvalidUrlNoParamsFound";
}
var paramsObj = {};
paramsList.forEach(function(item) {
var keyValueArray = item.split("=");
paramsObj[keyValueArray[0]] = keyValueArray[1];
});
return paramsObj;
}
var href = location.href;
var params = parseUrl(href);
var lastSegment = window.location.pathname.split('/').pop();
var assessmentId, classroomId;
function setAjaxEndpoint() {
if ($.inArray(lastSegment, beTeacherNotDone) || $.inArray(lastSegment, beStudentNotDone)) {
lastSegment = 'assignment'; // Use this one for now
}
}
setAjaxEndpoint();
function setDataParams() {
if ((params.assessmentId || params.classroomId) === undefined) {
//Set this temporary while waiting for BE to be ready
assessmentId = "206a9246-ce83-412b-b8ad-6b3e28be44e3";
classroomId = "722bfadb-9774-4d59-9a47-89ac9a7a8f9a";
} else {
assessmentId = params.assessmentId;
classroomId = params.classroomId;
}
}
setDataParams();
$.ajax({
url: "/BIM/rest/report/" + lastSegment,
type: "POST",
dataType: "json",
data: {
assessmentId: assessmentId,
classroomId: classroomId
},
success: function(objects) {
function updateAssignmentSummary(x) {
var header = objects.assignments[x].header;
var name = objects.assignments[x].name;
var car, cdr, report_type_full;
// Check for space in report_type
if (header.report_type.indexOf(' ') >= 0) {
if (getReportTitle() === "Section Exercise") {
report_type_full = header.report_type.split(/(\s+)/);
car = report_type_full[0];
cdr = report_type_full[2];
} else {
report_type_full = getReportTitle().split(" ");
car = report_type_full[0];
cdr = report_type_full[1];
}
report_type_car.html(car);
report_type_cdr.html(cdr);
report_type_title.html(car + " " + cdr + " " + header.section_num);
} else {
car = header.report_type;
report_type_car.html(car);
report_type_title.html(car + " " + header.section_num);
}
section_num.html(header.section_num);
problem_set.html(header.problem_set);
// Not show date if summary
if (name === "Summary") {
start_time.html(" ");
due_time.html(" ");
$("#as-due-time-div").hide();
$("#as-start-time-div").hide();
} else {
$("#as-due-time-div").show();
$("#as-start-time-div").show();
start_time.html(moment(parseInt(header.start_time)).format("MM/DD/YYYY h:mm A"));
due_time.html(moment(parseInt(header.due_time)).format("MM/DD/YYYY h:mm A"));
}
// For Student
if (header.student_name) {
student_name.html(header.student_name);
}
student_am.html(header.student_am);
student_total.html(header.student_total);
submit_am.html(header.submit_am);
submit_total.html(header.submit_total);
avg_score.html(header.avg_score);
// Temp
assignment.html("ALGEBRA 1 ");
date.html("2/10/2015");
correct_num.html("8");
correct_total_num.html("20");
danger.html(header.danger);
warning.html(header.warning);
success.html(header.success);
danger_list.html(header.danger_list);
warning_list.html(header.warning_list);
success_list.html(header.success_list);
}
function updatePercentPieChart() {
var data = {};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
var options = {
width: 160,
height: 160,
chartArea: {
left: 10,
top: 20,
width: "100%",
height: "100%"
},
colors: ['#F46E4E', '#F9C262', '#ADB55E', ],
legend: 'none',
enableInteractivity: false,
pieSliceText: 'none',
};
// Gather all the data
$.each(objects.assignments, function(i, v) {
var header = v.header;
var total = header.danger + header.warning + header.success;
data[i] = new google.visualization.arrayToDataTable([
['Piechart', 'Number of Skills'],
['danger', (header.danger / total) * 100],
['warning', (header.warning / total) * 100],
['success', (header.success / total) * 100],
]);
});
// Populate the dropdown-menu
$.each(objects.assignments, function(i, v) {
var name = v.name;
var assignmentId = v.assignmentId;
// Auto Populate the dropdown-menu
$("#as-dd.dropdown").append('<option value="' + assignmentId + '">' + name + '</option>');
// Dropdown-menu change
$('#as-dd').on('change', function() {
var i = $('option:selected', $(this)).index();
updateAssignmentSummary(i);
chart.draw(data[i], options);
});
});
// Initializing
updateAssignmentSummary("0");
chart.draw(data[0], options);
}
// Load the Visualization API and the piechart package.
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(updatePercentPieChart());
}
});
});
});
json can be read as objects, just use a for loop to iterate through the object array and create elements that way.
An important thing to keep in mind is that JSON, in JavaScript, should be treated as an regular Object Keeping that in mind let's say you got something like this from your AJAX call:
{
"average_grade": "B-",
"teacher": "Mrs. Yeltson",
"roster": 26
}
Now looking at your code, I would advise that you implement a templating solution. (It's not as bad as it sounds)
What we will do is label everything that should have the content will a special attribute for=teacher, like so:
<h1><span for="teacher">Loading...</span>'s Class</h1>
<h4>Class of <span for="roster">Loading..</span></h4>
<p>Averages a <span for="average_grade">Loading...</span></p>
And then when you get the results of the call, just fill in the span with the proper value:
$.getJSON("http://api.school.k12.us/api/class", function(data) {
for(res in data) {
$("[for="+res+"]").each(function() {$(this).text(data[res])})
}
})
And Volia! Now you have a templated way to fill in values from an AJAX call.
Hope I could help!

Categories