Javascript output not showing - javascript

We have a JavaScript assignment that we have to do. We have to build a sentence generator. When I run this in Chrome, nothing happens when I click the buttons. When I check the Console Log, it says Uncaught ReferenceError: mySubject is not defined. I thought I defined it already in element1.onclick function?
This is my code so far:
<body>
<div id="container">
<div id="buttons">
<button id="btn1">Generate subject</button>
<input name="subject" type="text" id="subject"
/>
<button id="btn2">Generate verb</button>
<input name="verb" type="text" id="verb" />
<button id="btn3">Generate adjective</button>
<input name="adj" type="text" id="adj" />
<button id="btn4">Generate object</button>
<input name="object" type="text" id="object" />
</div>
<!--buttons closing div-->
<div>
<p id="output">asjkldhfahfjasf;d</p>
</div>
<!--output closing div-->
</div>
<!--container closing div-->
<script>
var subject = new Array("Mel Gibson", "Optimus-Prime", "The Cat-lady", "The student", "My Dentist");
var verb = new Array("licks", "pets", "hugs", "stabs", "eats");
var adj = new Array("fat", "ugly", "delicious", "redundant", "hopeless");
var object = new Array("cat", "bacon-strip", "dog-house", "bigmac", "hobo");
var element1 = document.getElementById("btn1");
var element2 = document.getElementById("btn2");
var element3 = document.getElementById("btn3");
var element4 = document.getElementById("btn4");
element1.onclick = function() {
mySubject = subject[Math.random() * subject.length]
};
element2.onclick = function() {
myVerb = verb[Math.random() * verb.length]
};
element3.onclick = function() {
myAdj = adj[Math.random() * adj.length]
};
element4.onclick = function() {
myObject = object[Math.random() * object.length]
};
document.getElementById("output").innerHTML = mySubject + myVerb + " the" + myAdj + myObject + ".";
</script>
</body>
I'm starting to get so lost and have no idea what to do and this is only one of the many problems I have.
EDIT:
So I got some help with my Javascript and everything is now working except for the output. I want it to output into the output div, but it's not outputting anything. This is my code now:
<h1>The Amazing Fantastical Sentence Generator!</h1>
<h4>Have hours of fun with your imaginary friends!</h4>
</div><!--title closing div-->
<div id="buttons">
<button id="btn1">Generate subject</button>
<input name="subject" type="text" id="insubject"/>
<button id="btn2">Generate verb</button>
<input name="verb" type="text" id="verb"/>
<button id="btn3">Generate adjective</button>
<input name="adj" type="text" id="adj"/>
<button id="btn4">Generate object</button>
<input name="object" type="text" id="object"/>
<div >
<p id="output"></p>
</div><!--output closing div-->
</div><!--container closing div-->
<script>
var subject=new Array("Mel Gibson", "Optimus-Prime", "The Cat-lady", "The student", "My Dentist");
var verb=new Array("licks", "pets", "hugs", "stabs", "eats");
var adj=new Array("fat", "ugly", "delicious", "redundant", "hopeless");
var object=new Array("cat", "bacon-strip", "dog-house", "bigmac", "hobo");
var element1=document.getElementById("btn1");
var element2=document.getElementById("btn2");
var element3=document.getElementById("btn3");
var element4=document.getElementById("btn4");
element1.onclick=function() {document.getElementById('insubject').value=subject[Math.floor(Math.random()*(subject.length))];}
element2.onclick=function(){document.getElementById('verb').value=verb[Math.floor(Math.random()*(verb.length))];}
element3.onclick=function(){document.getElementById('adj').value=adj[Math.floor(Math.random()*(adj.length))];}
element4.onclick=function(){document.getElementById('object').value=object[Math.floor(Math.random()*(object.length))];}
document.getElementById("output").innerHTML= document.getElementById("insubject").value + document.getElementById("verb").value + " the" + document.getElementById("adj").value + document.getElementById("object").value + ".";
</script>
</body>
</html>

Variables declared inside functions are local to those functions, which means that you can't use them outside of those functions. Try declaring your variables as global outside of the functions.

you should define the mySubject variable along with myVerb and myAdj as follows :
var mySubject;
var myVerb;
var myAdj;

You are defining it inside a function. Declare them outside the function, then try assigning them the value inside.

