mikejones has asked for the wisdom of the Perl Monks concerning the following question:

Respected monks... I am trying to get this to print right, but seem to fail often. I am trying to print a 30 day calander (-15 days from today and +15 days from today) with todays date in bold which I have done, but cannot seem to get the 30 days to print using a table in CGI. Here is my code:
#!/usr/bin/perl #use strict; #use warnings; require "dbi-lib.pl"; use CGI qw/:standard *table start_ul/, (-unique_headers); use CGI::Carp qw(fatalsToBrowser); use DBI; my $cgi = new CGI; local $sth; #----------------------# # Function calls # #----------------------# print_header(); initialize_dbi(); #----------------# # Begin Main # #----------------# print $cgi->header(), $cgi->start_html ('Oreilly Lesson 11'), $cgi->h1 ({-style=>'Color:blue'},'SQL Class'); print "<u>",$cgi->strong('Date/Time CGI Table:'),"</u><p>"; print $cgi->caption('MySQL calendar table output, Lesson 11:'); print "<p>"; run_statement( "select date_format(curdate(), '%b %e, %Y');" ); my $today = $sth->fetchrow; run_statement("select dayofweek(curdate() );" ); my $dayofweek = $sth->fetchrow; #&run_statement( "select date_format(curdate()-2,'%W');" ); + #my $twodayago = $sth->fetchrow; #print "$twodayago <p>"; my %WeekDays = ( Sunday => 1, Monday => 2, Tuesday => 3, Wednesday => 4, Thursday => 5, Friday => 6, Saturday => 7 ); my ($day, $day1, $week,) = (0,0,0); my (@weeks, @weeks1, @weeks_anonymous,) = ((),(),()); ## Set up array with dates minus 15 days and plus 15 days from current + date ## foreach $day ('-15' .. '15') { run_statement( "select date_format(date_add(curdate(), interval '$ +day' day), '%b %e, %Y');" ); push (@weeks, $sth->fetchrow); } ## Match up dates with dayofweek #'s ## foreach $day1 ('-15' .. '15') { run_statement( "select dayofweek(date_add(curdate(), interval '$da +y1' day));" ); push (@weeks1, $sth->fetchrow); } ## Begin Table ## print table({border=>undef}); #print Tr ({-align=>'CENTER',-valign=>'TOP'}); @weeks_anonymous = ( [ $weeks[0], $weeks[1], $weeks[2], $weeks[3], + $weeks[4], $weeks[5], $weeks[6] ], [ $weeks[7], $weeks[8], $weeks[9], $weeks[10], + $weeks[11], $weeks[12], $weeks[13] ], [ $weeks[14], $weeks[15], $weeks[16], $weeks[17], + $weeks[18], $weeks[19], $weeks[20] ], [ $weeks[21], $weeks[22], $weeks[23], $weeks[24], + $weeks[25], $weeks[26], $weeks[27] ], [ $weeks[28], $weeks[29], $weeks[30], $weeks[31], + undef, undef, undef ], + ); foreach $element (@weeks_anonymous) { print Tr({-align=>'CENTER',-valign=>'TOP'}); for $date (@{$element}) { if (! defined $date) { print td (''); } elsif ($date eq $today) { print td(strong($date) ); } else { print td ($date); } } print $cgi->end_Tr; } print $cgi->end_html; # thank you !

