# ================================================================== # Gossamer Threads Module Library - http://gossamer-threads.com/ # # GT::SQL::Display::HTML # Author: Scott & Alex # $Id: Relation.pm,v 1.18 2004/08/28 03:53:45 jagerman Exp $ # # Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. # ================================================================== # # Description: # HTML module that provides a set of method to control your # user display in order to get rid of HTML coding inside CGI script. # package GT::SQL::Display::HTML::Relation; # =============================================================== use strict; use vars qw/@ISA $AUTOLOAD $VERSION $ERROR_MESSAGE $ATTRIBS $DEBUG $FONT %SIZE_FORMS/; use GT::SQL::Display::HTML; @ISA = qw/GT::SQL::Display::HTML/; $FONT = 'face="Tahoma,Arial,Helvetica" size=2'; $VERSION = sprintf "%d.%03d", q$Revision: 1.18 $ =~ /(\d+)\.(\d+)/; $DEBUG = 0; $ERROR_MESSAGE = 'GT::SQL'; $ATTRIBS = { db => undef, input => undef, code => {}, mode => '', font => $FONT, hide_timestamp => 0, view_key => 0, defaults => 0, search_opts => 0, values => {}, multiple => 0, table => 'border=0 width=500', tr => '', td => 'valign=top align=left', extra_table => 1, col_font => $FONT, val_font => $FONT, hide => [], skip => [], view => [], disp_form => 1, disp_html => 0, file_field => 0, file_delete => 0, file_use_path => 0, }; sub display { # --------------------------------------------------------------- # Display a record as html. # my $self = shift; my $opts = shift; $self->reset_opts; $opts->{disp_form} = 0; $opts->{disp_html} = 1; return $self->_display ($opts || ()); } sub _display { # --------------------------------------------------------------- # Handles displaying of a form or a record. # my $self = shift; # Initiate if we are passed in any arguments as options. if (@_) { $self->init (@_); } # Get the column hash and primary key $self->{pk} = [$self->{db}->pk] unless $self->{pk}; $self->{cols} = $self->{db}->ordered_columns; # Output my $out = ''; # Hide the primary keys. $self->{view_key} and push (@{$self->{view}}, @{$self->{pk}}) if ($self->{pk}); # Now go through each column and print out a column row. my @ntables = values %{$self->{db}->{tables}}; my (@tmp, @tables); for my $t (@ntables) { my @cols = $t->ordered_columns; my %fk = $t->fk; my %cols = $t->cols; my $name = $t->name; my $found = 0; COL: foreach my $col_name (@cols) { if (exists $self->{values}->{$col_name}) { $self->{values}->{$name . '.' . $col_name} = delete $self->{values}->{$col_name}; } $self->{cols}->{$name . '.' . $col_name} = $cols{$col_name}; FK: for (keys %fk) { if (exists $self->{db}->{tables}->{$_}) { if (exists $fk{$_}->{$col_name}) { $found = 1; last FK; } } } } $found ? (push (@tmp, $t)) : (@tables = ($t)); } push @tables, @tmp; # Calculate the form values. my $values = $self->_get_defaults; # Set the table widths depending on if we need a third column. my ($cwidth, $vwidth) = ('30%', '70%'); if ($self->{search_opts}) { $cwidth = "30%"; $vwidth = "60%" } for my $table (@tables) { $out .= $self->mk_table ( table => $table, values => $values, cwidth => $cwidth, vwidth => $vwidth ); } $out .= '
'; foreach (@{$self->{hide}}) { my $field_name = $self->{multiple} ? "$self->{multiple}-$_" : $_; my $val = $values->{$_}; if (exists $self->{cols}->{$_}->{time_check} and $self->{cols}->{$_}->{time_check}) { $val ||= $self->_get_time ($self->{cols}->{$_}); } defined $val or ($val = ''); GT::SQL::Display::HTML::_escape(\$val); $out .= qq~~; } $self->{extra_table} and ($out .= "\n"); return $out; } sub mk_table { my $self = shift; my %opt = @_; my $out = ''; $self->{extra_table} and ($out .= "

