I am trying to link together an object in JS to a function of a button in Jquery. I've linked Jquery to my HTML so it is technically working, however, it's a specific project that is requiring the buttons to display the info. in the object. I've tried editing it on my own and I keep getting stuck and I'm not sure how to link the two. The instructions are included as well.
// create a JavaScript object here with the following fields: firstName, lastName, jobTitle, homeOffice
function About(firstName, lastName, jobTitle, homeOffice, tellMeMore) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.homeOffice = homeOffice;
this.tellMeMore = tellMeMore;
};
var about01 = new About("Megan", "Adams", "Customer Serice Rep", "Penn Field", "I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art.");
// using jQuery and the object above, display the information as the appropriate button is clicked
var button = document.querySelectorAll ('button');
$(document).ready(function() {
$(".button").click(function() {
$(".name").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button1").click(function() {
$(".job").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button2").click(function() {
$(".office").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button3").click(function() {
$(".more").fadeToggle(1000);
});
});
<!DOCTYPE html>
<html>
<head>
<title role="title">CEP Engineering Application</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body>
<article>
<header role=banner>
<h1>About Me</h1>
</header>
<img src="img/IMG_1989.jpg" alt="Megan Adams Picture" style="width:250px;height:460px; "class="img">
<section>
<button type="button" class="button">Name</button>
<p class="name">Megan Adams</p>
</section>
<section>
<button type="button" class="button1">Job Title</button>
<p class="job">Customer Service Reo</p>
</section>
<section>
<button type="button" class="button2">Home Office</button>
<p class="office">Penn Field</p>
</section>
<section>
<button type="button" class="button3">Tell Me More</button>
<p class="more">I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art. </p>
</section>
<script src="init.js"></script>
</article>
</body>
</html>
I have edited both the code and html and made them much smaller.
now have a look at attribute data and read the comment to understand, how this work.
// create a JavaScript object here with the following fields: firstName, lastName, jobTitle, homeOffice
function About(firstName, lastName, jobTitle, homeOffice, tellMeMore) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.homeOffice = homeOffice;
this.tellMeMore = tellMeMore;
};
var about01 = new About("Megan", "Adams", "Customer Serice Rep", "Penn Field", "I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art.");
// using jQuery and the object above, display the information as the appropriate button is clicked
var button = document.querySelectorAll ('button');
$(document).ready(function() {
// present the values,
$("section > p").each(function(){
// more dynamic approch
var field = $(this).attr("data");
var value ="";
if (field){
field.split(" ").forEach((x)=> {
if (value== "")
value = about01[x];
else value += " " + about01[x] // firstName and lastName
});
$(this).html(value)
}
});
// now you only need one method click to display toggle p
$(".button").click(function() {
// you know that p exist under button
// so go back to parent of the current object and then find the p and toggle it.
$(this).parent().find("p").fadeToggle(1000);
});
});
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<article>
<header role=banner>
<h1>About Me</h1>
</header>
<img src="img/IMG_1989.jpg" alt="Megan Adams Picture" style="width:250px;height:460px; "class="img">
<section>
<button type="button" class="button">Name</button>
<p data="firstName lastName" ></p>
</section>
<section>
<button type="button" class="button">jobTitle</button>
<p data="jobTitle"></p>
</section>
<section>
<button type="button" class="button">homeOffice</button>
<p data="homeOffice"></p>
</section>
<section>
<button type="button" class="button">Tell Me More</button>
<p data="tellMeMore"> </p>
</section>
<script src="init.js"></script>
</article>
Only a single jQuery() is necessary. You can use get the property names of the object using Array.prototype.keys() convert the className of current element .toLowerCase() within .html(), .filter() the property names where .indexOf() className of the current element is greater than -1, .map() and .join() the result
$(function() {
function About(firstName, lastName, jobTitle, homeOffice, tellMeMore) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.homeOffice = homeOffice;
this.tellMeMore = tellMeMore;
};
const about01 = new About("Megan", "Adams", "Customer Serice Rep", "Penn Field", "I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art.");
const keys = Object.keys(about01);
$(".name, .job, .office, .more").html(function() {
const el = this;
return keys.filter(function(value) {
return value.toLowerCase()
.indexOf(el.className) > -1
})
.map(function(value) {
return about01[value]
}).join(" ")
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<body>
<div class="name"></div>
<div class="job"></div>
<div class="office"></div>
<div class="more"></div>
</body>
You only need to use one document.ready method in your JS.
What you can do to achieve this is add a click event listener to all your buttons. Then when a button is clicked you can refer to the button clicked using $(this). The element which you want to append text to is the paragraph next to the button clicked. You can get the paragraph element by using $(this).next('p'). Using the class name of the paragraph you can then work out which object property to display.
Below, I have used an object called classToProp which maps your class names to strings retrieved from your About object. Using this you can display the specific information you want to the adjoining p tag.
See working example below:
function About(firstName, lastName, jobTitle, homeOffice, tellMeMore) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.homeOffice = homeOffice;
this.tellMeMore = tellMeMore;
};
var about01 = new About("Megan", "Adams", "Customer Serice Rep", "Penn Field", "I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art.");
var classToProp = {
name: about01.firstName + " " + about01.lastName,
job: about01.jobTitle,
office: about01.homeOffice,
more: about01.tellMeMore
}
$(document).ready(function() {
$("button").click(function() {
var nextP = $(this).next('p');
var className = nextP.attr("class");
var txt = nextP.text(); // get the text from the paragraph
nextP.text(txt ? "" : classToProp[className]); // if the text is empty, display the associated property from your object, otherwise, if it already has text make it empty - this allows for a toggle effect
});
})
<!DOCTYPE html>
<html>
<head>
<title role="title">CEP Engineering Application</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body>
<article>
<header role=banner>
<h1>About Me</h1>
</header>
<img src="img/IMG_1989.jpg" alt="" style="width:250px;height:460px; " class="img">
<section>
<button type="button" class="button">Name</button>
<p class="name"></p>
</section>
<section>
<button type="button" class="button1">Job Title</button>
<p class="job"></p>
</section>
<section>
<button type="button" class="button2">Home Office</button>
<p class="office"></p>
</section>
<section>
<button type="button" class="button3">Tell Me More</button>
<p class="more"></p>
</section>
<script src="init.js"></script>
</article>
</body>
</html>
Do you want something like below using jQuery $(selector).html(value);
// create a JavaScript object here with the following fields: firstName, lastName, jobTitle, homeOffice
function About(firstName, lastName, jobTitle, homeOffice, tellMeMore) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.homeOffice = homeOffice;
this.tellMeMore = tellMeMore;
};
var about01 = new About("Megan", "Adams", "Resolutions Specialist", "Penn Field", "I have been working at HomeAway in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art.");
$(".name").html(`${about01.firstName} ${about01.lastName}`);
$(".job").html(about01.jobTitle);
$(".office").html(about01.homeOffice);
$(".more").html(about01.tellMeMore);
// using jQuery and the object above, display the information as the appropriate button is clicked
var button = document.querySelectorAll('button');
$(document).ready(function() {
$(".button").click(function() {
$(".name").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button1").click(function() {
$(".job").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button2").click(function() {
$(".office").fadeToggle(1000);
});
});
$(document).ready(function() {
$(".button3").click(function() {
$(".more").fadeToggle(1000);
});
});
button {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title role="title">CEP Engineering Application</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body>
<article>
<header role=banner>
<h1>About Me</h1>
</header>
<img src="img/IMG_1989.jpg" alt="Megan Adams Picture" style="width:250px;height:460px; " class="img">
<section>
<button type="button" class="button">Name</button>
<p class="name">Megan Adams</p>
</section>
<section>
<button type="button" class="button1">Job Title</button>
<p class="job">Customer Service Reo</p>
</section>
<section>
<button type="button" class="button2">Home Office</button>
<p class="office">Penn Field</p>
</section>
<section>
<button type="button" class="button3">Tell Me More</button>
<p class="more">I have been working at in customer service since December 2018 and transferred over to the Resolutions Department in fall of 2018. In my spare time I love watching scary movies, listening to true crime podcasts and music, and making art. </p>
</section>
<script src="init.js"></script>
</article>
</body>
</html>
Related
Last Update
I realized why I was getting undefined when I created the result2 variable I set it to undefined instead of let result2 = ''; setting it to a string. Once I made that adjustment the undefined went away. Final script.js is below.
Update 4
It finally works it came down to the following line which was incorrect document.querySelectorAll("weathers").innerHTML = result2; I had to go back and change weathers to an id and not a class and I had to change the line above to document.querySelector("#weathers").innerHTML += result2; and now it works. I just have to figure out on my own why I get an undefined in my code see image.
Update 3
I am down to my last portion which is I get the results I want if I console log my results which look like this:
With this line I am not getting anything in my html document.querySelectorAll("weathers").innerHTML = result2; I am going to try something else to see if I could get this to work. If you notice though I am getting an undefined in my code in the image does anyone know if that impacts why I am not getting any output? I get no error messages either.
UPDATE 2
I made the adjustments to eliminate too much code the updates code will just be in my script.js file listed below. I get the following output which is an array of objects:
When I run the code I get the following error message:
Uncaught TypeError: Cannot read property 'name' of undefined
at XMLHttpRequest.xhr2.onload (script.js:57) xhr2.onload # script.js:57 load (async) loadWeathers # script.js:33
I am going to work on the correct syntax to extract the information I need since it is now an array of objects and not just an object.
UPDATE 1
With a suggestion below I was able to finally get something to work off of. Now I can see that instead of giving me one city at a time it is putting all of the cities inside of the api request url and I get the following error message:
script.js:77 GET
http://api.openweathermap.org/data/2.5/weather?q=San_Francisco,Miami,New_Orleans,Chicago,New_York_City&APPID=XXXXXXXX
404 (Not Found)
Background:
I am learning about API's and am building a mini weather web app. I am learning the long way Vanilla Javascript before I move onto doing the same thing in Jquery.
Goal:
I would like to have two things going on at once:
When a user inputs a name of a city a card will pop up with weather information.
When a user visits the page there will be already about five major cities populated on the page like so:
What I have so far:
So far I have been able to build the functionality for the input so when a user inputs the name of the city a card will pop up on the page and looks like this:
I also have some code to get into the next topic which is my problem.
Problem:
I have added a second ajax call that contains an array of cities that will be added to the URL. I have added a second button ("Get Weathers") for testing purposes that when I click on the button all of the cities will pop up like in the first image. I have done some research but everything I find involves jquery and not vanilla javascript Ajax. I cannot figure out why nothing is populating. I have checked the console for errors and I am not getting any. When I check the network traffic I am not getting any call requests. I am not getting anything and I cannot figure out why.
Here is my html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<LINK REL=StyleSheet HREF="style.css" TYPE="text/css">
<title>Current Weather App</title>
</head>
<body>
<main role="main">
<section class="jumbotron text-center">
<div class="container">
<h1 class="jumbotron-heading">Today's Weather</h1>
<p class="lead text-muted">Curious about weather in your location? Just fill in below and submit.</p>
<p>
<div class="input-group mb-3">
<input type="text" class="form-control" id="city">
<div class="input-group-append">
<button class="btn btn-outline-secondary" id="buttonW" type="button">Get Weather</button>
<button class="btn btn-outline-secondary" id="buttonW2" type="button">Get Weathers</button>
</div>
</div>
</p>
</div>
</section>
<div id="weather"></div>
<div class="album py-5 bg-light">
<div class="container">
<div class="row" id="weathers"></div>
</div>
</div>
</main>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">
</script>
<script src="script.js"></script>
</body>
</html>
Here is my FINAL script.js file:
// Create an event listener
document.getElementById("buttonW").addEventListener("click", loadWeather);
document.getElementById("buttonW2").addEventListener("click", loadWeathers);
///////////////THIS IS PART OF THE loadWeathers///////////////////////////////////////////////////////////////////////////////////////////
function getCity(locations) {
for (let i = 0; i < locations.length; i++) {
}
return locations;
}
function loadWeathers() {
let xhr2 = new XMLHttpRequest();
const cities = [
"5368361",
"4173495",
"4335045",
"4887398",
"5128638"
];
const base_path2 =
"http://api.openweathermap.org/data/2.5/group?id=" + getCity(cities) + "&APPID=XXXXXXXXXXXXXXXXXXXXXX";
xhr2.open("GET", base_path2, true);
xhr2.onload = function () {
if (this.status == 200) {
let cityWeathers2;
try {
cityWeathers2 = JSON.parse(this.responseText);
} catch (e) {
// JSON not valid, show error message
}
console.log(cityWeathers2)
// //add weather info
for (let i = 0; i < cities.length; i++) {
let result2 = '';
result2 +=
`<div class="col-md-4">
<div class="card mb-4 box-shadow">
<div class="card-body">
<h5 class="card-title">${cityWeathers2.list[i].name}</h5>
<p class="card-text">Here are some weather details for your City</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">Weather: ${cityWeathers2.list[i].weather[0].main} <img class="card-img-top weather-icon" src="${getIconURL(cityWeathers2.list[i].weather[0].icon)}" alt="Card image cap"></li>
<li class="list-group-item">Temperature: ${convertKtoF(cityWeathers2.list[i].main.temp) }° </li>
<li class="list-group-item">Wind Speed: ${convertMPStoMPH(cityWeathers2.list[i].wind.speed) } </li>
<li class="list-group-item">Geo Location: ${cityWeathers2.list[i].coord.lat} , ${cityWeathers2.list[i].coord.lon}</li>
</ul>
</div>`
// console.log(result2)
document.querySelector("#weathers").innerHTML += result2;
}
}
}
xhr2.send();
}
function loadWeather() {
// console.log(city);
let xhr = new XMLHttpRequest();
const city = document.getElementById("city").value;
const base_path =
"http://api.openweathermap.org/data/2.5/weather?q=" + city + "&APPID=XXXXXXXXXXXXXXXXXXXXXXX";
xhr.open("GET", base_path, true);
xhr.onload = function () {
// const city = document.getElementById("city").value;
if (this.status == 200) {
let cityWeathers;
try {
cityWeathers = JSON.parse(this.responseText);
} catch (e) {
// JSON not valid, show error message
}
const result =
`<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">${cityWeathers.name}</h5>
<p class="card-text">Here are some weather details for your City</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">Weather: ${cityWeathers.weather[0].main} <img class="card-img-top weather-icon" src="${getIconURL(cityWeathers.weather[0].icon)}" alt="Card image cap"></li>
<li class="list-group-item">Temperature: ${convertKtoF(cityWeathers.main.temp) }° </li>
<li class="list-group-item">Wind Speed: ${convertMPStoMPH(cityWeathers.wind.speed) } </li>
<li class="list-group-item">Geo Location: ${cityWeathers.coord.lat} , ${cityWeathers.coord.lon}</li>
</ul>
</div>`;
document.getElementById("weather").innerHTML = result;
}
}
xhr.send();
}
// Convert from Kelvins to Fahrenheit
function convertKtoF(kelvin) {
return Math.round((kelvin - 273.15) * 1.8);
}
// Convert from Meters Per Second to Miles Per Hour
function convertMPStoMPH(mps) {
return (Math.round(10 * mps * 2.2369362920544) / 10) + " mph";
}
// Weather icon
function getIconURL(icon) {
return "https://openweathermap.org/img/w/" + icon + ".png";
}
Any guidance or suggestions would be greatly appreciated!
I can't speak to the accuracy of the request (per comments), but the problem is xhr2.send(); is within the body of your xhr2.onload function.
For multiple cities, you may need to use city Ids, see https://openweathermap.org/current#severalid. The docs don't seem to mention multiple cities by name as you are attempting to do.
So, Im creating a HTML file which has buttons with labels like: First Name, Last name, etc
I need to program the button so that when user clicks it the Fist name button should go away and in the <div> you instead see the name "John Doe"
I've created this in my .js file:
// create a JavaScript object here with the following fields: firstName, lastName, jobTitle, homeOffice
var demo = {
firstName : "Waseem",
lastName : "Qazi",
jobTitle : "Traveler Care",
homeOffice : "Penn. field",
tellMeMore : "Exicted to re-start my coding adventure again. Been a while
since I had coded. Looking forward to all the learning and growth this
amazing oppportunity will present."
givefirstname : function() {
return this.firstName;
};
using jQuery and the object above, display the information as the appropriate button is clicked.
How do I call this in HTML file so that each function gives the corresponding data back on the screen?
my call line in HTML file:
<li>
<a class="selected" href="">
<button type="button" onclick=demo.givefirstname>
First Name
</button>
</a>
</li>
<br>
You can either replace, or hide/show some dom elements. I'm going to go with the latter. I'm also going to make the giveFirstName method a showValue method so it's more flexible.
var demo = {
firstName : "Waseem",
lastName : "Qazi",
jobTitle : "Traveler Care",
homeOffice : "Penn. field",
tellMeMore : "Exicted to re-start my coding adventure again. Been a while since I had coded. Looking forward to all the learning and growth this amazing oppportunity will present.",
showValue : function(key, el) {
el.getElementsByTagName('span')[0].style.display = 'none';
var paragraph = el.getElementsByTagName('span')[1];
paragraph.style.display = 'inline';
paragraph.innerHTML = this[key];
},
}
p.value {
display: none;
}
<li>
<a class="selected" onclick="demo.showValue('firstName', this)">
<span class="title">First Name</span>
<span class="value"></span>
</a>
</li>
You need to call the function, and you need to add code that replaces the button with what it returns.
In the code below I've changed the <a> to <div>, since you can't have a button inside an anchor, and clicking on the anchor would try to follow the link.
var demo = {
firstName: "Waseem",
lastName: "Qazi",
jobTitle: "Traveler Care",
homeOffice: "Penn. field",
tellMeMore: `Exicted to re-start my coding adventure again. Been a while
since I had coded.Looking forward to all the learning and growth this
amazing oppportunity will present.`,
givetitle: function() {
return this.jobTitle;
},
givefirstname: function() {
return this.firstName;
},
givelastname: function() {
return this.lastName;
}
};
function replaceMe(element, contents) {
element.parentElement.innerHTML = contents;
}
<ul>
<li>
<div class="selected">
<button type="button" onclick="replaceMe(this, demo.givefirstname())">
First Name
</button>
</div>
</li>
<li>
<div class="selected">
<button type="button" onclick="replaceMe(this, demo.givelastname())">
Last Name
</button>
</div>
</li>
<li>
<div class="selected">
<button type="button" onclick="replaceMe(this, demo.givetitle())">
Job Title
</button>
</div>
</li>
</ul>
I'm learning how to build a website and I am having problems with the following
code. I can't figure out what is going on with it at all. I'm using visual studio code to write this in.
var HtmlCode = {
GetMenuItem:function(item){
let plg = item.choices[0];
let prg = item.choices[1];
let lbl_plg = '${item.type} - ${item.name} - ${plg.size}';
let lbl_prg = '${item.type} - ${item.name} - ${prg.size}';
return '<div class= "menu-item"> <div><div><img src="${item.img}"></div><div>${item.name}</div> </div><div>${item.descr}</div> <div> <div act="add2order" id="${plg.id}" cost="${plg.cost}" lbl="${plg_lbl}" title="Click to order">${plg.txt}</div> <div act="add2order" id="${prg.id}" cost="${prg.cost}" lbl="${prg_lbl}" title="Click to order">${prg.txt}</div> </div> </div>';
}
}
When I clean up the (return) and put it so I don't have to scroll to the right I get all sorts of errors in the visual studio code editor. I have it all together now on one line as shown in the example and it returns something but it won't return the menu items. I get all the items such as ${item.name} etc. but no img or any thing from my menu.
var App = {
Menu:null,
Init:function(){
this.Menu = JoesPizza.Menu;
$("#PizzaOrderSubmit").click(this.OrderNext);
},
LoadMenu:function(){
$("#MenuItemList").html("");
this.Menu.items.forEach(item => {
let html = HtmlCode.GetMenuItem(item);
$("#MenuItemList").append(html);
});
// attach click events to new menu items
}
}
var JoesPizza = JoesPizza||{};
JoesPizza.Menu = {"items":[
{"type":"Pizza", "name":"Cheese", "descr":"Marinara sauce topped with whole milk mozzarella cheese.",
"choices":[{"id":"pizza-cheese-lg", "size":"Large", "cost":22.99, "txt":"Large: $22.99"},
{"id":"pizza-cheese-rg", "size":"Regular", "cost":18.99, "txt":"Regular: $18.99"}],
"img":"/imgs/cheese.png"},
{"type":"Pizza", "name":"Pepperoni", "descr":"Marinara sauce with authentic old-world style pepperoni.",
"choices":[{"id":"pepp-lg", "size":"Large", "cost":23.99, "txt":"Large: $23.99"},
{"id":"pepp-rg", "size":"Regular", "cost":19.99, "txt":"Regular: $19.99"}],
"img":"/imgs/pepperoni.png"},
{"type":"Pizza", "name":"Meat Lover's", "descr":"Marinara sauce, authentic pepperoni, natural Italian sausage, roasted ham, smoked bacon, pork and beef.",
"choices":[{"id":"meat-lg", "size":"Large", "cost":23.99, "txt":"Large: $23.99"},
{"id":"meat-rg", "size":"Regular", "cost":19.99, "txt":"Regular: $19.99"}],
"img":"/imgs/meat.png"},
{"type":"Pizza", "name":"Supreme", "descr":"Marinara sauce, pepperoni, pork, beef,fresh mushrooms, fresh green bell peppers and fresh red onions.",
"choices":[{"id":"supr-lg", "size":"Large", "cost":23.99, "txt":"Large: $23.99"},
{"id":"supr-rg", "size":"Regular", "cost":19.99, "txt":"Regular: $19.99"}],
"img":"/imgs/supreme.png"},
{"type":"Wings", "name":"Traditional Bone-in", "descr":"Classic, juicy bone-in wings served perfectly crispy and tossed in your choice of signature sauce.",
"choices":[{"id":"wings-trad-12", "size":"12 Pieces", "cost":11.99, "txt":"12 Wings: $11.99"},
{"id":"wings-trad-08", "size":"8 Pieces", "cost":8.99, "txt":"8 Wings: $8.99"}],
"img":"/imgs/wings.png"}
]};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF8"/>
<title>Joe's Pizza</title>
<link type="text/css" rel="stylesheet" href="/css/app.css"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/menu.js"></script>
<script type="text/javascript" src="/js/html-templates.js"></script>
<script type="text/javascript" src="/js/app.js"></script>
</head>
<body>
<!-- top banner -->
<div class="page-top">
<img src="/imgs/pizza.png" title="Pizza Picture"/>
<span>joe's pizza</span>
<a href="/">
<img src="/imgs/home.png"></a>
</div>
<!-- page body -->
<div class="page-body">
<div class="side-left">
<div id="PizzaMenuHtml">
<fieldset id="PizzaMenu">
<legend>menu</legend>
<div id="MenuItemList">
</div>
</fieldset>
</div>
</div>
<div class="side-right">
<fieldset id="PizzaOrder">
<legend>your order</legend>
<div id="PizzaOrderItems">
</div>
<div id="PizzaOrderSummary">
<div>Order Total:</div>
<div></div>
</div>
<div id="PizzaOrderSubmit">Next >>></div>
</fieldset>
</div>
</div>
<div class="page-footer">
</div>
<script type="text/javascript">
App.Init();
App.LoadMenu();
</script>
</body>
</html>
When I clean up the (return) and put it so I don't have to scroll to the right I get all sorts of errors in the visual studio code editor.
Strings, like in your return, must start and end on the same line. New syntax allows this now, but you have to surround your string with ` a backtick. This is all explained here: Creating multiline strings in JavaScript
It appears you meant to use backticks in that first block since you also used template substitution syntax - which also only work inside backticks.
Perhaps when you change all those single quotes with backticks it will work, and you make your return more readable.
I am currently trying to randomize the ads that show up on this website with JavaScript. In order to do this I am importing two script files.
The issue is I can not get the image to load, and I am unsure as to whether it's a problem with the parameters I have set or an error in the format of "" and '' when trying to output the element. I have already attempted to preset the variable that belongs as the url with no luck. The line code I tried with this attempt was var img = "ad" + rNumber + ".jpg"; Below is the HTML code with the embedded JavaScript that I am working on. Any help with this problem would be greatly appreciated.
function randInt(n) {
randNum = Math.ceil(Math.random() * n);
return randNum;
}
function adDescription(n) {
var descrip = new Array();
descrip[1] = "[AD] Diamond Health Club - For all your Health Club Needs";
descrip[2] = "[AD] Pixal - Quality Digital Equipment and Accessories";
descrip[3] = "[AD] dHome - Quality Geodesic Domes and Homes";
descrip[4] = "[AD] Dunston Retreat Center - get away";
descrip[5] = "[AD] LanGear - Quality Network Solutions for all your Business Needs";
return descrip[n];
}
function adLink(n) {
var link = new Array();
link[1] = "http://www.diamondhealth.com";
link[2] = "http://www.pixalproducts.com";
link[3] = "http://www.dhome.com";
link[4] = "http://www.dunstonretreats.com";
link[5] = "http://wwww.langearproducts.com";
return link[n];
}
<html>
<head>
<!--
New Perspectives on HTML and CSS
Tutorial 10
Case Problem 2
The Ridgewood Herald Tribune
Author: Brigitte Arcoite
Date: 7-31-17
Filename: front.htm
Supporting files: ads1.jpg - ads5.jpg, ads.js, fp.jpg, logo.jpg,
modernizr-1.5.js, random.js, styles.css
-->
<meta charset="UTF-8" />
<title>The Ridgewood Herald Tribune</title>
<script src="modernizr-1.5.js"></script>
<link href="styles.css" rel="stylesheet" type="text/css" />
<script src="random.js" type="text/javascript"></script>
<script src="ads.js" type="text/javascript"></script>
</head>
<body>
<nav>
<h1>Contents</h1>
<p class="section">Main</p>
<ul>
<li>Home</li>
<li>Subscriptions</li>
<li>Contact Us</li>
<li>News Sources</li>
</ul>
<p class="section">News</p>
<ul>
<li>Local</li>
<li>National</li>
<li>International</li>
</ul>
<p class="section">Sports</p>
<ul>
<li>Baseball</li>
<li>Basketball</li>
<li>Football</li>
<li>Golf</li>
<li>Hockey</li>
<li>Miscellaneous</li>
</ul>
<p class="section">Opinion</p>
<ul>
<li>Editorials</li>
<li>Columnists</li>
<li>Letters</li>
</ul>
<p class="section">Classifieds</p>
<ul>
<li>Employment</li>
<li>For Sale</li>
<li>Personals</li>
<li>Real Estate</li>
<li>Wanted</li>
</ul>
<p class="section">Other</p>
<ul>
<li>Business</li>
<li>Weather</li>
<li>Entertainment</li>
</ul>
</nav>
<section>
<div id="ads">
<script>
var rNumber = randInt(5); //generate a random integer from 1 to 5
var rAd = adDescription(descrip[rNumber]); //description of the random ad
var rLink = adLink(link[rNumber]); //url of the random ad
var img = "ad" + rNumber + ".jpg";
alert(rNumber);
document.write("<a href='" + rLink + "'>");
document.write("<img src='" + img + "' alt='" + rAd + "' />");
document.write("</a>");
</script>
</div>
<div id="request">Contact us today to place your ad</div>
<header><img src="logo.jpg" alt="Ridgewood Herald Tribune" /></header>
<img src="fp.jpg" alt="" id="fp" />
<h2>Park Opens</h2>
<p>The <i>Adventure Island</i> theme park opened its doors on Monday near Ridgewood. The park, one of the biggest in New Jersey, drew large crowds, but the long lines didn't deter anyone. "I've been watching them put up the rides over the last year,
it's really exciting to finally get inside the gates!" said Ridgewood resident Denise Brooks.
</p>
<p class="cont">story continues on page 2...</p>
<footer>
<address>
<b>Ridgewood Herald Tribune</b> ° 10010 Atwood Ave.
° Ridgewood, NJ 07451<br />
Phone: (201)555-1101 ° Fax: (201)555-1102
</address>
</footer>
</section>
</body>
</html>
Your variable randNum isn't defined. You're also getting the ol' Uncaught Reference error (randInt [function] not defined). Perhaps add an event listener to your scripts to ensure they run when the DOM Content is loaded
<script>
document.addEventListener("DOMContentLoaded", function(event) {
//console.log("DOM fully loaded and parsed");
do stuff here
});
</script>
Hope this helps
Background
I'm building up a website that lists organisations in my local area. The site is powered by an API and stores it's data in an instance of MongoDB.
I'm fetching JSON from the API and dynamically building the content in Javascript.
Now to test against XSS attacks I deliberately added some code to inject a Javascript alert into my page.
But it's not working? Which obviously I'm happy about but I'm more confused as to why not.
The JSON
{
"_created": "Tue, 11 Mar 2014 19:27:30 GMT",
"_etag": "fd8102613204000414cceff538771453b984a2c6",
"_id": "531f63a246e29300025291ba",
"_updated": "Tue, 11 Mar 2014 19:27:30 GMT",
"description": "<script>alert('hello');</script>",
"tags": [
"Antiques"
],
"title": "HTML Injection",
"url": "www.link.com"
}
the injected code
<script>alert('hello');</script>
The code to retrieve the JSON and render it
function S_GET(id) {
var a = new RegExp(id+'=([^&#=]*)');
return decodeURIComponent(a.exec(window.location.search)[1]);
}
// retrieves languages and adds them to a list
var organisationId = S_GET('organisationId');
var url = 'http://damp-island-8192.herokuapp.com/organisations/' + organisationId;
var dataRequest = new XMLHttpRequest();
dataRequest.open('GET',url, false);
dataRequest.onreadystatechange = processJSON;
dataRequest.send();
function processJSON() {
if ( dataRequest.readyState == 4 && dataRequest.status == 200 ) {
showJSON(dataRequest.responseText);
}
}
function showJSON(input) {
//dom elements
var list = document.createElement('ul');
list.setAttribute('id', 'organisation-details-list');
var organisation = JSON.parse(input);
// list organisation details
// title
var title = document.createElement('li');
title.setAttribute('class', 'organisation-title');
title.innerHTML = organisation.title;
list.appendChild(title);
// description
var desc = document.createElement('li');
desc.setAttribute('class', 'organisation-desc');
desc.innerHTML = organisation.description;
list.appendChild(desc);
// link
var link = document.createElement('li');
link.setAttribute('class', 'organisation-link');
var a = document.createElement('a');
a.setAttribute('href', organisation.url);
a.innerHTML = organisation.url;
link.appendChild(a);
list.appendChild(link);
document.getElementsByClassName('organisation')[0].appendChild(list);
};
The HTML
<!DOCTYPE html>
<head>
<title>Moving To Leicester</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
<div class="container">
<div class="header">
<ul class="nav nav-pills dropdown-menu-right">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="row padding-top-5">
<div class="col-md-2">
<!--Sidebar content-->
</div>
<div class="col-md-10">
<!--Body content-->
<div class="organisation"></div>
</div>
</div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/organisation-details-page.js"></script>
</body>
</html>
Question
Why doesn't the page trigger an alert when I'm viewing it?
To my knowledge inserting executable Javascript via AJAX is somewhat limited.
You cannot just get code via AJAX, put it in a LI's innerHTML an have it executed.
This is what you do:
var organisation=JSON.parse(input);
var title=document.createElement('li');
title.setAttribute('class','organisation-title');
title.innerHTML=organisation.title;
list.appendChild(title);
However, one work-around could be if you change your injection into this:
<iframe src='/' width='1' height='1' onload='window.alert("boo");'></iframe>
I think that would inject itself.