When I check the Console Log, it says Uncaught ReferenceError:
mySubject is not defined. I thought I defined it already in
element1.onclick function?
JavaScript scope is function scope. Any variable declared within a function only can be accessed by that function and any nested functions but not the outer ones.
If you want to access mySubject outside the function too you need to declare it where you have verb, subject, etc.. delcared.
In addition, even though you still have the issue that your document.getElementById command is using mySubject before the click event is assigning it but that is a different issue I suppose.

So I figured out how to fix this.
After having edited my code again, all the buttons were working, but they were not outputting correctly into the output div. So I declared all the Math.Random equations that were being run on my arrays, so that they all had a default answer. Also I created a default output that would display in the output div.
var subStr = subject[Math.floor(Math.random()*(subject.length))];
var verbStr = verb[Math.floor(Math.random()*(verb.length))];
var adjStr = adj[Math.floor(Math.random()*(adj.length))];
var objStr = object[Math.floor(Math.random()*(object.length))];
document.getElementById("output").innerHTML= subStr + " " + verbStr + " the " + adjStr + " " + objStr + " .";
Then I changed my onclick events.
element1.onclick=function(){
subStr = subject[Math.floor(Math.random()*(subject.length))];
document.getElementById('insubject').value=subStr;
document.getElementById("output").innerHTML= subStr + " " + verbStr + " the " + adjStr + " " + objStr + " .";
}
element2.onclick=function(){
verbStr = verb[Math.floor(Math.random()*(verb.length))];
document.getElementById('verb').value=verbStr;
document.getElementById("output").innerHTML= subStr + " " + verbStr + " the " + adjStr + " " + objStr + " .";
}
element3.onclick=function(){
adjStr= adj[Math.floor(Math.random()*(adj.length))];
document.getElementById('adj').value=adjStr;
document.getElementById("output").innerHTML= subStr + " " + verbStr + " the " + adjStr + " " + objStr + " .";
}
element4.onclick=function(){
objStr= object[Math.floor(Math.random()*(object.length))];
document.getElementById('object').value=objStr;
document.getElementById("output").innerHTML= subStr + " " + verbStr + " the " + adjStr + " " + objStr + " .";
}
Now each Math.random was being calculated again, followed by it being inputted into the specific text field, and then outputting into the output div.

Related

Insert <br /> in a String in Javascript

Let's say, I have a pretty long compund String:
var result = string1 + " - " + string2 + " - " + string3;
and I display the String in the Website by creating a new list item:
var listElement = document.createElement("li"),
container = document.querySelector("#resultlist"); //I have a <ul id="resultlist">
listElement.appendChild(document.createTextNode(result));
container.appendChild(listElement);
How can I add a <br /> tag between e.g. the second and the third part of the String? So, I need something like this:
result = string1 + " - " + string2 + " <br /> " + string3;
(But that attempt just displays the tag).
I also tried the \n command already, but this had no effect on the website output.
Thanks for your help!
The <br /> tag is HTML (at least you want it to be interpreted as HTML). You cannot add HTML to pages using createTextNode(), as the name suggests. You should use innerHTML instead.
var result = "First String" + " - " + "Second String" + " <br /> " + "Third String",
listElement = document.createElement("li"),
container = document.querySelector("#resultlist"); //I have a <ul id="resultlist">
listElement.innerHTML = result;
container.appendChild(listElement);
<ul id="resultlist"></ul>

HTML & Javascript - Button not working

