Script Tip…
Okay! It’s the final day of the Guitar Chord Script. The only thing left to do is parse the information from the array and give it to the showChord() function we hit upon last week.
For one last time, here’s the script and its effect:
Click a chord on the right and watch the dots provide the pattern.
Remember this from the last Script Tip?
Frets = parser (chords[Text])
If you recall, that line was used to grab a specific line from the array of chord names and radio button numbers. The “parser([Text])” line meant we were transferring that information to a function to be acted upon. That function, and following code, looks like this:
function parser (InString)
{
var Sep = “;”, NumSeps=1, Count, Start, ParseMark, parse;
for (Count=1; Count < InString.length; Count++)
{
if (InString.charAt(Count)==Sep)
NumSeps++;
}
parse = new Array ();
var Start=0, Count=1, ParseMark=0, LoopCtrl=1;
while (LoopCtrl==1)
{
ParseMark = InString.indexOf(Sep, ParseMark);
TestMark=ParseMark;
if ((TestMark==0) || (TestMark==-1))
{
parse[Count]= InString.substring (Start, InString.length);
LoopCtrl=0;
break;
}
parse[Count] = InString.substring (Start, ParseMark);
Start=ParseMark+1, ParseMark=Start, Count++;
}
parse[0]=Count;
return (parse);
}
Before we get into it, let’s stop and think about what this mess of code is supposed to do. First, let’s once again look at our familiar friend the A13 chord array entry:
chords[”A13″]=”1;3;20;22;23″
The numbers within the double quotes have been turned into a straight text string (remember that from the last Tip?) See how there are five numbers following each, separated by a semicolon? That’s important. Now, look again at the script, underneath the ShowChord() function. This is the last line:
document.guitar[parseInt(Frets[Count])].checked=true;
This is the line of code I basically skipped over in the last Tip. This does the magic of setting the correct radio buttons to “checked.” This code, because it’s inside the square brackets, will be replaced with the number it represents:
[parseInt(Frets[Count])]
The command “parseInt” is designed to return an integer, depending on what is found within its instance (the parentheses following it). “Frets[Count]” will be one of the numbers returned from the parser script looking at the text string delivered to it by chords[”A13″]=”1;3;20;22;23″.
So, when this parser script runs through the A13 array item, it will loop through five times returning 1, then 3, then 20, then 22, then 23. With me? Then the line:
document.guitar[parseInt(Frets[Count])].checked=true;
…will “check” each of those radio buttons. Okay, so now that we have a general idea of what is to happen, let’s see how it happens. We’ll start with the top half:
function parser (InString)
{
var Sep = “;”, NumSeps=1, Count, Start, ParseMark, parse;
for (Count=1; Count < InString.length; Count++)
{
if (InString.charAt(Count)==Sep)
NumSeps++;
}
There’s the name of the function that is to act upon “InString.” Remember that we passed the text of the array (A13) to this function. Once it arrives, there is a new variable name inside the
instance of the function. That gives the text string a new name. The text string that was sent to the parser function is now known as “InString.”
You’re probably familiar with the next line. It’s one that sets variables and brings others into play. Look at it. I’ll refer to it again in a moment.
A For loop is brought into play. The variable “Count” is given the value of 1. As long as “Count” is less than the length of the InString text string, Count will be moved up one each time the loop occurs. That means that when Count is equal to the length of the text string, (1) the loop stops and (2) every character in the text string has been inspected, so we’re done!
Remember that each number in the text string is separated by a semicolon and the variable Sep is set to represent a semicolon. So, the next If statement asks if the next character in the text string is a semicolon (the command “charAt” returns the next character in a text string).
If the next character is a semicolon, then “NumSeps” should increase. Basically, if the character is a semicolon, we can’t use it, so it should go on to the next character. That way, only the numbers in the text string are evaluated. The semicolons are skipped over. Very clever.
Now this monster:
parse = new Array ();
var Start=0, Count=1, ParseMark=0, LoopCtrl=1;
while (LoopCtrl==1)
{
ParseMark = InString.indexOf(Sep, ParseMark);
TestMark=ParseMark;
if ((TestMark==0) || (TestMark==-1))
{
parse[Count]= InString.substring (Start, InString.length);
LoopCtrl=0;
break;
}
parse[Count] = InString.substring (Start, ParseMark);
Start=ParseMark+1, ParseMark=Start, Count++;
}
parse[0]=Count;
return (parse);
}
We’re starting a “new Array” that will be built by this code out of the text string. If we stay with the A13th chord, we know the array will be 1, 3, 20, 22, 23.
The next line is common. Variables are given values to be brought into play later.
Now we have a While loop coming into play. The While loop, you might remember, runs as long as the condition within its instance is true. In this case, While LoopCtrl is equal to 1, the loop rolls… and LoopCtrl is equal to 1 because the authors set it to 1 just above.
The next line sets the variable “ParseMark” to the location of the next character. That’s what the method indexOf does; it returns the location of the character the script is working on. It knows which character the script is working on because of the instance: (Sep, ParseMark).
Remember that Sep was set above. Think of it as the starting point for the full length of the string. By setting Sep one up each time, this loop reads the next value each time it rolls through. What it won’t read are the semicolons because we got rid of them in the function above, remember?
Next, we exchange the variable name “TestMark” for “ParseMark.” I’m not sure why other than that’s the author’s preference. That text mark is then tested to see if it is 0 or one less than 0 (-1). If it’s one less, then we must be at the beginning, so set parse[Count] to whichever is the smaller of Start and InString.length. It’s obviously Start, which is equal to 0.
Next, parse[Count] is set to the value of the character that is being looked at, “Start” is increased by 1, as is “Count,” and finally “parse[0]” is set to the next “Count” value in case the function loops through again.
The value found (parse) is returned.
The script loops through again and again, clipping off the next value between the semicolons and returning it so the correct radio button can be checked. The process happens again and again until the script runs out of numbers. No more numbers means there are no more radio buttons to highlight.
The chord is displayed.
Wow! That was a wicked script, huh? Next week we’ll get into something a little less hairy.
Next Week: Setting and Getting a Cookie
Do YOU have a Script Tip you’d like to share? How about suggesting a Script Tip to write about? I’d love to hear it. Write me at: jburns@htmlgoodies.com. |
Learn to write your own JavaScripts with the
JavaScript Goodies!
on your Web pages here!