Forum Moderators: open

Message Too Old, No Replies

Arrays Using Form Input

Comparing and contrasting arrays

         

oceanwave

3:53 pm on Sep 21, 2004 (gmt 0)

10+ Year Member



Hi,

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!

Bernard Marx

6:00 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



..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.

oceanwave

7:00 pm on Sep 21, 2004 (gmt 0)

10+ Year Member



Thanks so much Bernard. I still am having trouble placing the two lines in the proper place.
var letters = new Array("spot","rover");
var youranswer = new Array(document.quiz.q1.value,document.quiz.q2.value);

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.

StupidScript

7:24 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The "youranswer" array would go at the top of the "arrayIntersect" function. When the function is called, the form elements have been defined and can be accessed at that time.

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?

StupidScript

7:43 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Just playing around ... here's an modification of your script that splits the user's answer and compares each word against the target array (for fun :):

<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!)

oceanwave

8:44 pm on Sep 21, 2004 (gmt 0)

10+ Year Member



Hi StupidScript! Thank you so much!

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?

StupidScript

9:24 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I know Tribble or Bernard can do this more smoothly, but here's my silly little answer to that:

<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>

oceanwave

10:08 pm on Sep 21, 2004 (gmt 0)

10+ Year Member



Works perfectly! It will take me quite awhile to pick this one apart. THANK YOU!

Any recommendations of books, tutorials, sites, that might be helpful to me (I'm sitting next to "Javascript Unleashed", though this is often above me)?

StupidScript

11:20 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Glad to give you something to chew on, oceanwave!

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.

StupidScript

11:46 pm on Sep 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



To wrap up my contribution, here, I have "fixed" your original script. The issues were with (1) when the array was declared and (2) when the form elements were called. I commented before the only two changes I made:

<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>

StupidScript

12:56 am on Sep 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What does Homer say? Duoh!?

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 ...

oceanwave

1:32 am on Sep 22, 2004 (gmt 0)

10+ Year Member



Well you have been mighty busy!

You've certainly given me a lot to learn from. Thanks so much, and an extra thanks for taking the time to explain why things work and the terminology I should research. Your help has been amazing!

StupidScript

2:29 am on Sep 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks, oceanwave. :blushes:

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! ;)

Bernard Marx

7:57 am on Sep 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thought for the morning..

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/);

Bernard Marx

8:00 am on Sep 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thought for the morning..

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?

oceanwave

2:52 pm on Sep 22, 2004 (gmt 0)

10+ Year Member



Good morning to all!

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!

StupidScript

3:03 pm on Sep 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Good morning, Bernard!

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 ...)