loop through arrays and output results to html - javascript

I've got this method speak(), which takes two arguments. It's a property of the prototype, so multiple objects will use it.
I'd like to grab those values it returns, loop through them, and output them to my html. The part I can't figure out is, how do I target each individual paragraph tag to correspond with the output of each from each of my variables generated results?
Would this require a double loop? I'm lost.
var para = document.querySelectorAll('p');
var speak = function(what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
console.log(whoWhat);
console.log(whoJob);
return whoWhat, whoJob;
};
function Peep(name, job) {
this.name = name;
this.job = job;
}
Peep.prototype.speak = speak;
var randy = new Peep('Randy', 'lawyer');
randy.speak('"blahblah"', randy.job);
var mandy = new Peep('Mandy', 'mom');
mandy.speak('"woooooaahhhh"', mandy.job);
Here's a jsfiddle

Check this one - jsFiddle
Keep adding the HTML to a text. And finally add them to the DOM.
var speak = function(what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
console.log(whoWhat);
console.log(whoJob);
return "<p>"+whoWhat+", "+whoJob+"</p>";
};
var txt = "";
var randy = new Peep('Randy', 'lawyer');
txt+=randy.speak('"blahblah"', randy.job);
var mandy = new Peep('Mandy', 'mom');
txt+=mandy.speak('"woooooaahhhh"', mandy.job);
document.getElementById('result').innerHTML = txt;
//in HTML add the result node
<body>
<p id='result'>
</p>
</body>

Using JavaScript you can access the DOM (Document Object Model) and can append new elements to existing elements. For example, you could create a new paragraph element and add this paragraph element to an existing div with the id "result". Here is an example:
var appendText = function (text, parentId) {
var para = document.createElement("p");
var node = document.createTextNode(text);
para.appendChild(node);
var parentElement = document.getElementById(parentId);
parentElement.appendChild(para);
}
var speak = function (what, job) {
var whoWhat = this.name + ' says, ' + what,
whoJob = this.name + "'s job is: " + job;
return [whoWhat, whoJob];
};
function Peep(name, job) {
this.name = name;
this.job = job;
}
Peep.prototype.speak = speak;
var randy = new Peep('Randy', 'lawyer');
var randySays = randy.speak('"blahblah"', randy.job);
appendText(randySays[0], "result");
appendText(randySays[1], "result");
var mandy = new Peep('Mandy', 'mom');
var mandySays = mandy.speak('"woooooaahhhh"', mandy.job);
appendText(mandySays[0], "result");
appendText(mandySays[1], "result");
Here is the jsfiddle with the required html: http://jsfiddle.net/stH7b/2/. You can also find more information on how to append a paragraph to the DOM here: http://www.w3schools.com/js/js_htmldom_nodes.asp

Related

how to do use onclick inside innerhtml

I have craeted a new div and inside the div Idisplay the information about a topic and also a link to read more about the topic, but my onlick funciton is not working it keeps telling that id is not define. How can I pass value thru innerHTML
function displayNews(section, id, title) {
var section = section;
var id = id;
var title = title;
contentDiv.innerHTML = '<div onclick="displayInfo(id, title);">More info</div>';
}
You could make a real element rather than html to optionally do this.
function displayNews(section, id, title) {
var section = section;
var id = id;
var title = title;
var element = document.createElement('div');
element.onclick = function () {
displayInfo(id, title);
};
element.innerHTML = "More info";
//i don't see contentDiv defined, but this shows the operation
contentDiv.appendChild(element);
}
You didn't properly concatenate the values.
This is what you meant to do, I guess:
function displayNews(section, id, title) {
var section = section;
var id = id;
var title = title;
var div = '<div onclick="displayInfo(' + id + ', "' + title + '");">More info</div>';
alert(div);
}
displayNews(1, 2, 3);

JavaScript beginner: why does this not work?

