in reply to Re: Generating a container table in HTML::CalendarMonth
in thread Generating a container table in HTML::CalendarMonth

Hi Mr. Muskrat, thanks for getting back to me.

I had more or less arrived at the script you propose, which does indeed push the calendars into the container table. The problem is that the line

$cal->item( 15, 16, 17 )->wrap_content( font({ size => 4, color => 're +d' }) );
dictates the days highlighted, rather than the array @days.

My challenge is to associate each @days with its corresponding $new_c

The code below I hope shows a bit more clearly what I'm trying to achieve - tho' it doesn't work - perhaps you wouldn't mind taking a look and giving me your comments. (I've done very little with hashes so far so I'm guessing a little bit on how this might be achieved).

#!/usr/bin/perl -w use strict; use CGI qw(:standard); use Date::Calc qw(:all); use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use lib '/home/users/t/my_site.com-90978/lib'; use HTML::AsSubs; use HTML::Element; use HTML::CalendarMonth; # @dates has already been sorted my @dates = ( 730000, 731158, 731159, 731160, 731161, 731178, 735000 ) +; my @cals; print header(), start_html(-title => "Calendars"); # As long as there is a date left in @dates while (defined $dates[0]) { # get the first value from @dates leaving @dates alone my $days = $dates[0]; # find out the year, month and day so we can create a calendar my ($year, $month, $day) = Add_Delta_Days(1,1,1, $days - 1); # run the CreateCal subroutine with the year and month from the firs +t date # store the returned value in @dates so it can be used the next time + through the while loop @dates = CreateCal($year, $month, @dates); } exit(0); sub CreateCal { # Get the year and month for the calendar # as well as the @dates to use my ($cyear, $cmonth, @dates) = @_; # set up some variables that are local to this subroutine my (@days, @temp); my %calendar; my $new_c; my $t; # Process each $days in @dates foreach my $days (@dates) { # Get the year, month and day of $days my ($year, $month, $day) = Add_Delta_Days(1,1,1, $days - 1); # does it match the calendar we are creating? if ($year == $cyear && $month == $cmonth) { # if yes, then add the $day to @days push (@days, $day); } else { # if no, then add the $days to @temp push (@temp, $days); } } #while there are spare $days remaining if (@temp) { my $new_c = new HTML::CalendarMonth(month => $cmonth, year => $c +year,); #Create hash linking $new_c and @days %calendar = ($new_c => @days); return @temp; #when all $days are used up: } else { # Embolden headers #throw new calendar with @days foreach ($new_c{@days}) { $_->item($_->month,$_->year)->wrap_content(font({size => '2'})) +; $_->item($_->dayheaders)->wrap_content(font({size => '1'})); $_->item(@days)->wrap_content(font({size => 4, color => 'red'})); # Generate container table my $t = new HTML::ElementTable ( maxrow => 1, maxcol => 6 ); # Populate container table foreach (0..$#cals) { $t->cell(0,$_)->push_content($cals[$_]); } print $t->as_HTML; } } } #There may be a lot of gobbledygook here but I hope it gives an idea o +f what I'm trying to do with this approach. #Other issue is re-sorting so the calendars are placed in the table in + order.

