How to display multiple HTML entities in AJAX and JSON? - javascript

I need to display this the image below by using an AJAX call tto get tthe JSON file, parse the JSON into a Javascript object, and tthen display the Javascript object on the web page.
At the moment I have been able to display one star for each question in the "Difficulty" column. However, I can't figure outt how to display the correct amount of stars in relation to the JSON code.
Below is my JSON code and below that, the HTML code:
JSON:
{
"studentRefNumber": "BGX8P21R5",
"testResult": [
{
"questionNumber": 1,
"content": "Read a table to solve a problem",
"topic": "Chance & Data",
"correctAnswer": "C",
"yourAnswer": "C",
"difficultyLevel": 1
},
{
"questionNumber": 2,
"content": "Calculate the perimeter of a shape",
"topic": "Measures & Units",
"correctAnswer": "B",
"yourAnswer": "B",
"difficultyLevel": 2
},
{
"questionNumber": 3,
"content": "Solve a word problem involving speed of a vehicle",
"topic": "Algebra & Patterns",
"correctAnswer": "C",
"yourAnswer": "A",
"difficultyLevel": 2
},
{
"questionNumber": 4,
"content": "Solve a word problem involving multiple additions",
"topic": "Algebra & Patterns",
"correctAnswer": "C",
"yourAnswer": "C",
"difficultyLevel": 3
},
{
"questionNumber": 5,
"content": "Identify a shape reflected about a given axis",
"topic": "Space & Geometry",
"correctAnswer": "A",
"yourAnswer": "D",
"difficultyLevel": 5
},
{
"questionNumber": 6,
"content": "Solve a complex problem involving time",
"topic": "Measures & Units",
"correctAnswer": "D",
"yourAnswer": "A",
"difficultyLevel": 3
},
{
"questionNumber": 7,
"content": "Solve a complex problem involving fractions",
"topic": "Number & Arithmetic",
"correctAnswer": "B",
"yourAnswer": "B",
"difficultyLevel": 4
},
{
"questionNumber": 8,
"content": "Solve a complex equation involving two variables",
"topic": "Number & Arithmetic",
"correctAnswer": "C",
"yourAnswer": "B",
"difficultyLevel": 5
},
{
"questionNumber": 9,
"content": "Identify an object shown from a different position",
"topic": "Space & Geometry",
"correctAnswer": "B",
"yourAnswer": "B",
"difficultyLevel": 4
},
{
"questionNumber": 10,
"content": "Translate data table into a graph",
"topic": "Chance & Data",
"correctAnswer": "A",
"yourAnswer": "A",
"difficultyLevel": 1
}
]
}
HTML:
<html>
<head>
<script>
function makeAjaxQueryTestResult(){
//create XMLHttpRequest
var xhttp = new XMLHttpRequest();
//create a handler for the readyState change
xhttp.onreadystatechange = function() {
readyStateChangeHandler(xhttp);
};
//get JSON file by making async call
xhttp.open("GET", "Question4.json", true);
xhttp.send();
}
function readyStateChangeHandler(xhttp){
if (xhttp.readyState == 4){
// readyState = 4 means DONE
if(xhttp.status == 200){
// status = 200 means OK
handleStatusSuccess(xhttp);
}else{
// status is NOT OK
handleStatusFailure(xhttp);
}
}
}
// XMLHttpRequest failed
function handleStatusFailure(xhttp){
// display error message
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}
// XMLHttpRequest success
function handleStatusSuccess(xhttp){
var jsonText = xhttp.responseText;
// parse the json into an object
var testResultObj = JSON.parse(jsonText);
// display the object on the page
displayTestResult(testResultObj);
}
// display the object on the page
function displayTestResult(testResultObj){
// print the testResultObj on the console
// console.log(testResultObj);
// construct HTML code to display information
var html = "<h2>Test Result. Student Reference Number: " + testResultObj.studentRefNumber + "</h2>";
html += "You scored 6 out of 10";
html += "<br /><br />";
html += "<table border='1'>";
html += "<tr><th>Question</th><th>Content</th><th>Topic</th><th>Correct Answer</th><th>Your Answer</th><th>Difficulty</th></tr>";
for(var i=0; i < testResultObj.testResult.length; i++){
var testObj = testResultObj.testResult[i];
html += "<tr>";
html += "<td>" + testObj.questionNumber + "</td>";
html += "<td>" + testObj.content + "</td>";
html += "<td>" + testObj.topic + "</td>";
html += "<td>" + testObj.correctAnswer + "</td>";
if (testObj.yourAnswer == testObj.correctAnswer){
html += "<td align='center' style='color:green'>";
html += "✓";
html += "</td>";
}else{
html += "<td align='center'>" + testObj.yourAnswer + "</td>";
}
var starLvl = "⭐" * testObj.difficultyLevel;
html += "<td>" + starLvl + "</td>";
}
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = html;
}
</script>
</head>
<body>
<button onClick="makeAjaxQueryTestResult()">Get Test Result</button>
<br /> <br />
<div id="display">
</div>
</body>
</html>