Replies are listed 'Best First'.
Re: cgi calander
by Joost (Canon) on Feb 11, 2007 at 03:09 UTC
Re: cgi calander
by GrandFather (Saint) on Feb 11, 2007 at 04:01 UTC

    For a start decide if you are going to use the OO interface to CGI or the functional interface. If you are going to use the functional interface you don't need to create a $cgi object.

    I don't see anything in your code that aligns dates (numeric) with day (name). You may find it helps to do this in two passes - generate a table (2d array) of weeks populated with the correct dates (and undefs at start and end for "missing" dates), then loop over the weeks to generate the HTML table. The following may help:

    use strict; use warnings; use CGI::Pretty qw(:standard start_table end_table start_Tr end_Tr), ( +-unique_headers); use CGI::Carp qw(fatalsToBrowser); print header(); print start_html (-title => "Calendar sample"); my @weekDays = qw(Sunday Monday Tuesday Wednesday Thursday Friday Satu +rday); my $today = 11; my @weeks = ( [undef, undef, undef, undef, undef, undef, 27], [28, 29, 30, 31, 1, 2, 3], [ 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24], [25, 26, undef, undef, undef, undef, undef] ); print start_table(); print Tr ({-align=>'CENTER',-valign=>'TOP'}, td (\@weekDays)); for my $week (@weeks) { print start_Tr({-align=>'CENTER',-valign=>'TOP'}); for my $date (@$week) { if (! defined $date) { print td (''); } elsif ($date == $today) { print td(strong($date)); } else { print td ($date); } } print end_Tr(); } print end_html ();

    Generates:

    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
    27
    28 29 30 31 1 2 3
    4 5 6 7 8 9 10
    11 12 13 14 15 16 17
    18 19 20 21 22 23 24
    25 26

    Update: clean up table layout


    DWIM is Perl's answer to Gödel

      Some creative urge over took me and i figured out the date calculations to go with your HTML output! ;)

      use strict; use warnings; use Data::Dumper; use CGI::Pretty qw(:standard start_table end_table start_Tr end_Tr), ( +-unique_headers); #use CGI::Carp qw(fatalsToBrowser); use Date::Calc qw(Week_of_Year Monday_of_Week Add_Delta_Days Standard +_to_Business); my @day = (2007,2,10); my @week = Week_of_Year(@day); my @weeks = []; for my $delta (-15..15) { my @n_day = Add_Delta_Days(@day,$delta); #calculate which week we are in my @n_week = Week_of_Year(@n_day); #calculate the day of the week my @b_day = Standard_to_Business(@n_day); #put it in a nice array of arrayref $weeks[$n_week[0]]->[$b_day[2]-1] = $n_day[2]; } # this seemed easier than calculating the smallest week # number and subtracting that from each index @weeks = grep {defined} @weeks; print header(); print start_html (-title => "Calendar sample"); my @weekDays = qw(Mon Tue Wed Thur Fri Sat Sun); print start_table(); print Tr ({-align=>'CENTER',-valign=>'TOP'}, td (\@weekDays)); for my $week (@weeks) { print start_Tr({-align=>'CENTER',-valign=>'TOP'}); for my $date (@$week) { if (! defined $date) { print td (''); } elsif ($date == $day[2]) { print td(strong($date)); } else { print td ($date); } } print end_Tr(); } print end_html ();

      ___________
      Eric Hodges
      ok thank you for pushing me in the right direction, but now when the dates change my calendar gets thrown off. I tested this by simply adding and subtracting 1 from the SQL call curdate() +1 or curdate() -1. Here is my code:
      #use strict; #use warnings; require "dbi-lib.pl"; use CGI qw/:standard *table start_ul/, (-unique_headers); use CGI::Carp qw(fatalsToBrowser); use DBI; my $cgi = new CGI; local $sth; #----------------------# # Function calls # #----------------------# print_header(); initialize_dbi(); #----------------# # Begin Main # #----------------# print $cgi->header(), $cgi->start_html ('Oreilly SQL Class, Lesson 11'),# Header $cgi->h1 ({-style=>'Color:blue'},'SQL Class');# Body print "<u>",$cgi->strong('Date/Time CGI Table:'),"</u><p>"; print $cgi->caption('MySQL calendar table output, Lesson 11:'); print "<p>"; run_statement( "select date_format(curdate(), '%b %e, %Y');" ); my $today = $sth->fetchrow; #run_statement( "select dayofweek('$today');" ); #my $dayofweek = $sth->fetchrow; #print $dayofweek; #&run_statement( "select date_format(curdate()-2,'%W');" ); + #my $twodayago = $sth->fetchrow; #print "$twodayago <p>"; my @WeekDays = qw(Sunday Monday Tuesday Wednesday Thursday Friday Satu +rday); my ($day,$week,) = (0,0); my (@weeks, @weeks_anonymous,) = (); foreach $day ('-15' .. '15') { run_statement( "select date_format(date_add(curdate(), interval '$ +day' day), '%b %e, %Y');" ); push (@weeks, $sth->fetchrow); } ## Begin Table ## print table({border=>undef}); print Tr ({-align=>'CENTER',-valign=>'TOP'}, td (\@WeekDays)); @weeks_anonymous = ( [ undef, undef, undef, $weeks[0], $weeks[1], $weeks[2], $weeks[3] ], [ $weeks[4], $weeks[5], $weeks[6], $weeks[7], $weeks[8], $weeks[9], $ +weeks[10] ], [ $weeks[11], $weeks[12], $weeks[13], $weeks[14], $weeks[15], $weeks[1 +6], $weeks[17] ], [ $weeks[18], $weeks[19], $weeks[20], $weeks[21], $weeks[22], $weeks[2 +3], $weeks[24] ], [ $weeks[25], $weeks[26], $weeks[27], $weeks[28], $weeks[29], $weeks[3 +0], $weeks[31] ], ); foreach $element (@weeks_anonymous) { print Tr({-align=>'CENTER',-valign=>'TOP'}); for $date (@{$element}) { if (! defined $date) { print td (''); } elsif ($date eq $today) { print td(strong($date)); } else { print td ($date); } } print $cgi->end_Tr; } print $cgi->end_html; ************************** I was thinking of hard-coding January, Febuary and March months into +an anonymous array then combined with the @weeks_anonymous elements c +reate a final anonymous array that reflects the correct pairing of +daynames and dates???
