Document Home
Previous: An Integrated Dynamic Environment
sel_form subroutine
store subroutine

The get_form Subroutine


sub get_form	{
		unlink '/home/www/recs' if -e '/home/www/recs';
		$forms->delete('action');
		print header("text/html");
		print start_html(),
			("<font size='5'><center>Scorecard Entry</center></font>"),
			("<p><br>");
	
		print start_form(-method=>"post");
		my $i=1;
		my $test;
		my $num_forms=param('num_forms');					
		my ($ec1,$rc1,$pc1,$erc1,$et1);
					
		print $forms->p('<center>');		
		if ($num_forms==8)	{
				
					
					while ($i <= $num_forms)	{
							
							           print $forms->p('<table border width="85%"><tr><td>'),
												('Event Code:<input type="text" name="ec" size="2"><br>'),
												('Role Code:<input type="text" name="rc" size="2"><br>'),
												('Participant Code:<input type="text" name="pc" size="4"><br>'),
												('Event Result Code:<input type="text" name="erc" size="2"><br>'),
												('Event Text:<input type="text" name="et" size="25">'),
												('</td>');
										$i++;
						
						
						
									print	$forms->p('<td>'),
												('Event Code:<input type="text" name="ec" size="2"><br>'),
												('Role Code:<input type="text" name="rc" size="2"><br>'),
												('Participant Code:<input type="text" name="pc" size="4"><br>'),
												('Event Result Code:<input type="text" name="erc" size="2"><br>'),
												('Event Text:<input type="text" name="et" size="25">'),
												('</td>'),
												('</tr>');
										$i++;
									print $forms->p('</table>');
								}
		
				}

		if ($num_formsɠ)	{	
						
					while ($i <= $num_forms)	{
						
							
									my $test=($i % 2);
							
									if ($testɬ)
										{
											
											print $forms->p('<table border width="85%"><tr><td width="75%">'),			
														 ('Event Code:<input type="text" name="ec" size="2"><br>'),
														 ('Role Code:<input type="text" name="rc" size="2"><br>'),
														 ('Participant Code:<input type="text" name="pc" size="4"><br>'),
														 ('Event Result Code:<input type="text" name="erc" size="2"><br>'),
														 ('Event Text:<input type="text" name="et" size="25">'),		 	
												         ("</td>"),
												         ("<td width='25%'>"),	
												         ('<center><img src="/images/baseball.jpg" alt=""></center>'),
												         ('</td>'),
												         ('</tr>');
										}
									
									if ($test==0)
										{
											print $forms->p('<table border width="85%"><tr><td width="25%">'),
												         ('<center><img src="/images/baseball.jpg" alt=""></center> '),
												         ('</td>'),
												         ('<td width="75%">'),
														 ('Event Code:<input type="text" name="ec" size="2"><br>'),
														 ('Role Code:<input type="text" name="rc" size="2"><br>'),	
														 ('Participant Code:<input type="text" name="pc" size="4"><br>'),
														 ('Event Result Code:<input type="text" name="erc" size="2"><br>'),
														 ('Event Text:<input type="text" name="et" size="25">'),			
												         ('</td>'),	
												         ('</tr>');
									
										}
									print $forms->p('</table>');
									$i++;
								}
					
			}
		
		


		print $forms->hidden('action','store');
		print $forms->hidden("num_forms",$num_forms);
		print submit(-name=>"submit",-value=>'store');
		print $forms->p('</center>');
		print endform;
		print "<p><br>";
		print end_html;
}

I know the way I've formatted the code above has widened your browser a bit, but I wanted to preserve the fomatting of the subroutine. The purpose of the subroutine is to generate the page that will be used to enter forms, and the bulk of the subroutine is taken up with the generation of those forms. The statements within the two if statements are prime candidates for both inclusion in a subroutine of their own and far more elegant expression in perl. In my opinion the benefits of doing the first are not sufficient to worry about it in the current context, but I can see situations in which it may be worthwhile, so it is possible that I'll do that in some later version of this code. The second might allow the code to be smaller, but if anything would execute slightly more slowly because that expression would likely rely on more server processing than is required to simply print back to the browser, and would likely be substantially less legible. Regardless, I may play around with that somewhere down the road, but not now. Sometimes it makes sense to get fancy, but at other times it can simply be an exercise in trying to impress someone.