You need to loop N times, corresponding to your difficulty level.
var starLvl = "";
for(let i=0; i < testObj.difficultyLevel; i++) {
starLvl += "⭐"; // concatenates N stars
}
html += "<td>" + starLvl + "</td>";

Related

Using object attribute as image source

I'm trying to pass the video object's image attribute as the source so I can display the image on the screen when the program runs. For obvious reasons, it can't find the source, because no file has the name 'videoObj1.image'. I was wondering if there is a workaround, maybe to take the text of the attribute and pass that as a source? Or even a way to directly use videoObj1.image. Thanks in advance.
Part of Question2.html where I try to use the image attribute as the source:
function displayVideo(videoObj){
var html = "<h1>Search Result " + "</h1>" + "<b>";
html += "Search keyword: " + videoObj.result.searchKeyword;
html += "<table>";
for(var i=0; i < videoObj.result.video.length; i++){
var videoObj1 = videoObj.result.video[i];
html += "<tr>";
html += "<td>" + "<img src=videoObj1.image>" + "</td>";
html += "<td align='right'>" + videoObj1.channel + "</td>";
html += "<td style='color:green' align='right'>";
html += videoObj1.view;
html += "<img src='stockUp.png' />";
html += "</td>";
html += "<td align='right'>" + videoObj1.link + "%</td>";
html += "</tr>";
}
html += "</table>";
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = html;
}
Question2.json:
{
"result": {
"searchKeyword": "Mathematics",
"video": [
{
"title": "Chaos Game",
"channel": "Numberphile",
"view": "428K",
"link": "http://www.youtube.com/watch?v=kbKtFN71Lfs",
"image": "http://i.ytimg.com/vi/kbKtFN71Lfs/0.jpg",
"length": "8:38"
},
{
"title": "Australian Story: Meet Eddie Woo, the maths teacher you wish you'd
had in high school",
"channel": "ABC News (Australia)",
"view": "223K",
"link": "http://www.youtube.com/watch?v=SjIHB8WzJek",
"image": "http://i.ytimg.com/vi/SjIHB8WzJek/0.jpg",
"length": "28:08"
},
{
"title": "Ham Sandwich Problem",
"channel": "Numberphile",
"view": "557K",
"link": "http://www.youtube.com/watch?v=YCXmUi56rao",
"image": "http://i.ytimg.com/vi/YCXmUi56rao/0.jpg",
"length": "5:53"
},
{
"title": "Magic Square Party Trick",
"channel": "Numberphile",
"view": "312K",
"link": "http://www.youtube.com/watch?v=aQxCnmhqZko",
"image": "http://i.ytimg.com/vi/aQxCnmhqZko/0.jpg",
"length": "3:57"
},
{
"title": "The 8 Queen Problem",
"channel": "Numberphile",
"view": "909K",
"link": "http://www.youtube.com/watch?v=jPcBU0Z2Hj8",
"image": "http://i.ytimg.com/vi/jPcBU0Z2Hj8/0.jpg",
"length": "7:03"
}
]
}
}
The problem is you're passing the string "videoObj1.image" to the img src attribute, which obviously is not going to work.
Rather you should pass the variable either by using classic string concatenation approach like this:
"<td><img src=" + videoObj1.image + "></td>";
OR
Using the recommended and modern template literals approach like this:
`<td><img src=${videoObj1.image}></td>`;

How do i correct the array index for accessing questions in the source code of quiz in Javascript language