Re: cgi calander
by CountZero (Bishop) on Feb 11, 2007 at 09:12 UTC
    It can be as easy as:
    use strict; use HTML::Calendar::Simple; my $cal = HTML::Calendar::Simple->new; my $html = $cal->calendar_month; print $html;
    Do check out HTML::Calendar::Simple it has a lot of useful functions (such as adding a pin up picture above the data!). If you need even more functionality there is HTML::CalendarMonthSimple or if you want to have total control HTML::CalendarMonth (which is built upon HTML::ElementTable).

    Of course all these are on a calender month basis, but can be used as a basis and inspiration for your -15 to +15 calender.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      ok I did and I will again to refresh. thank you
      I am not able to use this module due to server Perl restrictions. I am taking an online class and they will not allow me to install this module due to the version of Perl and c compiler. Anywho...I still need some help as my date and daynames are not matching up when days pass or are subtracted. Shouldn't I be able to manipulate the @weeks_anonymous array using the SQL select dayofweek(curdate()); instead of using hardcoded undef's? Please help or any hints would be appreciated.
      thx!
      #!/usr/bin/perl #use strict; #use warnings; require "dbi-lib.pl"; use CGI qw/:standard *table start_ul/, (-unique_headers); use CGI::Carp qw(fatalsToBrowser); use DBI; my $cgi = new CGI; local $sth; #----------------------# # Function calls # #----------------------# print_header(); initialize_dbi(); #----------------# # Begin Main # #----------------# print $cgi->header(), $cgi->start_html ('Oreilly SQL Class, Lesson 11'), + # Header $cgi->h1 ({-style=>'Color:blue'},'Derek\'s SQL Class'); + # Body print "<u>",$cgi->strong('Date/Time CGI Table:'),"</u><p>"; print $cgi->caption('MySQL calendar table output, Lesson 11:'); print "<p>"; run_statement( "select date_format(curdate(), '%b %e, %Y');" ); my $today = $sth->fetchrow; run_statement("select dayofweek(curdate() );" ); my $dayofweek = $sth->fetchrow; print $dayofweek; #&run_statement( "select date_format(curdate()-2,'%W');" ); + #my $twodayago = $sth->fetchrow; #print "$twodayago <p>"; my @WeekDays = qw(Sunday Monday Tuesday Wednesday Thursday Friday Satu +rday); my ($day,$week,) = (0,0); my (@weeks, @weeks_anonymous,) = ((),()); foreach $day ('-15' .. '15') { run_statement( "select date_format(date_add(curdate(), interval '$ +day' day), '%b %e, %Y');" ); push (@weeks, $sth->fetchrow); } ## Begin Table ## print table({border=>undef}); print Tr ({-align=>'CENTER',-valign=>'TOP'}, td (\@WeekDays)); @weeks_anonymous = ( [ $weeks[0], $weeks[1], $weeks[2], $weeks[3] + ], [ $weeks[4], $weeks[5], $weeks[6], $weeks[7], + $weeks[8], $weeks[9], $weeks[10] ], [ $weeks[11], $weeks[12], $weeks[13], $weeks[14], + $weeks[15], $weeks[16], $weeks[17] ], [ $weeks[18], $weeks[19], $weeks[20], $weeks[21], + $weeks[22], $weeks[23], $weeks[24] ], [ $weeks[25], $weeks[26], $weeks[27], $weeks[28], + $weeks[29], $weeks[30], $weeks[31] ], ); foreach $element (@weeks_anonymous) { print Tr({-align=>'CENTER',-valign=>'TOP'}); for $date (@{$element}) { if (! defined $date) { print td (''); } elsif ($date eq $today) { print td(strong($date)); } else { print td ($date); } } print $cgi->end_Tr; } print $cgi->end_html;