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

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!

Related

how to fix onClick button for append functions?

Here I work on a project where I want to implement open and close buttons but I am not able to do
currently, it's a close button for both, I need to add separate open and close buttons so that when the user clicks on open then it's open and when someones click on close then it should close properly also when I click continuously close then buttons freezes for sometime
Here is the demo of my JSFiddle Demo
please check the js Fiddle demo where buttons doesn't work properly
Here is the code
function createItem(item) {
var elemId = item.data("id");
var clonedItem = item.clone();
var newItem = $(`<div data-id="${elemId}"></div>`);
newItem.append(clonedItem);
newItem.appendTo('.item-append');
}
function countSaveItems() {
$('.count').html($(".item-append div.item-save[data-id]").length);
}
$('.item-all .item-save').click(function() {
$(this).toggleClass('productad')
window.localStorage.setItem('test_' + this.dataset.id, $(this).hasClass('productad'));
});
$('.item-all .item-save').each(function() {
var id = 'test_' + $(this).data("id");
$(this).append(`<button class='close'>Close</button>`);
if (localStorage.getItem(id) && localStorage.getItem(id) == "true") {
$(this).addClass('productad');
createItem($(this));
countSaveItems();
}
});
$(".item-all .item-save").click(function() {
var elemId = $(this).data("id");
var existing = $(`.item-append div[data-id="${elemId}"]`);
if (existing.length > 0) {
existing.remove();
} else {
createItem($(this));
}
countSaveItems();
});
$(".item-append").on("click", ".close", function() {
var id = $(this).parent().data("id");
localStorage.removeItem(`test_${id}`);
$(`.item-save[data-id='${id}']`).removeClass('productad');
$(this).parent().remove();
countSaveItems();
});
.item-save {
position: relative;
display: block;
font-size: 14px;
margin: 5px;
padding: 5px;
background: #a5a5a5;
float: left;
text-align: center;
cursor: pointer;
}
.productad {
background: red;
color: #eee
}
.count {
display: block;
background: #cbcbcb;
float: left;
font-size: 15px;
padding: 5px 18px;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='item-all'>
<div class='item-save' data-id='123'>
Save1
</div>
<div class='item-save' data-id='124'>
Save2
</div>
<div class='item-save' data-id='125'>
Save3
</div>
<div class='item-save' data-id='126'>
save4
</div>
</div>
<div class='item-append'>
</div>
<div class='count'>0</div>
Any Kind of help or suggestion is highly appreciated
To do the effect you need to add the open button into the HTML because that will be static, then switch between "Open" and "Close" when the user clicks into the "Open" or close the item, also needs to fix the local storage instead of removing in the close button just switch the value to false and validate based on that value. check the following code to see if that is what you are looking for:
function createItem(item){
var elemId = item.data("id");
var clonedItem = item.clone();
var newItem = $(`<div data-id="${elemId}"></div>`);
newItem.append(clonedItem);
clonedItem.children('.open').remove();
clonedItem.append(`<button class='close'>Close</button>`);
newItem.appendTo('.item-append');
}
function countSaveItems(){
$('.count').html($(".item-append div.item-save[data-id]").length);
}
$('.item-all .item-save').click(function() {
var id = $(this).data("id");
var lsId = `test_${id}`;
$(this).toggleClass('productad');
if (!$(this).hasClass('productad')){
window.localStorage.setItem(lsId, false);
$(this).children(".open").html("Open");
createItem($(this));
}else{
window.localStorage.setItem(lsId, true);
$(this).children(".open").html("Close");
$(`.item-append div[data-id='${id}']`).remove();
}
countSaveItems();
});
$('.item-all .item-save').each(function() {
var id = 'test_' + $(this).data("id");
if (localStorage.getItem(id) && localStorage.getItem(id) == "true") {
$(this).addClass('productad');
createItem($(this));
}
countSaveItems();
});
$(".item-all .item-save").click(function() {
var elemId = $(this).data("id");
var existing = $(`.item-append div[data-id="${elemId}"]`);
if (existing.length > 0){
existing.remove();
}else{
createItem($(this));
}
countSaveItems();
});
$(".item-append").on("click", ".close", function() {
var id = $(this).parent().data("id");
window.localStorage.setItem(`test_${id}`, false);
$(`.item-save[data-id='${id}']`).removeClass('productad');
$(`.item-save[data-id='${id}']`).children(".open").html("Open");
$(this).parent().parent().remove();
countSaveItems();
});
.item-save {
position: relative;
display: block;
font-size: 14px;
margin: 5px;
padding: 5px;
background: #a5a5a5;
float: left;
text-align: center;
cursor: pointer;
}
.productad {
background: red;
color: #eee
}
.count {
display: block;
background: #cbcbcb;
float: left;
font-size: 15px;
padding: 5px 18px;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='item-all'>
<div class='item-save' data-id='123'>
Save1 <button class='open'>Open</button>
</div>
<div class='item-save' data-id='124'>
Save2 <button class='open'>Open</button>
</div>
<div class='item-save' data-id='125'>
Save3 <button class='open'>Open</button>
</div>
<div class='item-save' data-id='126'>
Save4 <button class='open'>Open</button>
</div>
</div>
<div class='item-append'></div>
<div class='count'>0</div>

Can anyone help me pass this data? ;)

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)

