Name

table-editor — table editor

ATTRIBUTES

Attribute Pos. Req. Default Description
mv_data_table | table Yes table name
item_id | key Yes key
[ ui_data_fields | mv_data_fields | fields ] Yes No All fields. Fields to edit.
[ ui_meta_view | view ]
cgi
ui_multi_key
item_id_left
ui_sequence_edit
notable
ui_clone_id | clone clone existing record
ui_profile | profile form profile
all_opts
save_meta
no_meta None Turns off meta editor link.
across
cell_span
default_ref
append
check
class
database
hidden None hidden form variables
default None default values
disabled
error
extra
field
filter
form
height
help inline help
help_url
label
wid_href
lookup
lookup_query
meta
js_check
maxlength
options
outboard
override
passed
pre_filter
prepend
template
widget
widget_class HTML class for all widgets
width
colspan
blabel
elabel
hidden_all
next_text OK Label for "OK" button.
cancel_text Cancel Label for "Cancel" button.
back_text Back Label for "Back" button.
no_top None Whether to hide buttons at the top or not.
ok_button_style font-weight: bold; width: 40px; text-align: center HTML style attribute for "OK" button.
wizard
nosave
action_click
wizard_next
wizard_cancel
mv_cancelpage
mv_prevpage
output_map
no_table_meta
tabbed
auto_secure
keep_errors
ui_profile_success
mv_failpage
orig_cancel_text
orig_back_text
action
message_label
all_errors
color_fail
[ ui_display_only | email_fields ]
interpolate     0 interpolate input?
reparse     1 interpolate output?
hide     0 Hide the tag return value?

DESCRIPTION

BEHAVIOR

This tag does not appear to be affected by, or affect, the rest of Interchange.

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

table-editor is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0:

Source: code/UI_Tag/table_editor.coretag
Lines: 30


# Copyright 2002-2007 Interchange Development Group and others
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  See the LICENSE file for details.
# 
# $Id: table_editor.coretag,v 1.18 2007-03-30 23:40:54 pajamian Exp $

UserTag table-editor Order          mv_data_table item_id
UserTag table-editor addAttr
UserTag table-editor AttrAlias      clone ui_clone_id
UserTag table-editor AttrAlias      table mv_data_table
UserTag table-editor AttrAlias      fields ui_data_fields
UserTag table-editor AttrAlias      mv_data_fields ui_data_fields
UserTag table-editor AttrAlias      key   item_id
UserTag table-editor AttrAlias      view  ui_meta_view
UserTag table-editor AttrAlias      profile ui_profile
UserTag table-editor AttrAlias      email_fields ui_display_only
UserTag table-editor hasEndTag
UserTag table-editor Version        $Revision: 1.18 $
UserTag table-editor MapRoutine     Vend::Table::Editor::editor
UserTag table-editor Documentation  <<EOD
Hint:   table_editor may not work for tables where the primary key
field is named 'id'.

You can change this behavior by just removing this line from ICDIR/etc/varnames:

    mv_session_id            id
EOD

Source: lib/Vend/Table/Editor.pm
Lines: 2594