My html page is not responding to this code I wrote in JS, i'm a total beginner, and just started learning JS, can somebody tell me why this doesn't work?
/* this is a practice file that'll play with js
nothing strange to look at here folks! */
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(HotelName){
this.HotelName = HotelName;
this.numRooms = 20;
this.numGuests;
this.checkAvailability {
if(numRooms != 20 ){
return true;
}
else{
return false;
}
}
this.getHotelName = function(){
//can it work with this dot operator?
return this.HotelName;
}
}
var HiltonHotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = getHotelName();
var el = document.getElementById('name');
el.textContent = fullName;
<!DOCTYPE html>
<html>
<body>
<div id = 'greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id = 'hotelName'>Hyatt</span>
</div>
<script
src = "https://stacksnippets.net/js">
</script>
</body>
</html
I'm pretty sure it's ordering and my syntax i need to work on, any advice is greatly appreciated thank you!
Few misunderstandings:
checkAvailability is a function, you are missing parens.
while accessing the getHotelName function, you have to refer to the HiltonHotel variable, to be able to access and call that function.
few minor errors in your html code, while operating in code snippet, you don't have to add a separate script, it's connected together by default.
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(HotelName) {
this.HotelName = HotelName;
this.numRooms = 20;
this.numGuests;
this.checkAvailability = function() { // it's a function (missing parens)
if (numRooms != 20) {
return true;
} else {
return false;
}
}
this.getHotelName = function() {
return this.HotelName;
}
}
var WeiHotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = WeiHotel.getHotelName(); // refer to the `WeiHotel` variable
var el = document.getElementById('name');
el.textContent = fullName;
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>
An extension to the answer of #KindUser:
You're not using closures anywhere in this class to store some private state. Therefore you should attach the methods to the prototype and not to the instance itself. It's more economic, because now all instances share one function, not one per instance. And the JS engine can optimize that better.
Then, you have another error in checkAvailability: numRooms needs to be addressed as this.numRooms because it is a property of this instance, and there is no variable with this name.
And one about style. If you have something like
if(condition){
return true;
}else{
return false;
}
you can simplify this to:
return condition;
//or if you want to enforce a Boolean value,
//but your condition may return only a truthy/falsy value:
return Boolean(condition);
//sometimes also written as:
return !!(condition);
Next. Stick to the coding standards. In JS a variable/property starting with an uppercase letter would indicate a class/constructor, therefore HotelName, HiltonHotel, WeiHotel are misleading.
And I find the property name hotelName redundant and counter-intuitive. Imo you have a Hotel, it has a name, but that's just an opinion.
var firstName = 'Steven';
var lastName = 'Curry';
var fullName = firstName + ' ' + lastName;
function Hotel(name) {
this.name = name;
this.numRooms = 20;
this.numGuests;
}
Hotel.prototype.checkAvailability = function() {
return this.numRooms !== 20;
}
Hotel.prototype.getHotelName = function() {
return this.name;
}
var hotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = hotel.getHotelName(); // refer to the `weiHotel` variable
var el = document.getElementById('name');
el.textContent = fullName;
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>
or as an ES6 class (and some playin around):
class Person{
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
//this is a getter, you can read it like a property
get fullName(){
return this.firstName + " " + this.lastName;
}
//this function is implicitely called whenever you try to convert
//an instance of `Person` into a string.
toString(){
return this.fullName;
}
}
class Hotel{
constructor(name) {
this.name = name;
this.numRooms = 20;
this.numGuests;
}
checkAvailability() {
return this.numRooms !== 20;
}
getHotelName() {
return this.name;
}
}
var steve = new Person('Steven', 'Curry');
var hotel = new Hotel('Hilton');
var hName = document.getElementById('hotelName');
hName.textContent = hotel.getHotelName(); // refer to the `weiHotel` variable
var el = document.getElementById('name');
el.textContent = steve.fullName;
//this uses the `toString()` method to convert the `Person` steve into a string
//for people, this makes sense, for the Hotel you'd want to think:
// - where do I want to use this?
// - and what should this string contain?
console.log("Hello, I'm " + steve + " and I'm at the "+ hotel.name);
<div id='greeting'> Hello
<span id="name">friend</span>!
<h1>Welcome To the <span id='hotelName'>Hyatt</span></h1>
</div>

How can I find the value of a specific property from all instances of an object?

