Forum Moderators: open
I read a tutorial about comparing arrays. The tutorial was great, but it explained how to do it with already defined arrays. I decided I wanted to learn how to do it when a user enters information in a form, where one of the arrays does not already have the values inserted. I keep getting errors that my document values are null or not an object. Here's what I am trying to do:
1. Compare the letters array with the youranswer array to see what items are the same.
2. Compare the letters array with the youranswer array to see what items the user did not guess.
3. It does not matter which textbox the user inputs the answer in, q1 or q2 could be entered with either spot or rover.
4. The answers should not be case sensitive.
Here's what I have so far:
<SCRIPT LANGUAGE="javascript">
var letters = new Array("spot","rover");
var youranswer = new Array(document.quiz.q1.value,document.quiz.q2.value);
function arrayIntersect(intersect_name, array_1, array_2)
{
var the_list = "";
for (var loop_1 = 0; loop_1 < array_1.length; loop_1++)
{
for (var loop_2 = 0; loop_2 < array_2.length; loop_2++)
{
if (array_1[loop_1] == array_2[loop_2])
{
the_list = the_list + array_1[loop_1] + " ";
}
}
}
alert("the " + intersect_name + " are: "+ the_list);
}
</script>
<form name="quiz">
<b>CAN YOU NAME MY TWO DOGS?</b><br><br>
<b>#1: Name Of Dog: </b>
<input type="textbox" name="q1" value="">
<P>
<b>#2: Name Of Other Dog: </b>
<input type="textbox" name="q2" value="">
<P>
<a href="#" onClick="arrayIntersect('correct answers',letters,youranswer); return false;">Grade Me!</a>
</form>
Thanks for trying to teach an old dog a new trick!
..null or not an object
Everyone makes this mistake once, except me.
I made it 27 times.
The page is read top to bottom. The HTML is parsed, and any script statement - not inside a function - is executed "on sight". This statement..
var youranswer = new Array(document.quiz.q1.value,document.quiz.q2.value); ..is executed before the elements referred to have been parsed, because they are below the statement.
In your case, you might as well put the statement into the function that is called when the button is clicked - else it won't respond to changes in the textboxes anyway.
I tried it both above and below the line
var the_list = "";
still got the error
I tried adding another function and calling it from the onclick
function postIt(){
var letters = new Array("spot","rover");
var youranswer = new Array(document.quiz.q1.value,document.quiz.q2.value);
}
error "letters is undefined" in onclick line
I guess I'm still not understanding how this should be written.
I see you're using "<input type='textbox' ..." syntax. In XHTML there is a "<textbox ref= ..." element, however (correct me if I'm wrong) normal HTML only has "<input type='text' ..." and "<textarea ...></textarea>" form elements.
If you have already tried putting the array declaration inside the function, perhaps the JS is having trouble figuring out which form elements you wish to access because it doesn't recognize the type of form element you are using?
<script type="text/javascript" language="javascript">
letters=new Array("baker","agent","chef","executive");
function arrayIntersect(array_1,fld) {
array_2=fld.value.split(" ");
the_list="";
for (loop_1=0;loop_1<array_1.length;loop_1++) {
for (loop_2=0;loop_2<array_2.length;loop_2++) {
if (array_1[loop_1]==array_2[loop_2]) {
the_list += array_1[loop_1]+" ";
}
}
}
alert("You indicated: "+the_list);
}
</script>
<center>
<form>
What do you want to do for a career?<br />
<textarea cols=40 rows=5 name="myanswer">I want to be a chef or a baker</textarea><br />
<input type="button" onclick="arrayIntersect(letters,this.form.elements['myanswer'])" value="Check">
</form>
</center>
(Not to be taken seriously, although it works fine!)
What a minute....I think you are on to something! I am taking this seriously! You did it!
So the user could enter all the responses in one textarea, and every word would be checked against the answer array. The alert lists all the correct answers. Brilliant! Now I have to go read about "splitting". By the way, sorry for the "text" mistake...I've been playing with this for far too long!
Now, how would I also list all the answers the user missed?
<script type="text/javascript" language="javascript">
letters=new Array("baker","agent","chef","executive");
function arrayIntersect(array_1,fld) {
array_2=fld.value.split(" ");
the_list="";
missed_list="";
gotMatch=new Array();
for (loop_1=0;loop_1<array_1.length;loop_1++) {
for (loop_2=0;loop_2<array_2.length;loop_2++) {
if (array_1[loop_1]==array_2[loop_2]) {
the_list += array_1[loop_1]+" ";
// make an array of the matches
gotMatch[gotMatch.length] = array_1[loop_1];
}
}
}
// compare original array with matched array
for (loop_3=0;loop_3<array_1.length;loop_3++) {
gotit=0;
for (loop_4=0;loop_4<gotMatch.length;loop_4++) {
if (array_1[loop_3]==gotMatch[loop_4]) { gotit=1; }
}
if (!gotit) { missed_list += array_1[loop_3]+" "; }
}
alert("Matches: "+the_list);
alert("Missed: "+missed_list);
}
</script>
<center>
<form>
What do you want to do for a career?<br />
<textarea cols=40 rows=5 name="myanswer">I want to be a chef or a baker</textarea><br />
<input type="button" onclick="arrayIntersect(letters,this.form.elements['myanswer'])" value="Check">
</form>
</center>
When I need Javascript help, or am up to my eyeballs in some project, I use basically 3 resources:
1) Javascript Core Reference
[devedge.netscape.com...]
2) Dynamic HTML (The Definitive Reference) by Danny Goodman
3) This forum, and others like it.
I find that scanning the list of available functions and whatnot often points me in the right direction, simply by virtue of a function name or description.
The key is having a pretty clear idea of WHAT you want to accomplish. With that in mind, you can greatly narrow the amount of research you will need to do.
That's about it. Lots of experimenting late into the night has also been very beneficial to me.
<SCRIPT LANGUAGE="javascript">
var letters = new Array("spot","rover");
// DECLARE an empty array as the page loads
// There are no form elements, yet, so don't include those here
// The array MUST be declared prior to executing the function, or it breaks
var youranswer=new Array();
function arrayIntersect(intersect_name, array_1, array_2)
{
// HERE is where I capture the form elements' values
// They have been defined, and now we can dump them into the array and use them
youranswer[0]=document.quiz.q1.value;
youranswer[1]=document.quiz.q2.value;
var the_list = "";
for (var loop_1 = 0; loop_1 < array_1.length; loop_1++)
{
for (var loop_2 = 0; loop_2 < array_2.length; loop_2++)
{
if (array_1[loop_1] == array_2[loop_2])
{
the_list = the_list + array_1[loop_1] + " ";
}
}
}
alert("the " + intersect_name + " are: "+ the_list);
}
</script>
<form name="quiz">
<b>CAN YOU NAME MY TWO DOGS?</b><br><br>
<b>#1: Name Of Dog: </b>
<input type="textbox" name="q1" value="">
<P>
<b>#2: Name Of Other Dog: </b>
<input type="textbox" name="q2" value="">
<P>
<a href="#" onClick="arrayIntersect('correct answers',letters,youranswer); return false;">Grade Me!</a>
</form>
Bernard, I hope that next to last piece of code gave you a little chuckle ...
oceanwave: Here is a much tidier script re: spot & rover, plus comments:
<script type="text/javascript" language="javascript">
// declare array with 'correct' answers
letters=new Array("baker","agent","chef","executive");
// function args = 'correct' array object ref, user input object ref
function arrayIntersect(array_1,fld) {
// make an array out of user input, split at the spaces
array_2=fld.value.split(" ");
// initialize empty variables: matches and misses
the_list="";
missed_list="";
// outer loop: for each in 'correct' array
for (loop_1=0;loop_1<array_1.length;loop_1++) {
// initialize/reset match indicator var
gotit=0;
// inner loop: for each in unser input array
for (loop_2=0;loop_2<array_2.length;loop_2++) {
// if user entry matches 'correct' entry
if (array_1[loop_1]==array_2[loop_2]) {
// add 'correct' match plus space to 'matches' string var
the_list += array_1[loop_1]+" ";
// set indicator = this one matches
gotit=1;
// end user:correct comparison
}
// end inner loop: user input answer array
}
// check indicator
if (!gotit) {
// didn't match, so add to 'missed' string var plus space
missed_list += array_1[loop_1]+" ";
}
// end outer loop: 'correct' array
}
// do something with the 'matches' and 'missed' strings
alert("Matches: "+the_list);
alert("Missed: "+missed_list);
// end function
}
</script>
<center>
<!-- initiallize the form -->
<form>
What do you want to do for a career?<br />
<!-- user input element 'myanswer', can be any kind of text input element -->
<textarea cols=40 rows=5 name="myanswer">I want to be a chef or a baker</textarea><br />
<!-- onclick triggers function, exposing it's insides to the application for the first time since it was read into memory .. since the button would not display if the form hadn't loaded, it's now safe to pass references to form elements back up to the in-memory-but-not-active-yet functions above .. if the references are used within the function, it's cool .. if they have already been made active by being outside the protection of a function's shell, and been triggered prematurely when the browser read them into memory, then you have probably received an error -->
<input type="button" onclick="arrayIntersect(letters,this.form.elements['myanswer'])" value="Check">
</form>
</center>
Whew! That's much better! Cheers ...
It just goes to show that the learning never stops. :)
Almost as important as the working code is the crazy stuff I put up before I came to my senses. Check it out to see why my next to last code (not the "fix") didn't cut the mustard. It's a good example of brawn over brains! ;)
With this:
array_2=fld.value.split(" "); If the user enters more than one space, the resulting array will have all the answers wrong from that point on (some members will have empty strings). I reckon that splitting on a regular expression for whitespace will accommodate that..
array_2=fld.value.split(/\s/);
With this:
array_2=fld.value.split(" "); If the user enters more than one space, the resulting array will have all the answers wrong from that point on (some members will have empty strings). I reckon that splitting on a regular expression for whitespace will accommodate that..
array_2=fld.value.split(/\s/); Hmmm. What if someone thinks you have a dog that answers to the name, Santa's Little Helper, or Napoleon Solo?
Bernard, I see that the line you suggested also allows the user to enter either a space or use "enter" between words. I also see your "food for thought" issue, regarding answers with more than one word. I have been reading about "array objects" (I hope this is correct), but I don't see anything that address the 2 word answer issue when a space has been chosen as the split.
StupidScript, I have been reading your explanations over and over again this morning, and it is starting to make sense. Thanks again! I did a search and started reading about "split".
I've been playing with this script, and I also realize the issue of it being case sensitive.
And the tutorial that started all of this was so easy!
A double space in the user input has no practical effect on the outcome:
array,with,double,,space,in,it
Now a multi-word answer is a little bit more tricky. I suppose something like:
names=new Array("helper","little","santa's","spot");
might be useful, without getting too wild with the code. (I reversed the name in the array to set up for appending to the "matches" string ... might need to escape the apostrophe ...)