I have created a quiz code in Javascript but when i inspect the program ,it is throwing an error for the line --> question=questions[index][0]. Here it says
Uncaught Typeerror :Cannot read of property "0" of undefined.
I do not know what is the solution. Of How else to read the questions array.I have defined the variables properly.Please help
var choiceA, choiceB, choiceC, choiceD, answer, element, correct = 0,
index;
var questions = [
["How many strokes in the Ashoka Chakra?", "12", "24", "32", "10", "B"],
["What is 30*2?", "60", "50", "20", "10", "A"],
[" What is largest fish? ", "Blue Whale", "Megaladon", "Hammer-head shark", "All the sharks", "B"],
["What is the currency of Europe and America respectively?", "Dollar and Euro", "Euro and Dollar", "Yen and Rupees", "Rupees and Yen", "B"],
["What is the seven wonders of the World amongst these?", "Taj Mahal", "Great Wall Of China", "Victoria Falls", "All of these", "D"],
["What is the main source of travel in Mumbai?", "Trains", "Aeroplane", "Autorickshaw", "Motorcycle", "A"],
["How many continents in the World?", "3", "4", "5", "6", "C"],
["What Ocean surrounds India ?", "Indian Ocean", "Pacific Ocean", "Atlantic Ocean", "Arctic Ocean", "A"],
["What station does not come in Mumbai-Railway-Western-Line?", "Sandhurst Road", "Andheri", "Borivali", "Naigaon", "A"],
["Who is the CEO of Google parent company- Alphabet Inc.?", "Madhuri Dixit", "Narendra Modi", "Tim Cook", "Sundar Pichai", "D"]
];
function selectQuestion() {
element = document.getElementById("select").innerHTML;
for (index = 0; index <= questions.length; index++) {
question = questions[index][0];
choiceA = questions[index][1];
choiceB = questions[index][2];
choiceC = questions[index][3];
choiceD = questions[index][4];
answer = questions[index][5];
element += question + "<br>";
element += "<input type='radio' name='choices' value='A'>" + choiceA + "<br>";
element += "<input type='radio' name='choices' value='B'>" + choiceB + "<br>";
element += "<input type='radio' name='choices' value='A'>" + choiceC + "<br>";
element += "<input type='radio' name='choices' value='B'>" + choiceD + "<br>";
element += "<input type='button' value='Submit' onclick='checkAnswer()'>" + "<br>";
}
}
function checkAnswer() {
var choice = document.getElementsByName("choices").values;
for (var index2 = 0; index2 <= choices.length; index2++) {
if (choices[index2].checked == choice) {
choice = answer;
}
}
if (choice == answer) {
correct++;
}
if (index == questions.length) {
alert("you have " + correct + "answers out of 10");
return false;
}
}
<html>
<head>
<title>Quiz code</title>
<style>
h1 {
text-align: center;
background-color: lightcoral;
}
#select {
text-align: center;
font-family: 'Trebuchet MS';
font-size: 20px;
}
</style>
</head>
<body onload="selectQuestion()">
<h1>QUIZ</h1>
<div id="select"></div>
</body>
</html>
It should be index < questions.length, because array index start from 0 and ends in n-1.
An array of length n will have index from 0 to n-1. So when you try to access element array[n] it will be undefined because there is no nth element in that array.
when you try to access array[n][0] you are trying to access undefined[0]. That is why it throws an error
for (index = 0; index < questions.length; index++) {
question = questions[index][0];
choiceA = questions[index][1];
choiceB = questions[index][2];
choiceC = questions[index][3];
choiceD = questions[index][4];
answer = questions[index][5];
}

How to separate items rendered from .getJSON by category prop