"); my $cols = $opt{table}->cols; my $name = $opt{table}->name; $out .= qq( {table}> ); my @cols = $opt{table}->ordered_columns; my %fk = $opt{table}->fk; COL: foreach my $col_name (@cols) { $out .= $self->mk_row (%opt, col_name => $col_name, fk => \%fk); } $out .= "
$name
\n"; $out .= "

\n" if $self->{extra_table}; return $out; } sub mk_row { my $self = shift; my %opt = @_; my $out = ''; for (keys %{$opt{fk}}) { if (exists $self->{db}->{tables}->{$_}) { (exists $opt{fk}->{$_}->{$opt{col_name}}) and return ''; } } my $col = $opt{table}->name . '.' . $opt{col_name}; # Run any code refs that have been setup. if (exists $self->{code}->{$col} and (ref $self->{code}->{$col} eq 'CODE')) { $out .= $self->{code}->{$col}->($self, $self->{cols}->{$col}, $opt{values}); return ''; } return '' if $self->_skip ($col); # Set the form name (using increment for multiple if requested) and also the display name. my $field_name = $self->{multiple} ? "$self->{multiple}-$col" : $col; my $display_name = exists ($self->{cols}->{$col}->{form_display}) ? $self->{cols}->{$col}->{form_display} : $col; my $value = $opt{values}->{$col}; my $disp = $self->{disp_form} ? $self->_get_form_display ($col) : $self->_get_html_display ($col); $disp eq 'hidden' and push (@{$self->{hide}}, $col) and return ''; $out .= "{tr}>{td} width='$opt{cwidth}'>{col_font}>$display_name{td} width='$opt{vwidth}'>{val_font}>"; # Get the column display subroutine $out .= $self->$disp( { name => $field_name, def => $self->{cols}->{$col}, value => $value }, $opt{values}, $self ); $out .= ""; # Display any search options if requested. if ($self->{search_opts}) { my $is_pk = 0; for (@{$self->{pk}}) { $is_pk = 1, last if ($_ eq $col); } $out .= qq~{td} width="10%">{val_font}>~; $out .= $self->_mk_search_opts({ name => $field_name, def => $self->{cols}->{$col}, pk => $is_pk }) || ' '; $out .= ""; } $out .= "\n"; return $out; } sub _get_defaults { # ------------------------------------------------------------------- # Returns default values for fields. Bases it on what's passed in, # cgi input, def file defaults, otherwise blank. # my $self = shift; my @ntables = values %{$self->{db}->{tables}}; my @cols = $self->{db}->ordered_columns; my $c = $self->{cols}; my $values = {}; foreach my $col (@cols) { my $value = ''; if (exists $self->{values}->{$col}) { $value = $self->{values}->{$col} } elsif (exists $self->{input}->{$col}) { $value = $self->{input}->{$col} } elsif ($self->{defaults} and exists $c->{$col}->{default}) { if ($c->{$col}->{type} =~ /DATE|TIME|YEAR/) { (defined $c->{$col}->{default} and $c->{$col}->{default} =~ /0000/) ? ($value = $self->_get_time($c->{$col})) : ($value = $c->{$col}->{default}); } else { $value = $c->{$col}->{default}; } } elsif ($self->{defaults} and $c->{$col}->{type} =~ /DATE|TIME|YEAR/) { $value = $self->_get_time($c->{$col}); } $values->{$col} = $value; } return $values; } 1; __END__ =pod # Options for display forms/views: # hide_timestamp => 1 # Do not display timestamp fields. # search_opts => 1 # Add search options boxes. # multiple => 1 # Prepend $multiple- to column names. # defaults => 1 # Use .def defaults. # values => {} # hash ref of values to use (overrides input) # table => 'string' # table properties, defaults to 0 border. # tr => 'string' # table row properties, defaults to none. # td => 'string' # table cell properties, defaults to just aligns. # extra_table => 0 # disable wrap form in extra table for looks. # col_font => 'string' # font to use for columns, defaults to $FONT. # val_font => 'string' # font to use for values, defaults to $FONT. # hide => [] # display fields as hidden tags. # view => [] # display fields as html with hidden tags as well. # skip => [] # don't display array of column names. =cut