The first couple of lines in the subroutine perform what are essentially housekeeping functions. The first line becomes pertinent as page after page of records are entered, unlinking the ascii file of written records written by a previous incarnation of the script. The second line deletes the action paramter from the CGI environment space. By default, the CGI module appends additional values when paramters have the same name. The script uses this behavior to allow the entry of multiple forms. In other contexts, this could be used to construct a history of actions that could be used in some fashion in the session. (Think about that a little, and think about the internet surfing you've done ... ah, I can see the light going on in your eyes.) In this situation, however, we just want to be rid of whatever is currently stored there so it doesn't interfere with what we're going to put there now.


Once past these lines, the subroutine adopts a structure very much like the multirec example discussed previously. The num_forms parameter holds the value selected on the form generated by the sel_form subroutine. If that value is eight, the form is generated with four rows of two forms each, as in the multirec example. (Note the form of the expression in the if statement. The "==" is the numeric equality test in perl, while "=" is the numeric assignment operator, as in "$num_forms=8;". That statement assigns the value 8 to the scalar $num_forms, it doesn't check to see whether $num_forms equals 8. In this context, I could as easily have used the equality operator used by perl for string operations ("eq" ... you can see that in use in the main body of the script) because there is nothing about the comparison that is really numeric, and perl is smart enough to switch back and forth between textural or numeric interpretation of the value "8" as appropriate. Note also that in conditional statements like this, perl simply evaluates the statement within parentheses to determine the truth value of the statement. If the statement is true, it is assigned the value 1 and if not the value 0. It is this value that perl uses to determine whether the condition will pass or not. If I were to say
my $example=0;
if ($example){...}
the if condition would fail, but any non-zero value stored in the scalar would cause it to pass. Similarly, if I were to declare a scalar and use it in an if statement, such as in
my $another_example;
if ($another_example){...}
the condition would fail, because the value of $another_example is undefined, or null. This is a common structure in much perl code, in effect that is what I am doing in the main body of this script when I assign a value to the $action scalar if the action parameter is undefined. In that context, however, the statement uses the simpler convention of doing something if the statement fails. That is the most common method of error-handling in perl, something I've briefly touched on earlier and we will handle in more depth later.)


Regardless, as the code executed if this if statement passes is the same as previously discussed in the multiple records sample I'll jump to the condition in which $num_forms is less than eight, which is a lot more interesting anyway. The pages that display fewer than eight forms do so in a staggered format, as illustrated in the picture earlier in this section. This requires, of course, that the size of the individual table columns be adjusted from row to row. This cannot be done within a single table...once the width of the table's columns are set it is going to stay that way until the table ends. Therefore, each row in the table represents an individual table, the first with 75% of its width in the left hand column, in which the entry form is displayed, and the next with 75% of the width and the entry form on the right hand side. The forms alternate down the page in this fashion until the number of forms desired have been displayed. To preserve a common look and feel, I changed the code that generates the eight-form page to generate one table for each row, even though it was not required for that page.


Ok, you might ask, how are we going to go about drawing a variable number of forms down the page, keeping track of where the next one should be? We've used counters before ... they represent the simplest example of a programming trick in which some kind of pattern is used to control the execution of a chunk of code. This example is just one step up from a simple counter. If we divide the counter scalar by 2, we get the simple progression {0.5,1.0,1.5 ... }. Therefore, I use the modulus operator (%) to store the remainder of that operation to the scalar $test. Since the value of $test will alternate between 0 and 0.5, a left side oriented table is printer if the remainder is 0 and a right side oriented table is printed if the value held in that scalar is greater than 0. Pretty slick, huh? Far more complex problems than this can be solved through the use of techniques only slightly more involved. Keep things like this in mind. You'd be surprised how often you can hit a target hidden behind a concrete slab by bouncing the ball off a side wall first.


After I got the basic configuration for this worked out I decided that having a blank column that occupies 25% of any given row was kind of boring, so I found a small baseball-oriented image by a doind a google image search that is printed in that column. I think it looks pretty cool. Near the end of the subroutine, the paramter "action" is deleted and another set of hidden fields printed, with the value "store" placed in the "action" parameter and the $num_forms value in the "num_forms" parameter.