After seeing all the other posts, I completely rewrote the whole thing. I 
grouped the data in the controller so that entries on the same day will be in 
the same list, making easier to put each day of entries into its own table. I 
have really advanced the whole thing since my original post. Here is my 
controller:

def format_minutes(minutes):
        hours = round(minutes / 60)
        if hours == 0:
            return "00:%02d" % (minutes)
        else:
            minutes -= minutes * hours
            return "%02d:%02d" % (hours, minutes)
        
    def format_full_date(the_date):
        return the_date.strftime('%A, %B %d, %Y')
        
    # get information from database
    week_start, week_end = timeclock.get_week_range_for_date()
    rows = timeclock.list_for_user(auth.user, week_start, week_end)
    minutes_worked = timeclock.get_minutes_for_this_week(auth.user)
    minutes_vacation = timeclock.get_minutes_for_this_week(auth.user, 2)
    minutes_personal = timeclock.get_minutes_for_this_week(auth.user, 3)
    minutes_sick = timeclock.get_minutes_for_this_week(auth.user, 4)
    minutes_total = minutes_worked + minutes_vacation + minutes_personal + 
minutes_sick
    
    # begin formatting minutes for the week
    hours_worked = format_minutes(minutes_worked)
    hours_vacation = format_minutes(minutes_vacation)
    hours_personal = format_minutes(minutes_personal)
    hours_sick = format_minutes(minutes_sick)
    hours_total = format_minutes(minutes_total)
    
    # group entries together to make it easier for the view
    grouped_entries = dict()
    for row in rows:
        full_date = format_full_date(row.calculated_start)
        if full_date in grouped_entries:
            grouped_entries[full_date].append(row)
        else:
            grouped_entries[full_date] = [row]
    
    return dict(grouped_entries=grouped_entries,
        hours_worked=hours_worked, hours_vacation=hours_vacation,
        hours_personal=hours_personal, hours_sick=hours_sick, 
hours_total=hours_total
    )


And this is my view:

{{extend 'layout.html'}}
{{import datetime}}
<h1>Time Clock for {{=auth.user.first_name}} {{=auth.user.last_name}}</h1>

{{still_clocked_in = False}}
<div id="timeclock_list">
{{if len(grouped_entries) > 0:}}
    {{
        def format_time_string(the_date):
            if the_date is None: return 'Still clocked in'
            return the_date.strftime('%I:%M %p')
            
        def format_minutes(minutes):
            hours = round(minutes / 60)
            if hours == 0:
                return "00:%02d" % (minutes)
            else:
                minutes -= minutes * hours
                return "%02d:%02d" % (hours, minutes)
            pass
    }}
    
    {{for k, v in grouped_entries.iteritems():}}
        <h4>{{=k}}</h4>
        <table><thead><tr><th>Time in:</th><th>Time 
out:</th><th>Type:</th><th>Hours:</th></tr></thead><tbody>
        
        {{total_for_day = 0}}
        
        {{for entry in v:}}
            {{
                if entry.calculated_minutes is None:
                   still_clocked_in = True
                   entry_hours = ''
                else:
                    total_for_day += entry.calculated_minutes
                    entry_hours = format_minutes(entry.calculated_minutes)
                pass
                
                date_start = format_time_string(entry.calculated_start)
                date_end = format_time_string(entry.calculated_end)
                entry_type = db.timeclock_events[entry.event_type]
            }}
            
<tr><td>{{=date_start}}</td><td>{{=date_end}}</td><td>{{=entry_type}}</td><td 
class="center">{{=entry_hours}}</td></tr>
        {{pass}}
        
        {{total_for_day_formatted = format_minutes(total_for_day)}}
        </tbody><tfoot><tr><th class="right" colspan="3">Total for 
day:</th><th>{{=total_for_day_formatted}}</th></tr></tfoot></table>
    {{pass}}
</div>

<div id="timeclock_totals">
    <h4>Totals for week</h4>
    <table><tbody>
    
    {{if hours_worked != '00:00':}}
        <tr><td>Total hours worked this week:</td><td 
class="center">{{=hours_worked}}</td></tr>
    {{pass}}
    
    {{if hours_vacation != '00:00':}}
        <tr><td>Total hours of vacation this week:</td><td 
class="center">{{=hours_vacation}}</td></tr>
    {{pass}}
    
    {{if hours_personal != '00:00':}}
        <tr><td>Total hours of personal time this week:</td><td 
class="center">{{=hours_personal}}</td></tr>
    {{pass}}
    
    {{if hours_sick != '00:00':}}
        <tr><td>Total hours sick this week:</td><td 
class="center">{{=hours_sick}}</td></tr>
    {{pass}}
    
    </tbody><tfoot>
    <tr><th class="right">Grand total for this 
week:</th><th>{{=hours_total}}</th></tr>
    </tfoot></table>
{{else:}}
    <h5>No time clock entries for this week.</h5>
{{pass}}
</div>

{{
    if still_clocked_in:
        punch_text = 'Clock out'
    else:
        punch_text = 'Clock in'
    pass
    
    response.write(A(punch_text, _href=URL('punch'), _id='timeclock_punch', 
_class='no_print'))
}}

There is a lot more code because I have since added a lot functionality, but I 
think the code itself is fairly clean. I put most of the computational stuff in 
the controller, and only a couple of things needed to be formatted for the view.

On Mar 3, 2011, at 4:07 PM, Anthony wrote:

> On Thursday, March 3, 2011 10:31:18 AM UTC-5, Ross Peoples wrote:
> I know that web2py has HTML helpers like TABLE(), TR(), etc, but how would I 
> build a table in this way, while in a for loop? This is what I tried so far, 
> but it fails so horribly I don't even know where the error is:
> 
> {{extend 'layout.html'}}
> <h1>Time Clock for {{=user.first_name}} {{=user.last_name}}</h1>
> {{if len(rows) > 0:}}
>     {{
>         def get_day_of_year(the_date):
>             return the_date.timetuple().tm_yday
>             
>         def full_date_name(the_date):
>             return the_date.strftime('%A, %B %d, %Y')
>             
>         def time_string(the_date):
>             return the_date.strftime('%I:%M %p')
>             
>         prev_day_of_year = None
>         tables = []
>         trs = None
>         for row in rows:
>             if get_day_of_year(row.calculated_start) != prev_day_of_year:
>                 if trs is not None:
>                     tables[] = (H4(full_date_name(row.calculated_start)), trs)
>                     trs = []
>                     
>                 trs[] = TR((TD(time_string(row.calculated_start)), 
> TD(time_string(row.calculated_end))))
>                 prev_day_of_year = get_day_of_year(row.calculated_start)
>             else:
>                 trs[] = TR((TD(time_string(row.calculated_start)), 
> TD(time_string(row.calculated_end))))
>  
> Am I missing something here? Where are you building a table -- I don't see 
> any calls to TABLE(), just TR(). Also, I'm not sure about your syntax. It 
> looks like you are passing a tuple of TD's to TR instead of passing the TD's 
> as separate arguments (i.e., there's an extra set of parentheses inside TR). 
> Finally, what is 'trs[] =' doing -- I think that will raise a syntax error. 
> You should be able to create a table object (e.g., table = TABLE()), and then 
> append TR's to it via append -- e.g., table.append(TR('cell 1', 'cell 2')).
>  
> Anthony
>  

Reply via email to