Is there some kind of implementation or DOM I need?

I'm taking a beginner javascript/html/css course and don't have a super strong background in these. I'm trying to make a page that simulates a simple card game for a user versus the computer. The game takes digits that correspond to a card's suit and value and then displays them on the screen. Whoever has the higher card wins and a message is displayed.
This involves some things I'm not clear on, such as simple formatting or making the functions work together. I'm especially confused on where to put DOMs and how to even get a startbutton to work.
I'm using four functions:
randomizer
getcard
startgame
comparecard
In what ways can I make these interact with eachother? Are there any formatting issues in the css, html, etc.? Below is my initial code, I've tried too many variations and I'm just missing something I can't spot.
function randomizer(x) {
var y = x * Math.random();
var randNum = Math.round(y);
return randNum;
}
function getcard() {
var suit = randomizer(3);
var card = randomizer(13);
var wholeCard = suit + " " + card;
return wholeCard;
}
function startgame() {
var usercard;
var computercard;
usercard.getcard();
document.getElementByID("yourcard").innerHTML = usercard;
computercard.getcard();
document.getElementByID("computercard").innerHTML = computercard;
}
function comparecard() {
var usercard;
var computercard;
var winnermessage;
var usernum;
var computernum;
if (usernum > computernum) {
winnermessage = "You Win!";
} else if (usernum < computernum) {
winnermessage = "The Computer Wins!";
} else {
winnermessage = "It's a Tie!";
}
}
body {
font-family: Helvetica, Arial, sans-serif;
}
.cardcontain {
width: 80%;
margin: auto;
}
[class*="cardgrid"] {
float: left;
width: 45%;
text-align: center;
}
.cardgrid {
color: #aa4444;
}
.cardgrid2 {
display: block;
vertical-align: top;
color: #651e1e;
height: 110px;
font-size: 2em;
border: 2px solid #000000;
border-radius: 5px;
}
.cardgrid3 {
text-align: left;
color: #888888;
}
button {
background-color: #57ac75;
}
.winner::before {
display: block;
content: " ";
height: 400px;
}
.winner {
font-size: 24px;
font-weight: bolder;
color: #3f7a3b;
text-align: center;
}
<div class="cardcontain">
<h2 class="cardgrid">Computer Card</h2>
<h2 class="cardgrid">Your Card</h2>
</div>
<div class="cardcontain">
<div class="cardgrid2" id="computercard"></div>
<div class="cardgrid2" id="yourcard"></div>
</div>
<div class="cardcontain">
<div class="cardgrid">
<p> </p>
</div>
<div class="cardgrid"><button onclick="startgame()">Click here for your card</button></div>
</div>
<div class="cardcontain">
<div class="cardgrid3">
<h3>Key: first digit</h3>
<ul>
<li>0 = Spade</li>
<li>1 = Club</li>
<li>2 = Heart</li>
<li>3 = Diamond</li>
</ul>
</div>
<div class="cardgrid3">
<h3>Key: second digit</h3>
<ul>
<li>11 = Jack</li>
<li>12 = Queen</li>
<li>13 = King</li>
<li>14 = Ace</li>
</ul>
</div>
</div>
<p class="winner" id="winner"></p>
A few points
getcard probably needs to return the suit & value separately, as you need just the value to compare later on
Javascript is case sensitive so getElementByID is wrong (it is getElementById)
Where you had code like var usercard; and usercard.getcard(); makes no sense. getcard() is a standalone function which just returns a value so you probably wanted var usercard = getcard();
There are a bunch of other things which you will learn as you get better at javascript too broad for this answer
The below works along the lines I expect you thought
function randomizer(x) {
var y = x * Math.random();
var randNum = Math.round(y);
return randNum;
}
function getcard() {
var suit = randomizer(3);
var card = randomizer(13);
return {suit, card};
}
function startgame() {
var usercard = getcard();
var computercard = getcard();
document.getElementById("yourcard").innerHTML = usercard.suit + " " + usercard.card;
document.getElementById("computercard").innerHTML = computercard.suit + " " + computercard.card;
comparecard(usercard.card, computercard.card)
}
function comparecard(usernum, computernum) {
if (usernum > computernum) {
winnermessage = "You Win!";
} else if (usernum < computernum) {
winnermessage = "The Computer Wins!";
} else {
winnermessage = "It's a Tie!";
}
document.getElementById("winner").innerHTML = winnermessage;
}
body {
font-family: Helvetica, Arial, sans-serif;
}
.cardcontain {
width: 80%;
margin: auto;
}
[class*="cardgrid"] {
float: left;
width: 45%;
text-align: center;
}
.cardgrid {
color: #aa4444;
}
.cardgrid2 {
display: block;
vertical-align: top;
color: #651e1e;
height: 110px;
font-size: 2em;
border: 2px solid #000000;
border-radius: 5px;
}
.cardgrid3 {
text-align: left;
color: #888888;
}
button {
background-color: #57ac75;
}
.winner::before {
display: block;
content: " ";
height: 400px;
}
.winner {
font-size: 24px;
font-weight: bolder;
color: #3f7a3b;
text-align: center;
}
<div class="cardcontain">
<h2 class="cardgrid">Computer Card</h2>
<h2 class="cardgrid">Your Card</h2>
</div>
<div class="cardcontain">
<div class="cardgrid2" id="computercard"></div>
<div class="cardgrid2" id="yourcard"></div>
</div>
<div class="cardcontain">
<div class="cardgrid">
<p> </p>
</div>
<div class="cardgrid"><button onclick="startgame()">Click here for your card</button></div>
</div>
<div class="cardcontain">
<div class="cardgrid3">
<h3>Key: first digit</h3>
<ul>
<li>0 = Spade</li>
<li>1 = Club</li>
<li>2 = Heart</li>
<li>3 = Diamond</li>
</ul>
</div>
<div class="cardgrid3">
<h3>Key: second digit</h3>
<ul>
<li>11 = Jack</li>
<li>12 = Queen</li>
<li>13 = King</li>
<li>14 = Ace</li>
</ul>
</div>
</div>
<p class="winner" id="winner"></p>
Note: I have not fixed your randomizer but if you're generating playing cards I dont think you want to generate zeros... also if were going for realism you need to ensure the computer and player cant randomly pick the same card.

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