Replies are listed 'Best First'.
Possible Solution for Generating a container table in HTML::CalendarMonth
by Mr. Muskrat (Canon) on Mar 29, 2003 at 20:36 UTC

    I think I have solved your problem jonnyfolk.

    #!/usr/bin/perl use strict; use warnings; use CGI qw( :standard ); use HTML::CalendarMonth; use HTML::AsSubs; use HTML::Element; use Date::Calc qw( :all ); # @dates has already been sorted my @dates = ( 730000, 731158, 731159, 731160, 731161, 731178, 735000 ) +; my ( @cals, @days ); print start_html(-title => 'Calendars'); while ( defined $dates[0] ) { my $days = $dates[0]; my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); my $new_c = new HTML::CalendarMonth ( year => $year, month => $month + ); @dates = CreateCal( $year, $month, @dates ); push( @cals, $new_c ); } # Embolden headers foreach my $calnum ( 0 .. $#cals ) { my $cal = $cals[$calnum]; my @color = @{ $days[$calnum] }; # the days to be colored $cal->item( $cal->month, $cal->year )->wrap_content( font({ size => + '2' }) ); $cal->item( $cal->dayheaders )->wrap_content( font({ size => '1' }) + ); $cal->item( @color )->wrap_content( font({ size => 4, color => 'red +' }) ); } # Generate container table my $t = new HTML::ElementTable ( maxrow => 1, maxcol => 4 ); # Populate container table for my $calnum ( 0 .. $#cals ) { $t->cell( 0, $calnum )->push_content( $cals[$calnum] ); } print $t->as_HTML; print end_html(); exit(0); sub CreateCal { my ( $cyear, $cmonth, @dates ) = @_; my ( @day, @temp ); foreach my $days ( @dates ) { my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); if ( $year == $cyear && $month == $cmonth ) { push ( @day, $day ); } else { push ( @temp, $days ); } } push ( @days, [ @day ] ); # store the days of each calendar return @temp; }

      Hello, Mr Muskrat, sorry about the delay in getting back to you - I've been waiting for some time to go through this properly.

      Firstly this is a definite solution to the problem - it is throwing the calendars, with their specific day arrays into a container table.
      Secondly, I don't understand it!!

      Well, there are one or two things that are new to me and perhaps if you have a little time you wouldn't mind explaining them to me?

      In the sub CreateCal: push ( @days, [ @day ] ); # store the days of each calendar
      you're storing an array into and array, I thought that would need a %hash. What is the significance of the [ ]?

      After #Embolden headers, the line: my @color = @{ $days[$calnum] }; # the days to be colored
      seems to be a hash of some sort but I'm afraid I don't quite get it. (I do get the fact that you are storing an array of dates and then extracting them, but I don't understand the mechanics).

      I'm very impressed at the simplicity of what you have achieved compared to the Heath Robinson approach I had embarked upon - this looks like the real thing.

      I have also been trying very hard to get the calendars to fill different rows:
      the line  $t->cell( 0, $calnum )->push_content( $cals[$calnum] ); pushes all the calendars along a single row.

      If we generate a new table:

      # Generate container table my $t = new HTML::ElementTable ( maxrow => 12, maxcol => 3 );
      then how can I get the calendars to fill across and then down to the next row?

      By using  $t->cell( $calnum, $calnum )->push_content( $cals[$calnum] );
      the calendars fill diagonally, and I had hoped that by using

      # Populate container table for my $calnum ( 0 .. $#cals ) { my $row = int(my $calnum/4); $t->cell( 0, $calnum )->push_content( $cals[$calnum] ); }
      that might do the trick, but I am left with a blank screen. In fact everything I have tried pretty much leaves me with a blank screen!!

      If you have any ideas on the latter and perhaps give an explanation of the former I would be very grateful

      Many thanks, though, for your help so far...

        Basicly, I'm creating an array of array references and then dereferencing them when it's time to use them. Fear not! Arrays of Arrays only sound scary. perlref, perlreftut, perldsc, perllol and References quick reference are all very informative!

        Here's what I think will be the finished product. We calculate the row and column based on the value of $calnum. Enjoy!

        #!/usr/bin/perl use strict; use warnings; use CGI qw( :standard ); use HTML::CalendarMonth; use HTML::AsSubs; use HTML::Element; use Date::Calc qw( :all ); # @dates has already been sorted my @dates = ( 730000, 731158, 731159, 731160, 731161, 731178, 731300, +731310, 731400, 731410, 731500, 731510, 735000 ); my ( @cals, @days ); print start_html(-title => 'Calendars'); while ( defined $dates[0] ) { my $days = $dates[0]; my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); my $new_c = new HTML::CalendarMonth ( year => $year, month => $month + ); @dates = CreateCal( $year, $month, @dates ); push( @cals, $new_c ); } # Embolden headers foreach my $calnum ( 0 .. $#cals ) { my $cal = $cals[$calnum]; my @color = @{ $days[$calnum] }; # the days to be colored $cal->item( $cal->month, $cal->year )->wrap_content( font({ size => + '2' }) ); $cal->item( $cal->dayheaders )->wrap_content( font({ size => '1' }) + ); $cal->item( @color )->wrap_content( font({ size => 4, color => 'red +' }) ); } # Generate container table my $t = new HTML::ElementTable ( maxrow => 12, maxcol => 3 ); my $row = 0; # Populate container table for my $calnum ( 0 .. $#cals ) { my $col = $calnum % 3; my $row = int( $calnum / 3 ); $t->cell( $row, $col )->push_content( $cals[$calnum] ); } print $t->as_HTML; print end_html(); exit(0); sub CreateCal { my ( $cyear, $cmonth, @dates ) = @_; my ( @day, @temp ); foreach my $days ( @dates ) { my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); if ( $year == $cyear && $month == $cmonth ) { push ( @day, $day ); } else { push ( @temp, $days ); } } push ( @days, [ @day ] ); # store the days of each calendar return @temp; }