+<FONT SIZE="+1"><B>
+<% ( $opt{labels} && exists $opt{labels}->{$pkey} )
+ ? $opt{labels}->{$pkey}
+ : $pkey
+%>
+</B></FONT>
+#<% ( !$clone && $object->$pkey() ) || "(NEW)" %>
+
+% my $tablenum = 0;
+<TABLE ID="TableNumber<% $tablenum++ %>" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
+
+% my $g_row = 0;
+% my @g_row_stack = ();
+% foreach my $f ( map { ref($_) ? $_ : {'field'=>$_} }
+% @$fields
+% ) {
+%
+% my $trash = &{ $opt{'field_callback'} }( $cgi, $object, $f )
+% if $opt{'field_callback'};
+%
+% my $field = $f->{'field'};
+% my $type = $f->{'type'} ||= 'text';
+%
+% my $label = ( $opt{labels} && exists $opt{labels}->{$field} )
+% ? $opt{labels}->{$field}
+% : $field;
+%
+% my $onchange = $f->{'onchange'};
+%
+% my $layer_values = {};
+% $layer_values = &{ $f->{'layer_values_callback'} }( $cgi, $object )
+% if $f->{'layer_values_callback'}
+% && ! $f->{'m2name_table'}
+% && ! $f->{'o2m_table'}
+% && ! $f->{'m2m_method'};
+%
+% warn "layer values: ". Dumper($layer_values)
+% if $opt{'debug'};
+%
+% my %include_common = (
+%
+% #text and derivitives
+% 'size' => $f->{'size'},
+% 'maxlength' => $f->{'maxlength'},
+% 'postfix' => $f->{'postfix'},
+%
+% #textarea
+% 'rows' => $f->{'rows'},
+% 'cols' => $f->{'cols'},
+%
+% #checkbox, title, fixed, hidden
+% #& deprecated weird value hashref used only by reason.html
+% 'value' => $f->{'value'},
+%
+% #select(-*)
+% 'options' => $f->{'options'},
+% 'labels' => $f->{'labels'},
+% 'multiple' => $f->{'multiple'},
+% 'label_showkey' => $f->{'label_showkey'},
+% 'disable_empty' => $f->{'disable_empty'},
+% #select-reason
+% 'reason_class' => $f->{'reason_class'},
+%
+% #selectlayers
+% 'layer_fields' => $f->{'layer_fields'},
+% 'layer_values' => $layer_values,
+% 'html_between' => $f->{'html_between'},
+%
+% #umm. for select-agent_types at least
+% 'disabled' => $f->{'disabled'},
+%
+% #any?
+% 'colspan' => $f->{'colspan'},
+% 'required' => $f->{'required'},
+% );
+%
+% $include_common{$_} = $f->{$_} foreach grep exists($f->{$_}),
+% qw( js_only html_only select_only layers_only cell_style ),#selectlayers,?
+% qw( empty_label ), # select-*
+% qw( value_col ), # select-table
+% qw( table name_col ), #(select,checkboxes)-table
+% qw( target_table link_table ), #checkboxes-table
+% qw( hashref agent_virt agent_null agent_null_right ),#*-table
+% qw( formatted_value ), #fixed
+% qw( country ), #select-country
+% qw( width height ), #htmlarea
+% qw( alt_format ), #select-cust_location
+% ;
+%
+% #select-table
+% $include_common{$_} = ref( $f->{$_} ) eq 'CODE'
+% ? &{ $f->{$_} }( $cgi, $object ) #, $f )
+% : $f->{$_}
+% foreach grep exists($f->{$_}), qw( extra_sql );
+%
+% if ( $type eq 'tablebreak-tr-title' ) {
+% $include_common{'table_id'} = 'TableNumber'. $tablenum++;
+% }
+% if ( $type eq 'tablebreak-tr-title' || $type eq 'title' ) {
+% $include_common{'colspan'} = $f->{colspan} if $f->{colspan};
+% }
+%
+% if ( $f->{include_opt_callback} ) {
+% %include_common = ( %include_common,
+% &{ $f->{include_opt_callback} }( $object )
+% );
+% }
+%
+% my $layer_prefix_on = '';
+%
+% my $include_sub = sub {
+% my %opt = @_;
+%
+% my $fieldnum = delete $opt{'fieldnum'};
+%
+% my $include = $type;
+% $include = "input-$include" if $include =~ /^(text|money|percentage)$/;
+% $include = "tr-$include" unless $include =~ /^(hidden|tablebreak|column)/;
+%
+% $include_common{'layer_prefix'} = "$field$fieldnum."
+% if $layer_prefix_on;
+%
+% my @include =
+% ( "/elements/$include.html",
+% 'field' => "$field$fieldnum",
+% 'id' => "$field$fieldnum", #separate?
+% 'label_id' => $field."_label$fieldnum", #don't want field0_label0...
+% %include_common,
+% %opt,
+% );
+%
+% if ( $include eq 'tr-input-date-field' ) {
+% # it's either hacking it here, or changing a lot more stuff
+% @include = (
+% "/elements/$include.html", {
+% 'name' => $field,
+% 'value' => $opt{curr_value},
+% 'label' => $label,
+% 'noinit' => $f->{noinit},
+% }
+% );
+% }
+%
+% @include;
+% };
+%
+% my $column_sub = sub {
+% my %opt = @_;
+%
+% my $column = delete($opt{field});
+% my $fieldnum = delete($opt{fieldnum});
+% my $include = delete($opt{type}) || 'text';
+% $include = "input-$include" if $include =~ /^(text|money|percentage)$/;
+%
+% ( "/elements/$include.html",
+% 'field' => $field.'__'.$column.$fieldnum,
+% 'id' => $field.'__'.$column.$fieldnum,
+% 'layer_prefix' => $field.'__'.$column.$fieldnum.".",
+% ( $fieldnum
+% ? ('cell_style' => 'border-top:1px solid black')
+% : ()
+% ),
+% 'cgi' => $cgi,
+% %opt,
+% );
+% };
+%
+% unless ( $type =~ /^column/ ) {
+% $g_row = 1 if $type eq 'tablebreak-tr-title';
+% $g_row++;
+% $g_row++ if $type eq 'title';
+% $g_row += scalar( @{ $f->{options} } )-1 if $type eq 'radio';
+% } else {
+% if ( $type eq 'columnstart' ) {
+% push @g_row_stack, $g_row;
+% $g_row = 0;
+% #} elsif ( $type eq 'columnnext' ) {
+% } elsif ( $type eq 'columnend' ) {
+% $g_row = pop @g_row_stack;
+% }
+%
+% }
+%
+% my $fieldnum = '';
+% my $curr_value = '';
+% if ( $f->{'m2name_table'} || $f->{'o2m_table'} || $f->{'m2m_method'} ) {
+%
+% my($table, $col);
+% if ( $f->{'m2name_table'} ) {
+% $table = $f->{'m2name_table'};
+% $col = $f->{'m2name_namecol'};
+% } elsif ( $f->{'o2m_table'} ) {
+% $table = $f->{'o2m_table'};
+% $col = dbdef->table($f->{'o2m_table'})->primary_key;
+% } elsif ( $f->{'m2m_method'} ) {
+% $table = $f->{'m2m_method'};
+% $col = $f->{'m2m_dstcol'};
+% }
+% $fieldnum = 0;
+% $layer_prefix_on = 1;
+% #print out the fields for the existing m2s
+% my @existing = ();
+% if ( $mode eq 'error' ) {
+% @existing = &{ $f->{'m2_error_callback'} }( $cgi, $object );
+% } elsif ( $object->$pkey() ) { # $mode eq 'edit'||'clone'
+% @existing = $object->$table();
+% warn scalar(@existing). " from $object->$table: ". join('/', @existing)
+% if $opt{'debug'};
+% } elsif ( $f->{'m2_new_default'} ) { # && $mode eq 'new'
+% @existing = @{ $f->{'m2_new_default'} };
+% }
+% foreach my $name_obj ( @existing ) {
+%
+% my $ex_label = '<INPUT TYPE="button" VALUE="X" TITLE="Remove this '.
+% lc($f->{'m2_label'}).
+% qq(" onClick="remove_$field($fieldnum);").
+% ' STYLE="color:#ff0000;font-weight:bold;'.
+% 'padding-left:2px;padding-right:2px"'.
+% '> '. ($f->{'m2_label'} || $field ). ' ';
+%
+% if ( $f->{'layer_values_callback'} ) {
+% my %switches = ( 'mode' => $mode );
+% $layer_values =
+% &{ $f->{'layer_values_callback'} }( $cgi, $name_obj, \%switches );
+% }
+% warn "layer values: ". Dumper($layer_values)
+% if $opt{'debug'};
+%
+% my @existing = &{ $include_sub }(
+% 'label' => $ex_label,
+% 'fieldnum' => $fieldnum,
+% 'curr_value' => $name_obj->$col(),
+% 'onchange' => $onchange,
+% 'layer_values' => $layer_values,
+% 'cell_style' => ( $fieldnum ? 'border-top:1px solid black' : '' ),
+% );
+% $existing[0] =~ s(^/elements/tr-)(/elements/);
+% my @label = @existing;
+% $label[0] = '/elements/tr-td-label.html';
+
+ <% include( @label ) %>
+ <TD COLSPAN="<% $f->{'colspan'} || 1 %>">
+ <% include( @existing ) %>
+ </TD>
+
+% if ( $f->{'m2_fields'} ) {
+% foreach my $c ( @{ $f->{'m2_fields'} } ) {
+% my $column = $c->{field};
+% my @column = &{ $column_sub }( %$c,
+% 'fieldnum' => $fieldnum,
+% 'curr_value' => $name_obj->$column()
+% );
+
+ <TD id='<% $field %>__<% $column %>_label<% $fieldnum %>'
+ style='text-align:right;vertical-align:top;
+ border-top:1px solid black;padding-top:5px;'>
+ <% $c->{'label'} || '' %>
+ </TD>
+ <TD style='border-top:1px solid black;padding-top:3px;'>
+ <% include( @column ) %>
+ </TD>
+% }
+% }
+
+ </TR>
+
+% $fieldnum++;
+% $g_row++;
+% }
+% #$field .= $fieldnum;
+% $onchange .= "\nspawn_$field(what);";
+% } else {
+% if ( $f->{curr_value_callback} ) {
+% $curr_value = &{ $f->{curr_value_callback} }( $cgi, $object, $field ),
+% } else {
+% $curr_value = $object->$field();
+% }
+% $curr_value = &{ $opt{'value_callback'} }( $f->{'field'}, $curr_value )
+% if $opt{'value_callback'} && $mode ne 'error';
+% }
+%
+% my @include = &{ $include_sub }(
+% 'label' => $label,
+% 'fieldnum' => $fieldnum,
+% 'curr_value' => $curr_value,
+% 'object' => $object,
+% 'cgi' => $cgi,
+% 'onchange' => $onchange,
+% ( $fieldnum ? ('cell_style' => 'border-top:1px solid black') : () ),
+% );
+%
+% if ( $f->{'m2name_table'} || $f->{'o2m_table'} || $f->{'m2m_method'} ) {
+% $include[0] =~ s(^/elements/tr-)(/elements/);
+% my @label = @include;
+% $label[0] = '/elements/tr-td-label.html';
+
+ <% include( @label ) %>
+ <TD COLSPAN="<% $f->{'colspan'} || 1 %>">
+ <% include( @include ) %>
+ </TD>
+
+% if ( $f->{'m2_fields'} ) {
+% foreach my $c ( @{ $f->{'m2_fields'} } ) {
+% my $column = $c->{field};
+% my @column = &{ $column_sub }( %$c, 'fieldnum' => $fieldnum );
+
+ <TD id='<% $field %>__<% $column %>_label<% $fieldnum %>'
+ style='text-align:right;vertical-align:top;
+ border-top:1px solid black;padding-top:5px;'>
+ <% $c->{'label'} || '' %>
+ </TD>
+ <TD style='border-top:1px solid black;padding-top:3px;'>
+ <% include( @column ) %>
+ </TD>
+% }
+% }
+
+ </TR>
+
+% } else {
+
+ <% include( @include ) %>
+
+% }
+% if ( $f->{'m2name_table'} || $f->{'o2m_table'} || $f->{'m2m_method'} ) {
+
+ <SCRIPT TYPE="text/javascript">
+
+ var <%$field%>_rownum = <% $g_row %>;
+ var <%$field%>_fieldnum = <% $fieldnum %>;
+
+ function spawn_<%$field%>(what) {
+
+ // only spawn if we're the last element... return if not
+
+ var field_regex = /(\d+)(_[a-z_]+)?$/;
+ var match = field_regex.exec(what.name);
+ if ( !match ) {
+ alert(what.name + " didn't match for " + what);
+ return;
+ }
+ if ( match[1] != <%$field%>_fieldnum ) {
+ return;
+ }
+
+ // change the label on the last entry & add a remove button
+ var prev_label = document.getElementById('<% $field %>_label' + <%$field%>_fieldnum );
+ prev_label.innerHTML = '<INPUT TYPE="button" VALUE="X" TITLE="Remove this <% lc($f->{'m2_label'}) %>" onClick="remove_<% $field %>(' + <%$field%>_fieldnum + ');" STYLE="color:#ff0000;font-weight:bold;padding-left:2px;padding-right:2px" > <% $f->{'m2_label'} || $field %>';
+
+ <%$field%>_fieldnum++;
+
+ //get the new widget
+
+% $include[0] =~ s(^/elements/tr-)(/elements/);
+% my @layer_opt = ( @include,
+% 'field' => $field."MAGIC_NUMBER",
+% 'id' => $field."MAGIC_NUMBER",
+% 'layer_prefix' => $field."MAGIC_NUMBER.",
+% );
+% warn @layer_opt if $opt{'debug'};
+
+ var newrow = <% include(@layer_opt, html_only=>1) |js_string %>;
+
+% #until the rest have html/js_only
+% if ( $type eq 'selectlayers' || $type =~ /^select-cgp_rule_/ ) {
+ var newfunc = <% include(@layer_opt, js_only=>1) |js_string %>;
+% } else {
+ var newfunc = '';
+% }
+
+ // substitute in the new field name
+ var magic_regex = /MAGIC_NUMBER/g;
+ newrow = newrow.replace( magic_regex, <%$field%>_fieldnum );
+ newfunc = newfunc.replace( magic_regex, <%$field%>_fieldnum );
+
+ // evaluate new_func
+ if (window.ActiveXObject) {
+ window.execScript(newfunc);
+ } else { /* (window.XMLHttpRequest) */
+ //window.eval(newfunc);
+ setTimeout(newfunc, 0);
+ }
+
+ // add new row
+
+ //hmm, can't use selectlayers after a tablebreak-title for now
+ var table = document.getElementById('TableNumber<% $tablenum-1 %>');
+
+ var row = table.insertRow(<%$field%>_rownum++);