In case this gets labeled as a duplicate or something similar; I just wanted to put it out there that I looked for an answer for about 3-4 days. The articles, topics and related questions that showed up did not solve my problem. If they do happen to be the solution, I currently don't and didn't understand why.
How can I, for example, loop through all instances of the player object and return each instance's value for the id property?
function player(id, damage, arena)
{
this.id = id;
this.damage = damage;
this.arena = arena;
}
var player1 = new player(101,10, true);
var player2 = new player(102,5, true);
var player3 = new player(103,20, true);
Don't laugh at me!
Even though I'm like 65% percent sure a string wouldn't serve as a reference
to an object, all my train of thoughts tend to revert back to something that works like this..
var txt = "";
for (i=1; i <= player_count; i++)
{
var x = "player"+i;
txt += " " + x.id;
}
document.GetElementById("someTextDivOrSomething").innerHTML = txt;
Can someone explain how I can go about doing this, or point me in the right direction?
You need some structure to hold the data, i.e. the representation of your players as you create them.
later on you can loop over the elements of your players collection
e.g.
let players = {};
...
players[101] = new player(101,10, true);
players[102] = new player(102,15, true);
players[103] = new player(103,20, true);
...
let txt = ""
for (let p of players) {
txt += " " + p.id
// note we need a name which is not "player" as that is taken
}
You can use a closure for the object constructor. The private variable players contains all instances of the class Player.
var Player = function () {
var players = [];
return function(id, damage, arena) {
this.id = id;
this.damage = damage;
this.arena = arena;
this.players = players;
this.players.push(this);
};
}();
var player1 = new Player(101, 10, true);
var player2 = new Player(102, 5, true);
var player3 = new Player(103, 20, true);
document.write(player1.players.length + '<br>'); // 3
document.write(player2.players.length + '<br>'); // 3
player3.players.forEach(function (a) { document.write('id: ' + a.id + '<br>'); }); // 101, 102, 103

Javascript button.onclick not functioning like I thought

So I was in the presumption that this function
button.onclick = exampleFunk;
would give me a handler on each button when I click them, but it doesn't. When replacing it with:
button.onclick = alert("bananas");
I'm getting alerts at page onload. The problem is already solved with this:
button.setAttribute("onclick", "removeIssue(this)");
Out of curiousity... What's going on?
edited layout of post
EDIT
var issues = [];
window.onload = function () {
//alert("venster geladen");
issuesToList()
}
function issuesToList(data) {
/*alert(
"array length is " + data.issues.length + "\n" +
"total_count is " + data.total_count + "\n" +
"limit is " + data.limit + "\n" +
"offset is " + data.offset + "\n" + ""
);*/
for (i = 0; i < data.issues.length; i++) {
issue = data.issues[i];
createIssue(issue);
}
}
function createIssue(issue){
var id = issue.id;
var tracker = issue.tracker;
var status = issue.status;
var priority = issue.priority;
var subject = issue.subject;
var description = issue.description;
var assignee = issue.assignee;
var watchers = issue.watchers;
var ticket = new Issue(id, tracker, status, priority, subject, description, assignee, watchers);
issues.push(ticket);
var button = document.createElement("button");
button.innerHTML = "-";
button.onclick = function (){ alert("bananas")};
//button.setAttribute("onclick", "removeIssue(this)");
var item = document.createElement("div");
item.setAttribute("id", id);
item.appendChild(button);
item.innerHTML += " " + subject;
var container = document.getElementById("container");
container.appendChild(item);
}
function removeIssue(e){
var key = e.parentNode.getAttribute("id");
var count = issues.length;
if(confirm("Confirm to delete")){
for(i=0; i<count; i++){
if (issues[i].id == key ){
issues.splice(i,1);
var element = document.getElementById(key);
element.parentNode.removeChild(element);
}
}
}
}
function Issue(id, tracker, status, priority, subject, description, assignee, watchers){
this.id = id;
this.tracker = tracker;
this.status = status;
this.priority = priority;
this.subject = subject;
this.description = description;
this.assignee = assignee;
this.watchers = watchers;
}
EDIT
<body>
<h1>List of Issues</h1>
<div id="container"></div>
<script src="http://www.redmine.org/issues.json?limit=10&callback=issuesToList"></script>
</body>
You need to mask the alert in a function:
button.onclick = function (){ alert("bananas")};
As such:
var btn = document.createElement("BUTTON");
var t = document.createTextNode("CLICK ME");
btn.appendChild(t);
btn.onclick = function() {alert("bananas")};
document.body.appendChild(btn);
Whats going on?
You alert() is executed on page load because its a function call. When the execution of your script reaches that line your assignment
button.onclick = alert("bananas");
is actually executing the alert statement and not assigning it to button.onclick
You can bind arguments to the function so that it returns with the function you want it to call using your arguments (with additional arguments passed later added on to the end). This way doesn't require writing extraneous code (when all you want to do is call a single function) and looks a lot sleeker. See the following example:
button.onclick = alert.bind(window, "bananas");
An unrelated example of how it works in your own code is like this:
var alert2 = alert.bind(window, 'Predefined arg');
alert2(); // 'Predefined arg'
alert2('Unused'); // 'Predefined arg'
For IE, this requires IE9 as a minimum. See MDN for more information.
EDIT: I've looked closer at your code and there was one significant change that was needed for it to work... You cannot add onto the innerHTML when you've added JavaScript properties to a child element. Changing the innerHTML of the parent element will convert your element into HTML, which won't have the onclick property you made before. Use element.appendChild(document.createTextNode('My text')) to add text dynamically.
See a functioning example here: http://jsfiddle.net/2ftmh0gh/2/

