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

Not exactly sure if this is what you are looking for... I basicly took my old code from Solution for Date::Calc to HTML::CalendarMonth and pasted in the new code that you wrote.

#!/usr/bin/perl use strict; use warnings; use Date::Calc qw(:all); use CGI qw(:standard); 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"); 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 + ); push ( @cals, $new_c ); @dates = CreateCal( $year, $month, @dates ); } # Embolden headers foreach my $cal ( @cals ) { $cal->item( $cal->month, $cal->year )->wrap_content( font({ size => + '2' }) ); $cal->item( $cal->dayheaders )->wrap_content( font({ size => '1' }) + ); $cal->item( 15, 16, 17 )->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 ( @days, @temp ); foreach my $days ( @dates ) { my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); if ( $year == $cyear && $month == $cmonth ) { push ( @days, $day ); } else { push ( @temp, $days ); } } return @temp; }

added It does put the calendars into a container table.

Replies are listed 'Best First'.
Re: Re: Generating a container table in HTML::CalendarMonth
by jonnyfolk (Vicar) on Mar 27, 2003 at 19:51 UTC
    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.

      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...