I've got a menu of coffee, for example, each with it's own parentCategory and I want to render them on the page like so but I'm not entirely sure where to start:
category title
item
item
item
item
category title
item
item
My data model looks like this:
{ "menuItems": [
{
"index": 0,
"parentCategory": "Americanos",
"calories": 234,
"name": "Caffè Americano",
"photos": {
"squareThumb": "http://www.starbucks.com/assets/67c30b9dacd4406db797b1690ac22475.jpg"
}
}, {
"index": 0,
"parentCategory": "Lattes",
"calories": 234,
"name": "Caffè Latte",
"photos": {
"squareThumb": "http://www.starbucks.com/assets/aee68ca3048142f38741f20b30b7a581.jpg"
}
}, {
"index": 0,
"parentCategory": "Mochas",
"calories": 234,
"name": "Caffè Mocha",
"photos": {
"squareThumb": "http://www.starbucks.com/assets/bc15a5ca9d744b66bda07254f2f50013.jpg"
}
}...
and my current script looks like so:
$.getJSON('menu.json', function(drinks) {
var getMenuItem = drinks.menuItems;
var sortedArray = getMenuItem.sort(function(a,b){
return a.parentCategory > b.parentCategory ?1 :-1
})
var output = "";
for (var i in sortedArray) {
output += "<div class='menuItem'><p>" + drinks.menuItems[i].name + "</p><img src='" + drinks.menuItems[i].photos.squareThumb + "'/></div>";
}
document.getElementById("demo").innerHTML=output;
});
Keep the latest category in a variable. Whenever the category changes, start a new <div> for the category.
var last_cat = null;
var output = "";
for (var i in sortedArray) {
var item = sortedArray[i];
if (item.parentCategory != last_cat) {
if (last_cat) { // close the previous category
output += "</div>";
}
output += "<div class='category'><p>" + item.parentCategory + "</p>";
last_cat = item.parentCategory;
}
output += "<div class='menuItem'><p>" + item.name + "</p><img src='" + item.photos.squareThumb + "'/></div>";
}
if (last_cat) {
output += "</div>";
}

How to add table headers to dynamically generated table containing Ajax data?

I am attempting to dynamically add the table header from the JSON data.
I need to generate the header (th) as well so that it is not done manually.
I have a very basic working example: And I am familiar with the JQuery solution, however, I would like to do this in a JavaScript only approach:
Some JSON formatted data:
var value = [{
"City": "KABUL",
"Continent": "ASIA",
"Country": "AFGHANISTAN",
"CountryAbbr": "AF",
"CountryId": "102120"
}, {
"City": "MARIEHAMN",
"Continent": "EUROPE",
"Country": "ALAND ISLANDS",
"CountryAbbr": "AX",
"CountryId": "102115"
}];
JavaScript:
var out = "<table>";
for ( var i = 0; i < value.length; i++) {
out += "<tr><td>" + value[i].Country +
"</td><td>" + value[i].City +
"</td><td>" + value[i].CountryAbbr +
"</td></tr>";
}
out += "</table>";
document.getElementById("tableContainer").innerHTML = out;
HTML:
<div id="tableContainer"></div>
A working fiddle:
dynamically generated table containing Ajax data
If you are talking about table header/heading.then the below code is helpful to you:
var value = [{
"City": "KABUL",
"Continent": "ASIA",
"Country": "AFGHANISTAN",
"CountryAbbr": "AF",
"CountryId": "102120"
}, {
"City": "MARIEHAMN",
"Continent": "EUROPE",
"Country": "ALAND ISLANDS",
"CountryAbbr": "AX",
"CountryId": "102115"
}];
var out = "<table>";
out+="<tr><th>Country</th><th>City</th><th>Country Code</th></tr>";//TABLE HEADER/HEADING----------
for ( var i = 0; i < value.length; i++ ) {
out += "<tr><td>" + value[i].Country +
"</td><td>" + value[i].City +
"</td><td>" + value[i].CountryAbbr +
"</td></tr>";
}
out += "</table>";
document.getElementById("tableContainer").innerHTML = out;

on change of div based drop down jquery

I have a drop down based on a JSON Object and the purpose of this to render a drop down box.
var Regions =
{
"ErrorInfo": {
"Success": true,
"ErrorCode": "",
"Program": "",
"Method": "",
"Message": "",
"Details": "",
"StackTrace": "",
"ErrorList": null
},
"Results": {
"DimName": "region",
"SubsetName": "",
"Members": [{
"ID": "CEurope",
"Name": "Central Europe",
"Children": [],
"Hierarchy": [],
"Attributes": []
},
{
"ID": "SEurope",
"Name": "Southern Europe",
"Children": null,
"Hierarchy": [],
"Attributes": []
}]
}
};
//var htmlStr = '';
var icount=0;
var mySelect = $('#options');
var optionsValues = '<select>';
$.each(Regions, function(){
optionsValues += '<option value="' + Regions.Results.Members[icount].ID + '">' + Regions.Results.Members[icount].Name + '</option>';
icount=icount+1;
});
optionsValues += '</select>';
var options = $('#options');
options.replaceWith(optionsValues);
This is my Javascript which is working but happy to refine the code so that I can learn the finer points of JS.
My HTML is like this
<!DOCTYPE html>
<html>
<head>
<title>JavaScript & jQuery - Chapter 13: Form Enhancement and Validation - Populate a selectbox</title>
<link rel="stylesheet" href="css/c13.css" />
</head>
<body>
<form name="howHeard" id="howHeard" action="/heard" method="post">
<div id="page">
</div>
<div id="options">
</div>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/124.js"></script>
</body>
</html>
My question is how do I detect an on change event of my drop down list.
Any help would be appreciated as I learn through the maze of jquery javascript etc.
Cheerio
This should do it:
options.change(function() {
alert( "It changed!" );
});
ref: https://api.jquery.com/change/
Some refinement in your JS:
//var icount=0; ->Not needed
//var mySelect = $('#options'); ->Not needed
var optionsValues = '<select id="mySelect">';
$.each(Regions, function(index){
optionsValues += '<option value="' + Regions.Results.Members[index].ID + '">' + Regions.Results.Members[index].Name + '</option>';
//icount=icount+1;-> Not needed
});
optionsValues += '</select>';
var options = $('#options');
options.replaceWith(optionsValues);
Basically for the above set-up, below code should work:
$("#mySelect").on('change',function(){
//do stuff here
});
Or if its dynamic element the below should definitely work:
$(document).on('change',"#mySelect",function(){
//do stuff here
});
UPDATE
WORKING DEMO TO CLARIFY YOUR DOUBTS
Bit more refinement on your JS:
var members=Regions.Results.Members; //Get all the members in a single variable
var optionsValues = '<select id="mySelect">';
//loop here for only member variables
$.each(members, function(index,value){
optionsValues += '<option value="' + value.ID + '">' + value.Name + '</option>';
});
optionsValues += '</select>';
var options = $('#options');
options.replaceWith(optionsValues);

Categories

Resources