I'm trying to finish my final project for my introductory web development course (I'm very new to javascript and html), which is a simple Mad Libs project. I've been running into problems all day with trying to get it to work, and I think I've largely eradicated most of the bugs. I've really hit a roadblock though, with the button I'm using that is supposed to load in the results and call the function that builds the story using an event listener in the javascript file. When I run my program, the button doesn't do a thing. I checked the Google Chrome developer console, and I'm not getting any error messages or anything, so I have no clue what I'm doing wrong.
Here's my javascript file (named mad_libs_1.js):
var story = document.querySelector("#story");
var adjective1 = document.querySelector("#adjective1");
var verbEndingInED = document.querySelector("#verbEndingInED");
var nounPlural1 = document.querySelector("#nounPlural1");
var liquid = document.querySelector("#liquid");
var nounPlural2 = document.querySelector("#nounPlural2");
var famousPerson = document.querySelector("#famousPerson");
var place = document.querySelector("#place");
var occupation = document.querySelector("#occupation");
var noun1 = document.querySelector("#noun1");
var nationality = document.querySelector("#nationality");
var femaleCelebrity = document.querySelector("#femaleCelebrity");
var noun2 = document.querySelector("#noun2");
var femaleFriend = document.querySelector("#femaleFriend");
var nounPlural3 = document.querySelector("#nounPlural3");
var number = document.querySelector("#number");
var adjective2 = document.querySelector("#adjective2");
//event listener for the button
var finished = document.querySelector("#finished");
if(finished){
finished.addEventListener("click", createStory, false);
}
function createStory(){
console.log("createStory HAS BEEN CALLED");
var finalStory = "";
finalStory += "I enjoy long, " + adjective1.bold();
finalStory += " walks on the beach, getting " + verbEndingInED.bold();
finalStory += " in the rain and serendipitous encounters with " + nounPlural1.bold();
finalStory += ". I really like piña coladas mixed with " + liquid.bold();
finalStory += ", and romantic, candle-lit " + nounPlural2.bold();
finalStory += ". I am well-read from Dr. Seuss to " + famousPerson.bold();
finalStory += ". I travel frequently, especially to " + place.bold();
finalStory += ", when I am not busy with work. (I am a " + occupation.bold();
finalStory += ".) I am looking for " + noun.bold();
finalStory += " and beauty in the form of a " + nationality.bold();
finalStory += " goddess. She should have the physique of " + femaleCelebrity.bold();
finalStory += " and the " + noun2.bold();
finalStory += " of " + femaleFriend.bold();
finalStory += ". I would prefer if she knew how to cook, clean, and wash my " + nounPlural3.bold();
finalStory += ". I know I’m not very attractive in my picture, but it was taken " + number.bold();
finalStory += " days ago, and I have since become more " + adjective2.bold() + ".";
story.innerHTML = finalStory;
console.log(story + " IS THE STORY");
}
and here's my html:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>Mad Libs 1</title>
<script type="text/javascript" src="mad_libs_1.js"></script>
</head>
<body lang="en-US">
<div class="container-fluid">
<h1>Mad Libs 1</h1>
</div>
<div class="container-fluid">
<ul>
<li>Adjective: <input type="text" name="adjective1" id="adjective1"><br>
<li>Verb Ending in "ED": <input type="text" name="verbEndingInED" id="verbEndingInED"><br>
<li>Noun (Plural): <input type="text" name="nounPlural1" id="nounPlural1"><br>
<li>Liquid: <input type="text" name="liquid" id="liquid"><br>
<li>Noun (Plural): <input type="text" name="nounPlural" id="nounPlural2"><br>
<li>Famous Person: <input type="text" name="famousPerson" id="famousPerson"><br>
<li>Place: <input type="text" name="place" id="place"><br>
<li>Occupation: <input type="text" name="occupation" id="occupation"><br>
<li>Noun: <input type="text" name="noun1" id="noun1"><br>
<li>Nationality: <input type="text" name="nationaltiy" id="nationality"><br>
<li>Female Celebrity: <input type="text" name="femaleCelebrity" id="femaleCelebrity"><br>
<li>Noun: <input type="text" name="noun2" id="noun2"><br>
<li>Female Friend: <input type="text" name="femaleFriend" id="femaleFriend"><br>
<li>Noun (Plural): <input type="text" name="nounPlural3" id="nounPlural3"><br>
<li>Number: <input type="text" name="number" id="number"><br>
<li>Adjective: <input type="text" name="adjective2" id="adjective2"><br>
<button id="finished">I'M FINISHED!</button>
</ul>
</div>
<div id="story"></div>
</body>
</html>
I know that my code practices are probably sloppy--I'm just trying to get it to work before I polish it up. Also, I have to use regular javascript and no jquery. I appreciate any help I get with this because I've been working in vain for hours and hours trying to figure out what's wrong.
Further to #Jaromanda X's suggestion, try wrapping your code in a function, and then assigning that function as the window.onload event handler.
This way your code won't run until the HTML document has been loaded. Otherwise your code might run before the document has loaded and there won't be any HTML elements to operate on.
function runOnLoad() {
// all your code in here
}
// assign your function as the handler for the onload event
window.onload = runOnLoad;
You might be interested to read this question for a bit more information about how to run code after the page has loaded, and a few different ways to do it.
pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it
You have errors in your code. bold() is not a function if you want to use bold text you can use <strong> tag.
Also if you want to get value from textbox you need to use value property.
function createStory() {
console.log("createStory HAS BEEN CALLED");
var finalStory = "";
finalStory += "I enjoy long, <strong>" + adjective1.value+ "</strong>";
story.innerHTML = finalStory;
console.log(story + " IS THE STORY");
}
I have corrected for the first textbox you can follow same for the rest.
You could use the addEventListener:
var div = document.getElementById('div');
function blah(e) {
}
div.addEventListener('click', blah);u
This would make a click event in the javascript. The e parameter is needed for this though because it calls for the event.