sub editor {

my ($table, $key, $opt, $overall_template) = @_;
show_times("begin table editor call item_id=$key") if $Global::ShowTimes;

#::logDebug("overall_template=$overall_template\nin=$opt->{overall_template}");
use vars qw/$Tag/;

editor_init($opt);

my @messages;
my @errors;
my $pass_return_to;
my $hidden = $opt->{hidden} ||= {};

#::logDebug("key at beginning: $key");
$opt->{mv_data_table} = $table if $table;
$opt->{table}      = $opt->{mv_data_table};
$opt->{ui_meta_view}  ||= $CGI->{ui_meta_view} if $opt->{cgi};

$key ||= $opt->{item_id};

if($opt->{cgi}) {
  $key ||= $CGI->{item_id};
  unless($opt->{ui_multi_key} = $CGI->{ui_multi_key}) {
    $opt->{item_id_left} ||= $CGI::values{item_id_left};
    $opt->{ui_sequence_edit} ||= $CGI::values{ui_sequence_edit};
  }
}

if($opt->{ui_sequence_edit} and ! $opt->{ui_multi_key}) {
  delete $opt->{ui_sequence_edit};
  my $left = delete $opt->{item_id_left}; 

  if(! $key) {
#::logDebug("No key, getting from $left");
    if($left =~ s/(.*?)[\0,]// ) {
      $key = $opt->{item_id} = $1;
      $hidden->{item_id_left} = $left;
      $hidden->{ui_sequence_edit} = 1;
    }
    elsif($left) {
      $key = $opt->{item_id} = $left;
    }
#::logDebug("No key, left now $left");
  }
  elsif($left) {
#::logDebug("Key, leaving left $left");
    $hidden->{item_id_left} = $left;
    $hidden->{ui_sequence_edit} = 1;
  }
}

$opt->{item_id} = $key;

$pass_return_to = save_cgi() if $hidden->{ui_sequence_edit};

my $data;
my $exists;
my $db;
my $multikey;

## Try and sneak a peek at the data so we can determine views and
## maybe some other stuff -- we definitely need table/key or a 
## clone id
unless($opt->{notable}) {
  # From Vend::Data
  my $tab = $table || $opt->{mv_data_table} || $CGI->{mv_data_table};
  my $key = $opt->{item_id} || $CGI->{item_id};
  $db = database_exists_ref($tab);

  if($db) {
    $multikey = $db->config('COMPOSITE_KEY');
    if($multikey and $key !~ /\0/) {
      $key =~ s/-_NULL_-/\0/g;
    }
    if($opt->{ui_clone_id} and $db->record_exists($opt->{ui_clone_id})) {
      $data = $db->row_hash($opt->{ui_clone_id});
    }
    elsif ($key and $db->record_exists($key)) {
      $data = $db->row_hash($key);
      $exists = 1;
    }
    
    if(! $exists and $multikey) {
      $data = {};
      eval { 
        my @inits = split /\0/, $key;
        for(@{$db->config('_Key_columns')}) {
          $data->{$_} = shift @inits;
        }
      };
    }
  }
}

my $regin = $opt->{all_opts} ? 1 : 0;

resolve_options($opt, undef, $data);

$Trailer = $opt->{xhtml} ? '/' : '';
if($regin) {
  ## Must reset these in case they get set from all_opts.
  $hidden = $opt->{hidden};
}
$overall_template = $opt->{overall_template}
  if $opt->{overall_template};

$table = $opt->{table};
$key = $opt->{item_id};
if($opt->{save_meta}) {
  $::Scratch->{$opt->{save_meta}} = uneval($opt);
}
#::logDebug("key after resolve_options: $key");

#::logDebug("cell_span=$opt->{cell_span}");
#### This code is also in resolve_options routine, change there too!
my $rowdiv         = $opt->{across}    || 1;
my $cells_per_span = $opt->{cell_span} || 2;
my $rowcount = 0;
my $span = $rowdiv * $cells_per_span;
#### 

my $oddspan = $span - 1;
my $def = $opt->{default_ref} || $::Values;

my $append       = $opt->{append};
my $check        = $opt->{check};
my $class        = $opt->{class} || {};
my $database     = $opt->{database};
my $default      = $opt->{default};
my $disabled     = $opt->{disabled};
my $error        = $opt->{error};
my $extra        = $opt->{extra};
my $field        = $opt->{field};
my $filter       = $opt->{filter};
my $form       = $opt->{form};
my $height       = $opt->{height};
my $help         = $opt->{help};
my $help_url     = $opt->{help_url};
my $id           = $opt->{id};
my $label        = $opt->{label};
my $wid_href     = $opt->{wid_href};
my $lookup       = $opt->{lookup};
my $lookup_query = $opt->{lookup_query};
my $meta         = $opt->{meta};
my $js_check     = $opt->{js_check};
my $maxlength    = $opt->{maxlength};
my $opts         = $opt->{opts};
my $options      = $opt->{options};
my $outboard     = $opt->{outboard};
my $override     = $opt->{override};
my $passed       = $opt->{passed};
my $pre_filter   = $opt->{pre_filter};
my $prepend      = $opt->{prepend};
my $template     = $opt->{template};
my $widget       = $opt->{widget};
my $width        = $opt->{width};
my $colspan      = $opt->{colspan} || {};

my $blabel = $opt->{blabel};
my $elabel = $opt->{elabel};
my $mlabel = '';
my $hidden_all = $opt->{hidden_all} ||= {};
#::logDebug("hidden_all=" . ::uneval($hidden_all));
my $ntext;
my $btext;
my $ctext;

if($pass_return_to) {
  delete $::Scratch->{$opt->{next_text}};
}
elsif (! $opt->{wizard} and ! $opt->{nosave}) {
  $ntext = $Tag->return_to('click', 1);
  $ctext = $ntext . "\nmv_todo=back";
}
else {
  if($opt->{action_click}) {
    $ntext = <<EOF;
mv_todo=$opt->{wizard_next}
ui_wizard_action=Next
mv_click=$opt->{action_click}
EOF
  }
  else {
    $ntext = <<EOF;
mv_todo=$opt->{wizard_next}
ui_wizard_action=Next
mv_click=ui_override_next
EOF
  }
  $::Scratch->{$opt->{next_text}} = $ntext;

  my $hidgo = $opt->{mv_cancelpage} || $opt->{hidden}{ui_return_to} || $CGI->{return_to};
  $hidgo =~ s/\0.*//s;
  $ctext = $::Scratch->{$opt->{cancel_text}} = <<EOF;
mv_form_profile=
ui_wizard_action=Cancel
mv_nextpage=$hidgo
mv_todo=$opt->{wizard_cancel}
EOF
  if($opt->{mv_prevpage}) {
    $btext = $::Scratch->{$opt->{back_text}} = <<EOF;
mv_form_profile=
ui_wizard_action=Back
mv_nextpage=$opt->{mv_prevpage}
mv_todo=$opt->{wizard_next}
EOF
  }
  else {
    delete $opt->{back_text};
  }
}

for(qw/next_text back_text cancel_text/) {
  $opt->{"orig_$_"} = $opt->{$_};
}

$::Scratch->{$opt->{next_text}}   = $ntext if $ntext;
$::Scratch->{$opt->{cancel_text}} = $ctext if $ctext;
$::Scratch->{$opt->{back_text}}   = $btext if $btext;

$opt->{next_text} = HTML::Entities::encode($opt->{next_text}, $ESCAPE_CHARS::std);
$opt->{back_text} = HTML::Entities::encode($opt->{back_text}, $ESCAPE_CHARS::std);
$opt->{cancel_text} = HTML::Entities::encode($opt->{cancel_text}, $ESCAPE_CHARS::std);

$::Scratch->{$opt->{next_text}}   = $ntext if $ntext;
$::Scratch->{$opt->{cancel_text}} = $ctext if $ctext;
$::Scratch->{$opt->{back_text}}   = $btext if $btext;

undef $opt->{auto_secure} if $opt->{cgi};

### Build the error checking
my $error_show_var = 1;
my $have_errors;
if($opt->{ui_profile} or $check) {
  $Tag->error( { all => 1 } )
    unless $CGI->{mv_form_profile} or $opt->{keep_errors};
  my $prof = $opt->{ui_profile} || "&update=yes\n";
  if ($prof =~ s/^\*//) {
    # special notation ui_profile="*whatever" means
    # use automatic checklist-related profile
    my $name = $prof;
    $prof = $::Scratch->{"profile_$name"} || "&update=yes\n";
    if ($prof) {
      $prof =~ s/^\s*(\w+)[\s=]+required\b/$1=mandatory/mg;
      for (grep /\S/, split /\n/, $prof) {
        if (/^\s*(\w+)\s*=(.+)$/) {
          my $k = $1; my $v = $2;
          $v =~ s/\s+$//;
          $v =~ s/^\s+//;
          $error->{$k} = 1;
          $error_show_var = 0 if $v =~ /\S /;
        }
      }
      $prof = '&calc delete $Values->{step_'
          . $name
          . "}; return 1\n"
          . $prof;
      ## Un-confuse vi }
      $opt->{ui_profile_success} = "&set=step_$name 1";
    }
  }
  my $success = $opt->{ui_profile_success};
  # make sure profile so far ends with a newline so we can add more
  $prof .= "\n" unless $prof =~ /\n\s*\z/;
  if(ref $check) {
    while ( my($k, $v) = each %$check ) {
      next unless length $v;
      $error->{$k} = 1;
      $v =~ s/\s+$//;
      $v =~ s/^\s+//;
      $v =~ s/\s+$//mg;
      $v =~ s/^\s+//mg;
      $v =~ s/^required\b/mandatory/mg;
      unless ($v =~ /^\&/m) {
        $error_show_var = 0 if $v =~ /\S /;
        $v =~ s/^/$k=/mg;
        $v =~ s/\n/\n&and\n/g;
      }
      $prof .= "$v\n";
    }
  }
  elsif ($check) {
    for (@_ = grep /\S/, split /[\s,]+/, $check) {
      $error->{$_} = 1;
      $prof .= "$_=mandatory\n";
    }
  }

  ## Enable individual widget checks
  $::Scratch->{mv_individual_profile} = 1;

  ## Call the profile in the form
  $opt->{hidden}{mv_form_profile} = 'ui_profile';
  my $fail = $opt->{mv_failpage} || $Global::Variable->{MV_PAGE};

  # watch out for early interpolation here!
  $::Scratch->{ui_profile} = <<EOF;
[perl]
#Debug("cancel='$opt->{orig_cancel_text}' back='$opt->{orig_back_text}' click=\$CGI->{mv_click}");
my \@clicks = split /\\0/, \$CGI->{mv_click};

for( qq{$opt->{orig_cancel_text}}, qq{$opt->{orig_back_text}}) {
#Debug("compare is '\$_'");
  next unless \$_;
  my \$cancel = \$_;
  for(\@clicks) {
#Debug("click is '\$_'");
    return if \$_ eq \$cancel; 
  }
}
# the following should already be interpolated by the table-editor tag
# before going into scratch ui_profile
return <<'EOP';
$prof
&fail=$fail
&fatal=1
$success
mv_form_profile=mandatory
&set=mv_todo $opt->{action}
EOP
[/perl]
EOF
  $opt->{blabel} = '<span style="font-weight: normal">';
  $opt->{elabel} = '</span>';
  $mlabel = ($opt->{message_label} || '&nbsp;&nbsp;&nbsp;'
. errmsg('<b>Bold</b> fields are required'));
  $have_errors = $Tag->error( {
                all => 1,
                show_var => $error_show_var,
                show_error => 1,
                joiner => "<br$Vend::Xtrailer>",
                keep => 1}
                );
  if($opt->{all_errors} and $have_errors) {
    my $title = $opt->{all_errors_title} || errmsg('Errors');
    my $style = $opt->{all_errors_style} || "color: $opt->{color_fail}";
    my %hash = (
      title => $opt->{all_errors_title} || errmsg('Errors'),
      style => $opt->{all_errors_style} || "color: $opt->{color_fail}",
      errors => $have_errors,
    );
    my $tpl = $opt->{all_errors_template} || <<EOF;
<p>{TITLE}:
<blockquote style="{STYLE}">{ERRORS}</blockquote>
</p>
EOF
    $mlabel .= tag_attr_list($tpl, \%hash, 'uc');

  }
}

AUTHORS

Interchange Development Group

SEE ALSO

DocBook! Interchange!