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.
Related
Javascript creates my html template tables. The function code below is called inside a for loop for TABLE which is inside a for loop for ROUND. The two loops are determined by variables (NumberOf)tables and (NumberOf)rounds, so they vary with use. The database needs to maintain records of the 6 fields for each TABLE in each ROUND, but those field names have not been programmed (yet?) to vary from one ROUND/TABLE instance to another for multiple reasons: it's not clear how to do so in a way to jeehaw with the python data models; I hope there is an easier alternative and; I want to not overburden the server with jinja-type code in the javascript as has been mentioned elsewhere on stackoverflow, for example.
function round1(ROUND,TABLE){
var tt;
tt = ' <div class="table">Table '+ TABLE +''
tt += ' <div class="flex-container partners1">'
tt += ' partners1'
tt += ' <input type="text" maxlength="8" name="partner1" value="name' + Number(1+4*(TABLE-1)) + '"></input>'
tt += ' <input type="text" maxlength="8" name="partner2" value="name' + Number(2+4*(TABLE-1)) + '"></input>'
tt += ' <input type="number" name="score1" >score1</input> '
tt += ' </div>'
tt += ' <p>'
tt += ''
tt += ' </p>'
tt += ' <div class="flex-container partners2">'
tt += ' partners2'
tt += ' <input type="text" maxlength="8" name="partner3" value="name' + Number(3+4*(TABLE-1)) + '"></input>'
tt += ' <input type="text" maxlength="8" name="partner4" value="name' + Number(4+4*(TABLE-1)) + '"></input>'
tt += ' <input type="number" name="score2" >score2</input> '
tt += ' </div>'
tt += ' </div>'
return tt;
}
The data models are given below. I am concerned with the processing burden of Posting data back to the server and Getting the results back to the template. But I am also troubled with how to parse and process the data items efficiently.
class Parties(ndb.Model):
email = ndb.StringProperty()
page = ndb.KeyProperty(kind=Pages)
name = ndb.StringProperty()
tables = ndb.IntegerProperty(default=0)
rounds = ndb.IntegerProperty(default=0)
class Rounds(ndb.Model):
party = ndb.KeyProperty(kind=Pages)
number = ndb.IntegerProperty(default=0)
class Tables(ndb.Model):
party = ndb.KeyProperty(kind=Pages)
number = ndb.IntegerProperty(default=0)
partner1 = ndb.StringProperty(default="")
partner2 = ndb.StringProperty(default="")
partner3 = ndb.StringProperty(default="")
partner4 = ndb.StringProperty(default="")
score1 = ndb.IntegerProperty(default=0)
score2 = ndb.IntegerProperty(default=0)
So I am looking for ideas on how I can rewrite the javascript, or redesign the database, and how to construct the python get and post template_values to coordinate the two.
Upon further analysis, I will attempt to rewrite my Python code to do much of the processing that is done now with javascript, hoping that the mismatch of data and code can be minimized. I was hoping to get ideas of ways to avoid such a rewrite by asking this question.
Or to minimize Python recoding because there is much javascript code not shown that would also have to be redone, I may revise the javascript code so that each input name includes its round and table values: for example, instead of name="parent1", name="r0t0parent1" for parent1 in round 1 and table 1. Python code should be able to parse self.request.get's of such names and hopefully the jinja2 template responses will not be too burdensome to create and parse, but I do not look forward to developing the additional jinja2. Perhaps the ideas suggested here can be employed. I welcome any further advice.
So this is what I have so far, I know I'm on the right track but I can't figure out to create a var for totting up the results and integrating that into my code...I understand that the var created for the multiplication should go after the last "+" in my "for" line.
<!DOCTYPE html>
<html>
<body>
<p></p>
<button onclick="loop()">Click here</button>
<p id="forLoop"></p>
<script>
function loop() {
var total = "";
var x;
for (x = 1; x < 13; x++) total += "2 x " + x + " = " + "<br>";
document.getElementById("forLoop").innerHTML = total;
}
</script>
</body>
</html>
You don't need another var. You can just use x*2. JavaScript is smart enough to evaluate the result and add it to the string as you would expect.
"2 × " + x + " = " + x*2 + "<br />"
Few notes:
To denote "times" (like: "a times b"), HTML has the × entity which renders like so: ×
It's considered bad practice to use <br> like this in production. Generate a table or a list, and add those as elements.
You should avoid .innerHTML until you are aware of the risks of using it.
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.
I have an event which parses a certain string which contains button name and url.
than I assign the data to a button. and add on click event which suppose to open url in a new window. But this on click event doe not work. The window does not show up. If url was wrong it would open a window and prompt a mistake.
But in my case when I click the botton it does not react. Probably something is wrong with on click event here: onclick=\"myWindow = window.open('partArray[1]', '', 'width=300,height=300');\". But I can't understand what.
here is the code
<script>
...
var checkType = partArray[0].split("+");
outPuts = outPuts + " <input type='button' class='WordDocType' name='" + partArray[0] + "' value='" + partArray[0] + "' onclick=\"myWindow = window.open('partArray[1]', '', 'width=300,height=300');\" /> "
document.getElementById("demo").innerHTML=outPuts;
</script>
<body>
...
<div id="demo"></div>
...
</body>
partArray[1] is not evaluated; the browser should still open window with the URL specified as "partArray[1]" but I doubt that is what you want. Try adding double quotes and concatenating it when you build your HTML.
outPuts = outPuts + " <input type='button' class='WordDocType' name='" + partArray[0] + "' value='" + partArray[0] + "' onclick=\"myWindow = window.open('" + partArray[1] + "', '', 'width=300,height=300');\" /> "
If you provide some more context or code it'd be easier to see what might be going on. Are you sure there is not a popup-blocker getting in the way?
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.