Document Home


Samples for this Section


Previous: Rounding Out the CGI-Based Entry Script

Changes to the Interface Script


If you read the narrative accompanying the previous incarnation you might be able to anticipate the changes I'm going to make here. If you recall, there was no provision in that version for protecting the inning record from ill-formatted values, and no way to delineate the top and bottom halves of an inning. I had also intended to roll all of the hidden fields into one large hidden field and pass that back and forth rather than the seven or eight values that I do pass around, but I found that while I was able to write the values into a hidden field and pass them around readily enough, I found that the script began behaving erratically when I began to do the little things attendant to making the application work.



For example, in one instance the script began running right through the submit buttons within forms after I had simply assigned a value to a scalar. I tussled with this for a couple of hours, finding resolution of the difficulty in one form only to have it pop back up again as a result of some change that should have had absolutely no effect on the forms whatsoever. From these trials I inferred that the steps I was taking to deal with this single large hidden field were interfering with the references used by CGI methods, in a fashion similar to the problems I described in the previous incarnation. While I have not traced execution though the module to be absolutely certian, the behavior of the script strongly suggests that this is the case.



It is relevant to note that moving data around in this fashion represents moving a little bit beyond the basic model of cgi scripts. At this point, I should either be wrapping some of this stuff into a module, to help keep the main namespace clean, or writing state information into cookies, which kind of works out to the same thing because maintaing state with more complex data structures through the use of cookies would require the use of a custom or canned module to avoid the kinds of difficulties I've run into here. I am not going to do either at this point - in the next section I am going to start building modules out of elements of this code base, and I currently plan to make state management part of the first functionality to be incorporated into the modules for this application.



Controlling the entry of the value for the current inning likely sounds like more of a chore than it really is. All we really have to do is create a widget that will display the set of values from which the user can select the inning. But I also want the user to select the half-inning (top or bottom of the inning) and to have the selection of these two elements placed in context on the page as a whole.




In other words, I want to create something that looks like this ...





and which sets up on the page like this.



Some time after I wrote this section I was testing the page in the context of the revised insert script when I noticed that the radio button group that displays the half_inning value was not displaying the value of the parameter on successive iterations of the script ... while the parameter was there and visible, the appropriate button was not checked. I messed with this in both the original format in which the group is constructed simply by printing the relevant commands back to the browser and by creating a button_group object with the CGI method, and in neither case would the current value be displayed. I have little doubt that I am simply missing the appropriate switch, but to avoid getting hung up here I simply changed that widget to a two value scrolling_list, which from a pragmatic standpoint exhibits the same kind of behavior, resulting in a displayed table that looks like this. Much of the discussion written around the radio button version below, however, has pertinence on levels beyond this specfic behavior, so i'm going to leave that discussion in and include what has been modified in italicized text like this. Look on it as getting two discussions for the price of one. <grin> I'll make an attempt to get back to this specific issue in a later section.


Implementing this is not a big deal. I simply create a single row table with three columns which hold, in turn, the text "Inning", a scrolling_list widget that displays a scrolling list within a small window, and a radio button group from which the half-inning is selected. I then center the widget on the page.

		print $forms->p('<center>');
		print $forms->p('<table border bgcolor="burlywood" width="25%">&<tr><td width="7%">'); 
		print $forms->p('Inning</td><td width="5%"><br><center>');
		print $forms->scrolling_list(-name=>'inning',
		   							 -values=>['01','02'...'20'],
									 -size=>'3');
		print $forms->p('</center></td><td width="8%">'),
				("<input type='radio' name='half_inning' value='a'>Top<input type='radio' name='half_inning' value='b'>Bottom<br>");
( 		print $forms->scrolling_list(-name=>'half_inning',
									-values=>['top','bottom'],
									-linebreak=>"true");)
		print $forms->p('</td></tr></table></center><center>');
As you can see both in the illustrations and in the code snippet, I have limited the width of this table to 25% of the page width and set the background color within the table to something that makes it stand out yet fits in well with the overall design of the page <ahem>. The illustrations shown above represent what is drawn at the resolution of my display, 1280x1024. (I like to display a lot of stuff on my desktop.)



I played around with the width values to assign to the columns in the table until their relative widths seemed about right. Width settings within the columns of a table define the relative width of the column within the overall table width. Therefore, the 7% assined to the first column of the table represents 35% of the table's overall width. (7 / (7+5+8) = 7/20 = 35%). Obviously, there is a level on which the percent sign is not relevant, because the width of this column is neither 7% of the screen width nor 7% of the table width. In fact, it is not 7% of anything. If you remove the % signs, however, assuming that the width of the table will simply be calculated on the basis of the relative size of the width values, whatever formatting the individual cells might have, such as the centering of the scrolling_list within the middle cell, will be lost, although the relative size of the cells will be drawn appropriately. On one level this does not make any sense, but if you think about it a bit you will likely see what is going on here. The web server is sending a stream of information to the browser which the browser is parsing and using as instructions on how to draw the page. Within the commands that represent the table definition the percent signs mean something, and their absence in certain contexts can create problems for the browser. Internet Explorer recovers from this one fairly gracefully, losing only cell-formatting. The output from other browsers may not fare as well, losing formatting at a higher level. If you keep in mind just what the html generated by your cgi scripts represents, you will be better able to debug some quirky contexts.



That being said, it is just as appropriate to check the manner in which page elements display under different resolutions as it is to check the display of a page as a whole. In this instance I felt reasonably certain that the table containing the widgets would display appropriately. If you take another look at the widget table above you can see that there is plenty of space around the cell elements. To verify that viability, however, I reset my display to 640x480 and accessed the script. The widget table displayed as in the illustration to the right. As you can see, the display was appropriate, but there was little room to spare. The final column, containing the radio buttons, has taken most of the available table width to display the labels associated with the two buttons. This reinforces the fact that major changes to a page should always be taken as requiring tests under different resolutions.



(As an aside, you may note that I simply print the radio buttons back to the page in the above code rather than calling the CGI modules radio_group method. The reason for this is simple ... with only two buttons I thought it was just as easy to print back to the page rather than defining an array for the labels and calling the CGI method.)



Beyond construction of the table holding the inning selection widgets, few changes are required to this script to implement the addition of half_inning as a data element. As in earlier circumstances in which I added a data element that plays a role in controlling script execution, it has to be added to the set of hidden fields being passed from script invocation to script invocation and also added to the string written to the output file. In addition, however, I decided to reset the inning_order counter upon changes in the half_inning rather than upon inning changes, so minor changes in the store subroutine were required to accomodate that. As I have been through those steps a couple of times already, I will leave them for you to track down on your own.



Next: Cleaning up the insert script