removeChild() parameter 1 not of type 'node'

I have some code for a shopping list, where there is a function to get rid of items.
For some reason, when I run that code on chrome, It returns this error in the console:
Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
at removeItem (index.html:59)
at addItem (index.html:50)
at HTMLAnchorElement.onclick (index.html:142)
Here is my code: (There may be some other errors like localStorage not working, but I can fix those. The real error I need help on is Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
at removeItem (index.html:59)
at addItem (index.html:50)
at HTMLAnchorElement.onclick (index.html:142))
<!DOCTYPE html>
<html>
<head>
<script src="https://use.fontawesome.com/6d2b2dd90b.js"></script>
<link href="https://fonts.googleapis.com/css?family=Encode+Sans+Expanded|Montserrat|Slabo+27px" rel="stylesheet">
<style>
li {
cursor: pointer;
}
ol {
text-align: center;
list-style-position: inside;
}
h1 {
font-family: 'Slabo 27px', sans-serif;
text-align: center;
font-size: 40px;
}
.form {
text-align: center;
}
input {
font-family: 'Encode Sans Expanded', sans-serif;
}
select {
font-family: 'Encode Sans Expanded', sans-serif;
}
a.test,
a:visited.test {
background-color: #f44336;
color: white;
padding: 8px 14px;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: pointer;
}
a:hover.test,
a:active.test {
background-color: red;
}
</style>
<script>
function addItem() {
var NewListItem = document.createElement("li");
NewListItem.innerHTML = document.getElementById("box").value;
var box2 = document.getElementById("box2").value;
if (box2 != "- Pick a category -") {
var x = document.getElementById(box2);
document.getElementById(box2).appendChild(NewListItem);
NewListItem.onclick = removeItem(box2);
document.getElementById("box").value = "";
saveList();
} else {
/*error*/
}
}
function removeItem(Type) {
/*if (confirm("Are you sure you want to delete this item?\n Ok = Yes\n Cancel = No") == true) {*/
document.getElementById(Type).removeChild(this);
saveList();
/*} else {
saveList();
}*/
}
function saveList() {
localStorage.storedList = document.getElementById("body").innerHTML;
}
function loadList() {
document.getElementById("body").innerHTML = localStorage.storedList;
for (var i = 0; i < document.getElementById("Pantry").children.length; i++) {
var node = document.getElementById("Pantry").children[i];
document.getElementById("Pantry").children[i].onclick = document.getElementById("Pantry").removeChild(node);
}
for (var k = 0; k < document.getElementById("Fridge").children.length; k++) {
var node2 = document.getElementById("Fridge").children[i];
document.getElementById("Fridge").children[k].onclick = document.getElementById("Fridge").removeChild(node2);
}
for (var d = 0; d < document.getElementById("Baking").children.length; d++) {
var node3 = document.getElementById("Baking").children[i];
document.getElementById("Baking").children[d].onclick = document.getElementById("Baking").removeChild(node3);
}
for (var f = 0; f < document.getElementById("Laundry + Bathroom").children.length; f++) {
var node4 = document.getElementById("Laundry + Bathroom").children[i];
document.getElementById("Laundry + Bathroom").children[f].onclick = document.getElementById("Laundry + Bathroom").removeChild(node4);
}
for (var b = 0; b < document.getElementById("Gardening").children.length; b++) {
var node5 = document.getElementById("Gardening").children[i];
document.getElementById("Gardening").children[b].onclick = document.getElementById("Gardening").removeChild(node5);
}
}
</script>
</head>
<body id="body">
<div class="h1">
<h1>Shopping List</h1>
</div>
<div class="form">
<input type="text" id="box" placeholder="Name of item">
<a onclick="addItem();" class="test"><i class="fa fa-plus-circle" aria-hidden="true"></i></a>
<br>
<select id="box2">
<option>- Pick a category -</option>
<option>Pantry</option>
<option>Fridge</option>
<option>Baking</option>
<option>Laundry + Bathroom</option>
<option>Gardening</option>
</select>
<br>
</div>
<br>
<fieldset>
<legend>Pantry</legend>
<ol id="Pantry" style="font-size: 110%; font-family: 'Montserrat', sans-serif;"></ol>
</fieldset>
<fieldset>
<legend>Fridge</legend>
<ol id="Fridge" style="font-size: 110%; font-family: 'Montserrat', sans-serif;"></ol>
</fieldset>
<fieldset>
<legend>Baking</legend>
<ol id="Baking" style="font-size: 110%; font-family: 'Montserrat', sans-serif;"></ol>
</fieldset>
<fieldset>
<legend>Laundry + Bathroom</legend>
<ol id="Laundry + Bathroom" style="font-size: 110%; font-family: 'Montserrat', sans-serif;"></ol>
</fieldset>
<fieldset>
<legend>Gardening</legend>
<ol id="Gardening" style="font-size: 110%; font-family: 'Montserrat', sans-serif;"></ol>
</fieldset>
<script>
if (localStorage.storedList) {
loadList();
}
</script>
</body>
</html>
I've looked at lots of other questions with the same error as me, but none of them have an answer that works with my code.
Thanks,
AlwardL
Notice how the error is thrown when adding an item?
NewListItem.onclick = removeItem(box2); is attempting to assign the value of the function call result to the click event.
You are passing a value, not a node, to the function: var box2 = document.getElementById("box2").value;
See DOM on-event handlers.

Categories