Cannot make unique javascript object. What's wrong with this code?

I'm trying to make a simple in in-page popup called like this:
var test = new popObject({}); //JSON options
and I'm having trouble because when I create two in a row, and call show() on the first one, the second one always shows. Both are created, but they aren't separate somehow, despite being called with new. What am I doing wrong here? I've included my code, but I have removed out the irrelevant functions for compactness.
function popObject(options) {
//functions
show = function() {
console.log(boxselector);
jQuery(boxselector).css("display", "block");
return jQuery(boxselector);
}
var hide = function() {...}
var update = function(updateOptions) {...}
var calcTop = function(passedHeight) {...}
var calcLeft = function(passedWidth) {...}
var calcHeight = function(passedHeight) {...}
var stripUnits = function(measure, auto) {...}
var destroy = function() {...}
//public functions
this.show = show;
this.hide = hide;
this.update = update;
this.destroy = destroy;
//constants
name = options.name; //name should never be changed.
boxselector = ".boxcontainer[name=" + options.name + "]";
boxbodyselector = ".boxbody[name=" + options.name + "]";
boxtitleselector = ".boxcontainer[name=" + options.name + "]"
boxboxselector = ".boxbox[name=" + options.name + "]"
title = options.title;
content = options.content;
width = options.width;
height = options.height;
this.name = name;
this.selectors = [boxselector, boxbodyselector, boxtitleselector, boxboxselector]
this.title = title;
this.content = content;
this.width = width;
this.height = height;
//variables
popupHtml = ...
//init code
jQuery("#dropzone").append(popupHtml); this.init = null;
jQuery(".boxbox[name=" + name + "]").css("top", calcTop(width));
jQuery(".boxbox[name=" + name + "]").css("left", calcLeft(height));
jQuery(".boxbody[name=" + name + "]").css("height", calcHeight(height));
}
This is because you're declaring a lot of variables in the global scope. Try the following code instead:
function popObject(options) {
//functions
this.show = function() {
console.log(boxselector);
jQuery(boxselector).css("display", "block");
return jQuery(boxselector);
}
var hide = function() {...}
var update = function(updateOptions) {...}
var calcTop = function(passedHeight) {...}
var calcLeft = function(passedWidth) {...}
var calcHeight = function(passedHeight) {...}
var stripUnits = function(measure, auto) {...}
var destroy = function() {...}
//public functions
this.show = show;
this.hide = hide;
this.update = update;
this.destroy = destroy;
//constants
var name = options.name; //name should never be changed.
var boxselector = ".boxcontainer[name=" + options.name + "]";
var boxbodyselector = ".boxbody[name=" + options.name + "]";
var boxtitleselector = ".boxcontainer[name=" + options.name + "]"
var boxboxselector = ".boxbox[name=" + options.name + "]"
var title = options.title;
var content = options.content;
var width = options.width;
var height = options.height;
this.name = name;
this.selectors = [boxselector, boxbodyselector, boxtitleselector, boxboxselector]
this.title = title;
this.content = content;
this.width = width;
this.height = height;
//variables
var popupHtml = ...
//init code
jQuery("#dropzone").append(popupHtml); this.init = null;
jQuery(".boxbox[name=" + name + "]").css("top", calcTop(width));
jQuery(".boxbox[name=" + name + "]").css("left", calcLeft(height));
jQuery(".boxbody[name=" + name + "]").css("height", calcHeight(height));
}
Note all the vars that weren't there before. This defines them as local to the function, and thus local to your object (and also, essentially, private... use this. instead of var to make public members).
Anything that isn't declared with a var or a this. is considered global. So, when you called show(), it used the global show, which referenced the object that was created later.
What is boxselector? If it's a generic selector then it would select all elements on the page, regardless if its inside of that unique object.
When you declare something without var or this within a function definition, such as
boxselector = ".boxcontainer[name=" + options.name + "]";
It creates it in the global namespace (attaches it to window)
Try changing this line to
var boxselector = ".boxcontainer[name=" + options.name + "]";

Categories