Why is my for loop not working in my JSON function?

Hey Guys im new at coding and working right now on a Twitch Viewer. (FreeCodeCamp)
Im able to get information from the JSON file and show it through my html code.
But my problem is that i cant get the names from my "gamer" array.
Why is the for loop not working in the json function?
Thank you very much for your help!
var gamer = ["OgamingSC2","ESL_SC2"];
for(i=0;i<(2);i++){
$.getJSON('https://api.twitch.tv/kraken/streams/'+gamer[i]+'/?callback=?', function(json) {
$('.list').append("<b>Name: " + gamer[i] + "</b><br>");
var logo = json.stream.channel.logo;
$('.list').append("Game: " + json.stream.channel.game + "<br>");
$('.list').append("Status: " + json.stream.channel.status + "<br>");
$('.list').append("Logo: " + "<img src=" + logo + ">" + "<br><br><br>");
console.log(json);
});}
img {
width: 5em;
border-radius: 10px;
}
<head><script src="http://code.jquery.com/jquery-1.11.2.min.js"></script> </head>
<body>
<b>Twitch.tv JSON API</b> </br>
<div class="list"></div>
</body>
What happens here is the $.getJson is an asynchronous call, which means that it will execute only after all of the sync operations are executed. So, the for loop runs twice, and two getJSON callback functions are added to the function stack.
Now as Javascript has lexical or functional scope, the variable i lives on in the global scope as 2 (as the final i++ also has executed).
Next, the callback functions are executed one by one off of the function stack. But alas, your variable i is now 2! Now the callback functions would only see gamer[2] which doesn't exist and this throws an undefined
If you add a console.log(i) to your $.getJSON, you'll see that it outputs only 2 two times.
Why don't you try this:
var gamer = ["OgamingSC2","ESL_SC2"];
gamer.map(function(gamer) {
loopIt(gamer);
});
function loopIt(gamer) {
$.getJSON('https://api.twitch.tv/kraken/streams/'+gamer+'/?callback=?', function(json) {
$('.list').append("<b>Name: " + gamer + "</b><br>");
var logo = json.stream.channel.logo;
$('.list').append("Game: " + json.stream.channel.game + "<br>");
$('.list').append("Status: " + json.stream.channel.status + "<br>");
$('.list').append("Logo: " + "<img src=" + logo + ">" + "<br><br><br>");
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<head><script src="http://code.jquery.com/jquery-1.11.2.min.js"></script> </head>
<body>
<b>Twitch.tv JSON API</b> </br>
<div class="list"></div>
</body>
i think it json gives nothing because you put callback=?
when you pass ? in call back variable it take value with ? and gives nothing.
so just put callback= .dont give any values and try again. and just alert json variable in function. you will know value is coming or not. i dont found nothing wrong with loop and json link.
For this types of server call in for loop , you can use custom loop.
Like this, https://jsfiddle.net/s8eLhxpx/
var gamer = ["OgamingSC2","ESL_SC2"];
var initCounter = 0;
callServerData()
function callServerData(){
$.getJSON('https://api.twitch.tv/kraken/streams/'+gamer[ initCounter ]+'/?callback=?', function(json) {
$('.list').append("<b>Name: " + gamer[ initCounter ] + "</b><br>");
var logo = json.stream.channel.logo;
$('.list').append("Game: " + json.stream.channel.game + "<br>");
$('.list').append("Status: " + json.stream.channel.status + "<br>");
$('.list').append("Logo: " + "<img src=" + logo + ">" + "<br><br><br>");
console.log(json);
initCounter++
if(initCounter < gamer.length){
callServerData();
}
});
}

JQuery append button

I am new to JQuery I have tried to read other solutions here in stackoverflow but I don't understand it yet. Could you please help me?
I have a button that is appended onto the page after calling a function addQuestion. When I click the button it does not work but the button with same id created in html does work.
<!DOCTYPE html>
<html>
<head>
<title>Javascript</title>
</head>
<body>
<div id="header">
<h1>My Site</h1>
</div>
<div id="content">
<p ><h2>Question: </h2></p>
<strong>question 1:</strong> how old am I? <br>
a) 18 <br>
b) 17 <br>
c) 22 <br>
<br>
<input id="myAnswer" type="text">
<button id="addOne">answer</button>
</div>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"> </script>
<script>
$('#addOne').click(function() {
var theAnswer = $('#myAnswer').val();
alert(theAnswer);
});
function addQuestion(questionNo, task, reply){
$('#content').append("<br><br><br>" + questionNo + task + "<br>" + reply + "<br>"
+ '<input id="myAnswer" type="text">' + '<button id="addOne">answer</button>' );
}
addQuestion("<strong> question 2: </strong>", "what's my name", "a) Will <br> b) Peter <br> c) Jeff " );
</script>
</body>
</html>
First use classes not ID's for that button. Secondly, you need a future-proof event listener. Third, namespace your components so there is some contextual binding:
// Notice we map the answer to the button with a data attribute.
function addQuestion(id, questionNo, task, reply){
$('#content').append("<br><br><br>" + questionNo + task + "<br>" + reply + "<br>"
+ '<input id="myAnswer-' + id + '" type="text">' + '<button class="addOne" data-answer-id="myAnswer-' + id + '">answer</button>' );
}
// Notice we bind click on the static container and delegate to a dynamic element.
$('#content').on('click', '.addOne', function() {
var theAnswer = $('#' + $(this).data('answer-id')).val();
alert(theAnswer);
});
// Example add - pass in 2 for an ID
addQuestion(2, "<strong> question 2: </strong>", "what's my name", "a) Will <br> b) Peter <br> c) Jeff " );
Working demo : http://jsfiddle.net/x231eLc8/
as your button gets added dynamically, you need to use jQuery.on() to attach event handler to your newly created button and ID's should be unique, so make sure you use different id in case you are generating multiple buttons:
$(document).ready(function() {
$(document).on('click', '#addOne', function() {
var theAnswer = $('#myAnswer').val();
alert(theAnswer);
});
});
Hi, the problem is that you can't have two buttons with the same ID .
You can create two different buttons .. and create a new script.
<script>
$('#addOne').click(function() {var theAnswer = $('#myAnswer').val();alert(theAnswer);});
$('#addTwo').click(function() {var theAnswer = $('#myAnswer2').val();alert(theAnswer);});
function addQuestion(questionNo, task, reply){$('#content').append("<br><br><br>" + questionNo + task + "<br>" + reply + "<br>"+ '<input id="myAnswer2" type="text">' + '<button id="addTwo">answer</button>' );};
addQuestion("<strong> question 2: </strong>", "what's my name", "a) Will <br> b) Peter <br> c) Jeff ");
</script>
OR use classes and the "this" word.

ng-if is not working even the condition is passed

In My following function we used the
"ng-if"[ng-if=\"GoalCard.assignment.totalResponsesToGrade>0**\"] to show/hide the button but its not showing the button even though the condition is passed.
angular.module("goalCard/studentWritingTab.tpl.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("goalCard/studentWritingTab.tpl.html",
"<div class=\"large-12 columns students-table-wrapper student-writing-passage\">\n" +
" <div class=\"summary-report-head\">\n" +
" {{locale['label.goalCard.title.writing']}}\n" +
" </div>\n" +
" <div class=\"small-12 columns students-table table-header goal-student-writing-report border-theme reset-foundation\" flexcroll ><div id=\"goalCardStudentWritingReport\"></div></div> \n" +
" <div class=\"clear\"></div>\n" +
" <div class=\"table-header-passage\"><a class=\"button button-one large-text passge-next right\" wga-click=\"label.goalCard.gradePassages\" ng-if=\"GoalCard.assignment.totalResponsesToGrade>0\" ng-click=\"gradePassages()\">{{locale['label.goalCard.button.writing']}}</a></div>\n" +
"</div> ");
}]);
You're sure
GoalCard.assignment.totalResponsesToGrade
is rightly instanced?
Try to access it so:
ng-if="GoalCard['assignment']['totalResponsesToGrade']>0"
Your scope would need to look like:
$scope.GoalCard = {};
$scope.GoalCard.assignment. = {};
$scope.GoalCard.assignment.totalResponsesToGrade = 0;

Categories