[interchange-cvs] interchange - heins modified 14 files

interchange-core@icdevgroup.org interchange-core@icdevgroup.org
Wed Nov 20 13:53:00 2002


User:      heins
Date:      2002-11-20 18:52:17 GMT
Modified:  .        MANIFEST
Modified:  code/UI_Tag auto_wizard.coretag
Modified:  dist/foundation/pages customerservice.html index.html
Modified:  dist/lib/UI/pages/admin flex_select.html item_edit.html
Modified:  dist/lib/UI/pages/include/menus Admin.txt
Modified:  lib/Vend/Table Editor.pm
Modified:  scripts  interchange.PL update.PL
Added:     dist/foundation/pages/survey standard.html
Added:     dist/lib/UI/pages/admin/survey index.html overall.html
Added:              question.html
Log:
* Add general purpose survey and mailed-form creator for the UI.
  Puts a customer satisfaction survey in the foundation -- probably
  should provide a mailed feedback example, too.

* Make outdated bin/update command work better. Probably should remove this
  script, though.

* Bring "edit items in sequence" into the Vend::Table::Editor intrinsically.
  No need now to do the munging of item_id_left on the select page, but
  still compatible with that (to ease problems for users who have done
  custom select pages).

* Add intro_text option for the table editor so that the first page
  of a wizard can have some stuff.

* Revamp auto-wizard to work with the survey table's mv_metadata structure.
  Provides several standard output options for wizards. (online help
  is in process).

Revision  Changes    Path
2.72      +10 -0     interchange/MANIFEST


rev 2.72, prev_rev 2.71
Index: MANIFEST
===================================================================
RCS file: /var/cvs/interchange/MANIFEST,v
retrieving revision 2.71
retrieving revision 2.72
diff -u -r2.71 -r2.72
--- MANIFEST	7 Nov 2002 19:15:54 -0000	2.71
+++ MANIFEST	20 Nov 2002 18:52:16 -0000	2.72
@@ -148,6 +148,7 @@
 code/UI_Tag/list_glob.coretag
 code/UI_Tag/list_keys.coretag
 code/UI_Tag/list_pages.coretag
+code/UI_Tag/menu_load.coretag
 code/UI_Tag/meta_record.coretag
 code/UI_Tag/mm_locale.coretag
 code/UI_Tag/mm_value.coretag
@@ -282,6 +283,7 @@
 dist/foundation/dbconf/default_db/pricing.dbm
 dist/foundation/dbconf/default_db/products.dbm
 dist/foundation/dbconf/default_db/state.dbm
+dist/foundation/dbconf/default_db/survey.dbm
 dist/foundation/dbconf/default_db/transactions.dbm
 dist/foundation/dbconf/default_db/tree.dbm
 dist/foundation/dbconf/default_db/userdb.dbm
@@ -308,6 +310,7 @@
 dist/foundation/dbconf/mysql/pricing.mysql
 dist/foundation/dbconf/mysql/products.mysql
 dist/foundation/dbconf/mysql/state.mysql
+dist/foundation/dbconf/mysql/survey.dbm
 dist/foundation/dbconf/mysql/transactions.mysql
 dist/foundation/dbconf/mysql/tree.mysql
 dist/foundation/dbconf/mysql/userdb.mysql
@@ -333,6 +336,7 @@
 dist/foundation/dbconf/oracle/pricing.ora
 dist/foundation/dbconf/oracle/products.ora
 dist/foundation/dbconf/oracle/state.ora
+dist/foundation/dbconf/oracle/survey.dbm
 dist/foundation/dbconf/oracle/transactions.ora
 dist/foundation/dbconf/oracle/tree.ora
 dist/foundation/dbconf/oracle/userdb.ora
@@ -359,6 +363,7 @@
 dist/foundation/dbconf/pgsql/pricing.pgsql
 dist/foundation/dbconf/pgsql/products.pgsql
 dist/foundation/dbconf/pgsql/state.pgsql
+dist/foundation/dbconf/pgsql/survey.dbm
 dist/foundation/dbconf/pgsql/transactions.pgsql
 dist/foundation/dbconf/pgsql/tree.pgsql
 dist/foundation/dbconf/pgsql/userdb.pgsql
@@ -625,6 +630,7 @@
 dist/foundation/pages/splash.html
 dist/foundation/pages/stock-alert-added.html
 dist/foundation/pages/stock-alert.html
+dist/foundation/pages/survey/standard.html
 dist/foundation/pages/swap_results.html
 dist/foundation/products/2ndDayAir.csv
 dist/foundation/products/450.csv
@@ -653,6 +659,7 @@
 dist/foundation/products/salestax.asc
 dist/foundation/products/shipping.asc
 dist/foundation/products/state.txt
+dist/foundation/products/survey.txt
 dist/foundation/products/transactions.txt
 dist/foundation/products/tree.txt
 dist/foundation/products/userdb.txt
@@ -1023,6 +1030,9 @@
 dist/lib/UI/pages/admin/special/key_violation.html
 dist/lib/UI/pages/admin/spread.html
 dist/lib/UI/pages/admin/spread_control.html
+dist/lib/UI/pages/admin/survey/index.html
+dist/lib/UI/pages/admin/survey/overall.html
+dist/lib/UI/pages/admin/survey/question.html
 dist/lib/UI/pages/admin/tablereport.html
 dist/lib/UI/pages/admin/tax.html
 dist/lib/UI/pages/admin/tax_simple.html



1.7       +495 -79   interchange/code/UI_Tag/auto_wizard.coretag


rev 1.7, prev_rev 1.6
Index: auto_wizard.coretag
===================================================================
RCS file: /var/cvs/interchange/code/UI_Tag/auto_wizard.coretag,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- auto_wizard.coretag	14 Nov 2002 17:13:35 -0000	1.6
+++ auto_wizard.coretag	20 Nov 2002 18:52:16 -0000	1.7
@@ -1,9 +1,403 @@
 UserTag  auto-wizard  Order  name
 UserTag  auto-wizard  AddAttr
 UserTag  auto-wizard  HasEndTag
+UserTag  auto-wizard  Version  $Version$
 UserTag  auto-wizard  Routine <<EOR
 
 use vars qw/$Session $Tag $CGI $Tmp $Scratch $Values $ready_safe/;
+	
+my @wanted_opts = qw/
+	already_message
+	already_title
+	bottom_buttons
+	break_row_class
+	combo_row_class
+	data_cell_class
+	data_row_class
+	display_type
+	help_cell_class
+	intro_text
+	label_cell_class
+	left_width
+	output_type
+	spacer_row_class
+	table_width
+	thanks_message
+	thanks_title
+	top_buttons
+	widget_cell_class
+/;
+
+my %overall_opt;
+@overall_opt{@wanted_opts} = @wanted_opts;
+
+sub thanks_title {
+	my ($opt, $already, $default) = @_;
+	my $tt = $already
+			?  ($opt->{already_title} ||= "You already did that survey!" )
+			:  ($opt->{thanks_title} ||= $default || "Thanks for completing the survey!");
+	return errmsg($tt);
+}
+
+sub thanks_message {
+	my ($opt, $already) = @_;
+	my $tm;
+	if($already) {
+		$opt->{already_message} ||=
+			"We only want to collect information once from each person. Thank you.";
+		$tm = $opt->{already_message};
+	}
+	else {
+		$opt->{thanks_message} ||= "Your survey is complete. Thank you.";
+		$tm = $opt->{thanks_message};
+	}
+	return errmsg($tm);
+	$opt->{intro_text} .= "<h1>$tm</h1>" if $already;
+}
+
+sub title_and_message {
+	my ($opt, $already) = @_;
+	my $tt = thanks_title($opt, $already);
+	my $tm = thanks_message($opt, $already);
+	return (
+				'',
+				"final: $tt",
+				'template: <<EOF',
+				$tm,
+				'EOF',
+			);
+}
+
+sub already {
+	my ($wizname, $set) = @_;
+	my $surv = $Vend::Session->{surveys} ||= {};
+	if(defined $set) {
+		$surv->{$wizname} = $set;
+	}
+
+	if ($Vend::Session->{logged_in}) {
+		if (! defined $surv->{$wizname}) {
+			my $o = {
+				function => 'check_file_acl',
+				location => "survey/$wizname",
+			};
+			$surv->{$wizname} = $Tag->userdb($o);
+		}
+		else {
+			my $o = {
+				function => 'set_file_acl',
+				location => "survey/$wizname",
+				mode => $surv->{$wizname},
+			};
+			$Tag->userdb($o);
+		}
+	}
+
+	return $surv->{$wizname};
+}
+
+sub survey_log_generate_final {
+	my ($wizname, $opt, $ary) = @_;
+
+	ref($opt) eq 'HASH'
+		or die "bad call to generate_final routine, output options not hash ref ($opt)";
+	ref($ary) eq 'ARRAY'
+		or die "bad call to generate_final routine, output not array ref ($ary)";
+
+	my $done = already($wizname);
+
+	push @$ary, title_and_message($opt, $done);
+
+	if ( $done ) {
+		$opt->{intro_text} .= '<h1>' . thanks_title($opt, 1) . '</h1>';
+	}
+#	else {
+#		$opt->{survey_counter}	||= "logs/survey/$wizname.cnt";
+#		$opt->{survey_file}		||= "logs/survey/$wizname.txt";
+#		push @$ary, "\tsurvey_file: $opt->{survey_file}";
+#		push @$ary, "\tsurvey_counter: $opt->{survey_counter}";
+#	}
+	return;
+}
+
+sub gen_email_header {
+	my ($wizname, $ref, $opt, $fnames) = @_;
+	my $subject = errmsg($opt->{email_subject} || "Reponse to %s", $wizname);
+	my $from_addr = $opt->{email_from};
+	my $cc_addr = $opt->{email_cc};
+	for(qw/ EMAIL_SURVEY EMAIL_INFO EMAIL_SERVICE /) {
+		next unless $from_addr = $::Variable->{$_};
+		last;
+	}
+	$from_addr ||= $Vend::Cfg->{MailOrderFrom} || $Vend::Cfg->{MailOrderTo};
+	my $tpl = <<EOF;
+From: $from_addr
+Subject: $subject
+To: {output_email}
+EOF
+	$tpl .= "Cc: $cc_addr\n" if $cc_addr;
+	return $tpl;
+}
+
+sub gen_email_template {
+	my ($wizname, $ref, $opt, $fnames) = @_;
+	my $tpl = gen_email_header($wizname, $ref, $opt, $fnames);
+	$tpl .= <<EOF;
+
+{code?}Sequence: {code}
+{/code?}Username: {username}
+IP Address: $CGI::remote_addr
+Host: $CGI::remote_host
+Date: {date}
+--------------------------------------------
+EOF
+
+	my @fields = grep /\S/, split /\s+/, $opt->{output_fields};
+	if(! @fields) {
+		@fields = @$fnames;
+	}
+
+	for(@fields) {
+		$tpl .= "$_: {$_}\n";
+	}
+	$tpl .= "--------------------------------------------\n";
+	return $tpl;
+}
+
+sub email_output {
+	my ($wizname, $ref, $opt, $fnames) = @_;
+#::logDebug("Called email_output");
+	return unless  $opt->{output_email};
+
+#::logDebug("email_output has an address of $opt->{output_email}");
+	## Check and see if already sent
+	if(! $opt->{output_repeated} and already($wizname)) {
+#::logDebug("email_output already done, repeated=$opt->{output_repeated} already=" . ::uneval($Vend::Session->{surveys}));
+		return;
+	}
+
+#::logDebug("email_output is continuing");
+	my $tpl	 = $opt->{email_template};
+	if(! $tpl or $tpl !~ /\S/) {
+		$tpl = gen_email_template($wizname, $ref, $opt, $fnames);
+	}
+	else {
+		$opt->{email_template} =~ s/\s+$//;
+		$opt->{email_template} =~ s/^\s+//;
+		if($opt->{email_template} !~ /[\r\n]/) {
+			$tpl = interpolate_html(Vend::Util::readfile($opt->{email_template}));
+		}
+		else {
+			$tpl = $opt->{email_template};
+		}
+		if($tpl !~ /^[-\w]+:/) {
+			$tpl = join "\n", gen_email_header($wizname, $ref, $opt, $fnames), $tpl;
+		}
+	}
+
+#::logDebug("email_output tpl=$tpl");
+
+	my @fields = grep /\S/, split /\s+/, $opt->{output_fields};
+	if(! @fields) {
+		@fields = @$fnames;
+	}
+	
+	my $outref = { %$opt };
+
+	$outref->{ip_address} = $CGI::remote_addr;
+	$outref->{host_name} = $CGI::remote_host;
+	$outref->{username} = $Vend::username || 'anonymous';
+	$outref->{date} = POSIX::strftime("%Y-%m-%d %H:%M:%S", localtime());
+
+	for(@fields) {
+		$outref->{$_} = $Values->{$_};
+	}
+	my $out = tag_attr_list($tpl, $outref);
+
+	my $status;
+	$status = $Tag->email_raw({}, $out)
+		or ::logError("Failed to send survey email output:\n$out");
+#::logDebug("email_output status=$status");
+	return $status;
+}
+
+sub survey_log_to_file {
+	my ($wizname, $ref, $opt, $fnames) = @_;
+
+	if(! $opt->{output_repeated} and already($wizname)) {
+		return template_attr($wizname, $ref, $opt, $fnames);
+	}
+
+	my $fn	 = $ref->{survey_file};
+	my $cfn  = $ref->{survey_counter};
+	my $sqlc = $ref->{survey_counter_sql};
+
+	if(! $fn) {
+		$fn = $::Variable->{SURVEY_LOG_DIR} || 'logs/survey';
+		$fn .= "/$wizname.txt";
+	}
+
+	if(! $cfn and ! $sqlc) {
+		$cfn = $fn;
+		$cfn =~ s/\.txt$//;
+		$cfn .= '.cnt';
+		$cfn =~ s:(.*/):$1.:;
+	}
+
+	my @fields = grep /\S/, split /\s+/, $opt->{output_fields};
+	if(! @fields) {
+		@fields = @$fnames;
+	}
+	if(! -f $fn) {
+		my $string = join "\t",
+						'code', 'ip_address', 'username', 'date', @fields;
+		$string .= "\n";
+		$Tag->write_relative_file($fn, $string);
+	}
+
+	my @o = $Tag->counter({file => $cfn, sql => $sqlc});
+	push @o, $CGI::remote_addr;
+	push @o, $Vend::username || 'anonymous';
+	push @o, POSIX::strftime("%Y-%m-%d %H:%M:%S", localtime());
+
+	for(@fields) {
+		my $result = $Values->{$_};
+		$result =~ s/\r?\n/\r/g;
+		$result =~ s/\t/  /g;
+		push @o, $result;
+	}
+
+	::logData($fn, @o);
+	email_output($wizname, $ref, $opt, $fnames);
+	already($wizname => 1);
+	return template_attr($wizname, $ref, $opt, $fnames);
+}
+
+my %survey_genfinal = (
+	survey_log => \&survey_log_generate_final,
+	email_only => sub {
+		my ($wizname, $opt, $ary) = @_;
+		push @$ary, title_and_message($opt, already($wizname));
+		if($opt->{continue_template}) {
+			push @$ary, "template: <<EOF";
+			push @$ary, $opt->{continue_template};
+			push @$ary, 'EOF';
+		}
+		return;
+	},
+	default => sub {
+		my ($wizname, $opt, $ary) = @_;
+		my $line = "final: ";
+		$line .= thanks_title(
+						$opt,
+						$Vend::Session->{surveys}{$wizname},
+						errmsg("Finished with %s", $wizname),
+					);
+		push @$ary, '';
+		push @$ary, $line;
+		if($opt->{continue_template}) {
+			push @$ary, "template: <<EOF";
+			push @$ary, $opt->{continue_template};
+			push @$ary, 'EOF';
+		}
+		return;
+	},
+);
+
+sub template_attr {
+	my ($wizname, $ref, $opt, $fields) = @_; 
+	my %attr;
+
+	if(ref($fields) eq 'hash') {
+		%attr = { %$fields };
+	}
+
+	$attr{TITLE} = $ref->{_page_title} || "Finished with $wizname...";
+	$attr{PROMPT} = $ref->{prompt};
+	$attr{ANCHOR} = $ref->{anchor} || 'Go';
+	$attr{EXTRA} = $ref->{extra} || '';
+	$attr{EXTRA} = " $attr{EXTRA}" if $attr{EXTRA};
+	$attr{URL} = wizard_url($ref, $opt, $fields);
+#::logDebug("generated ATTR is: " . uneval(\%attr));
+	my $template = $ref->{template} || <<EOF;
+<H1>{TITLE}</h1>
+{PROMPT}
+<p>
+<blockquote>
+<A HREF="{URL}"{EXTRA}>{ANCHOR}</A>
+</blockquote>
+EOF
+	return tag_attr_list($template, \%attr);
+}
+
+sub wizard_url {
+	my ($ref, $opt, $fields) = @_; 
+	my %attr;
+	my %ignore = qw/
+					page 
+					href
+					template
+					remap
+					/;
+				
+	my $form = { };
+	for(keys %$ref) {
+		next if /^_/;
+		next if $ignore{$_};
+		$form->{$_} = $ref->{$_};
+	}
+
+	$form->{href} = $opt->{output_href} || $ref->{href} || $ref->{page};
+	$form->{form} = 'auto';
+	for(@$fields) {
+		$form->{$_} = $Values->{$_};
+	}
+
+	my $save = { };
+	if($ref->{remap}) {
+		my @pairs = split /[\s,\0]+/, $ref->{remap};
+		for(@pairs) {
+			my ($k, $v) = split /=/, $_;
+			next unless $k and $v;
+			my $val = delete($form->{$k}) || $save->{$k};
+			$save->{$k} = $val;
+			$form->{$v} = $val;
+		}
+	}
+
+	return $Tag->area($form);
+}
+
+my %survey_auto = qw/
+						survey_log   1
+						email_only   1
+						auto_bounce  1
+					/;
+## Called with:
+##
+##	$$dest = $sub->($wizname, $ref, $opt, \@vals);
+##
+##	 $wizname name of wizard/survey
+##	 $ref     copy of final stanza of auto_wizard, hash ref with keys, can modify
+##	 %opts    Options auto_wizard was created with, can modify
+##	 @vals    Fields names collected in the wizard, can modify
+
+my %survey_action = (
+	survey_log => \&survey_log_to_file,
+	auto_bounce => sub {
+		my ($wizname, $ref, $opt, $fnames) = @_;
+		my $url = wizard_url($ref, $opt, $fnames);
+		email_output($wizname, $ref, $opt, $fnames);
+		my $status = $Tag->deliver( { type => 'text/html', location => $url });
+		return $status;
+	},
+	default => sub {
+		my ($wizname, $ref, $opt, $fnames) = @_;
+		$ref->{wizard_name} = $wizname;
+		email_output($wizname, $ref, $opt, $fnames);
+		return template_attr($wizname, $ref, $opt, $fnames);
+	},
+);
 
 sub compile_wizard {
 	my ($wizname, $opt, $script) = @_;
@@ -27,8 +421,51 @@
 	my $vip;
 	my $mark;
 	my $break;
+	my %opts;
+
+	if($opt->{db_id}) {
+#Debug("found db_id=$opt->{db_id}");
+		my ($t, $k) = split /:+/, $opt->{db_id}, 2;
+		BUILDWIZ: {
+			my $met = $Tag->meta_record($k, undef, $t)
+				or last BUILDWIZ;
+			my($structure) = delete $met->{ui_data_fields};
+			%opts = %$met;
+#Debug("display type=$opts{display_type} met=" . ::uneval($met) );
+			$met->{row_template} = $opt->{row_template}
+				if $opt->{row_template};
+			my $ids = $t . '::' . $k . '::';
+			$structure =~ s/\r\n?/\n/g;
+			my $string = "\n\n$structure";
+			my %break;
+			while ($string =~ s/\n+(?:\n[ \t]*=(.*))?\n+[ \t]*(\w[:.\w]+)/\n$2/) {
+				$break{$2} = $1;
+			}
+			$string =~ s/^[\s,\0]+//;
+			$string =~ s/[\s,\0]+$//;
+			$string =~ s/[,\0\s]+/ /g;
+			my @fields = split /\s+/, $string;
+			my @out = "$k: $met->{label}";
+			my $i = 1;
+			my $fields_line = join "\t", @fields;
+			for(@fields) {
+				if($break{$_}) {
+					push @out, "$i: $break{$_}";
+					$i++;
+				}
+				push @out, "\tdb_id: $ids$_";
+				push @out, '';
+			}
+			$opts{output_fields} ||= join " ", @fields;
+			my $otype = $opts{output_type} || 'default';
+			my $sub = $survey_genfinal{$otype} || $survey_genfinal{default};
+			$sub->($k, \%opts, \@out);
+			@lines = @out;
+		}
+	}
 
 #Debug("Found some lines, number=" . scalar @lines);
+#Debug("display type=$opts{display_type}");
 	for(@lines) {
 		if($mark) {
 			$sip .= "$_\n", next
@@ -56,7 +493,12 @@
 				$began = 1;
 				$wizname ||= $1;
 				my $title = $2;
-				$ref = { _page_name => 'begin', _name => [], title => $title };
+				$ref = {
+						_page_name => 'begin',
+						_name => [],
+						title => $title,
+						%opts,
+					};
 			}
 			next;
 		}
@@ -68,7 +510,8 @@
 			$qip = [];
 			undef $bip;
 			undef $blip;
-			$ref = {	_page_name		=> $pn,
+			$ref = {	
+						_page_name		=> $pn,
 						_name			=> $qip,
 						_breaks			=> $bip,
 						_break_labels	=> $blip,
@@ -203,12 +646,24 @@
 sub {
 	my ($wizname, $opt, $body) = @_;
 
-	return $Tmp->{auto_wizard} if $opt->{show} and ! $opt->{run};
+	my $dest;
+	$wizname ||= $CGI->{wizard_name};
+
+	if($opt->{scratch}) {
+		$Tag->tmp($opt->{scratch});
+		$::Scratch->{$opt->{scratch}} ||= '';
+		$dest = \$::Scratch->{$opt->{scratch}};
+	}
+	else {
+		$Tmp->{auto_wizard} ||= '';
+		$dest = \$Tmp->{auto_wizard};
+	}
+	return $$dest if $opt->{show} and ! $opt->{run};
 
 	if($opt->{compile} eq 'auto') {
 		$Session->{auto_wizard} ||= {};
 		undef $opt->{compile} if $wizname && $Session->{auto_wizard}{$wizname};
-		$opt->{show} = 1;
+		$opt->{show} = 1 unless defined $opt->{show};
 		$opt->{run} = 1;
 	}
 
@@ -217,7 +672,7 @@
 		$n = compile_wizard(@_)
 			or do {
 				::logError(
-					$Tmp->{auto_wizard} = errmsg(
+					$$dest = errmsg(
 											"Wizard %s failed to compile.",
 											$wizname,
 										)
@@ -248,7 +703,7 @@
 	my $fin = $wiz->[-1];
 
 	for($beg, $fin) {
-		die "Bad wizard!" unless ref($_) eq 'HASH';
+		return "Bad wizard!" unless ref($_) eq 'HASH';
 	}
 
 	my $lastwiz = $#$wiz;
@@ -264,7 +719,6 @@
 		delete $opts{$_};
 	}
 
-
 	if($CGI->{ui_wizard_action} eq 'Back') {
 		$current_page = $lastpage - 1;
 	}
@@ -319,7 +773,7 @@
 		}
 		elsif ( ($current_page + 1) == $lastwiz ) {
 			$opts{next_text} = errmsg('Finish')
-				if $fin->{auto};
+				if $survey_auto{$opts{output_type}} or $fin->{auto};
 		}
 		elsif ($current_page >= $lastwiz) {
 			$finished = 1;
@@ -327,7 +781,10 @@
 		$optref = $wiz->[$current_page];
 	}
 	
-	my %attr;
+	unless($current_page <= 1) {
+		delete $opts{intro_text};
+		delete $optref->{intro_text};
+	}
 
 	my %modsub = (
 			i		=> sub {
@@ -342,78 +799,38 @@
 						},
 		);
 
-	$attr{TITLE}  = $Scratch->{$title_var}  = $optref->{_page_title};
-	$attr{BANNER} = $Scratch->{$banner_var} = $optref->{_page_title};
+	$Scratch->{$title_var}  = $optref->{_page_title};
+	$Scratch->{$banner_var} = $optref->{_page_title};
 
 	if($finished) {
 			my $ref = { %$fin };
+
+			my $mod;
+			if( $mod = delete $ref->{_modifier}) {
+				for(keys %$ref) {
+					next if /^_/;
+					if(my $m = $mod->{$_}) {
+						my $v = $ref->{$_};
+						my $sub = $modsub{$m} || $modsub{default};
+						$ref->{$_} = $sub->($ref->{$_}, $m);
+					}
+				}
+			}
+
 			my @vals;
 			for my $w (@$wiz) {
 				next unless ref($w->{_name}) eq 'ARRAY';
 				push @vals, @{$w->{_name}};
 			}
-#Debug("finished, page ref=" . uneval($ref));
-			$ref->{href} ||= delete $ref->{page};
-			$attr{TITLE} = $Scratch->{$title_var}
-				= $ref->{_page_title} || "Finished with $wizname...";
-			$attr{PROMPT} = delete $ref->{prompt} || '';
-			$attr{ANCHOR} = delete $ref->{anchor} || 'Go';
-			$attr{EXTRA} = delete $ref->{extra} || '';
-			my $remap = delete $ref->{remap};
-			my $template = delete $ref->{template};
-			$attr{EXTRA} = " $attr{EXTRA}" if $attr{EXTRA};
-			my $auto = delete $ref->{auto};
-
-			my $mod = $ref->{_modifier} || '';
-			for(keys %$ref) {
-				next if /^_/;
-				my $m;
-				if($mod and $m = $mod->{$_}) {
-					my $v = $ref->{$_};
-					my $sub = $modsub{$m} || $modsub{default};
-					$ref->{$_} = $sub->($ref->{$_}, $m);
-				}
-			}
-
-			for(keys %$ref) {
-				next unless /^_/;
-				delete $ref->{$_};
-			}
-
-			$ref->{form} = 'auto';
-			for(@vals) {
-				$ref->{$_} = $Values->{$_};
-			}
-
-			my $save = {};
-			if($remap) {
-				my @pairs = split /[\s,\0]+/, $remap;
-				for(@pairs) {
-					my ($k, $v) = split /=/, $_;
-					next unless $k and $v;
-					my $val = delete($ref->{$k}) || $save->{$k};
-					$save->{$k} = $val;
-					$ref->{$v} = $val;
-				}
-			}
 
-			$attr{URL} = $Tag->area($ref);
-
-			if($auto) {
-				$opt->{reparse} = 1;
-				return '[bounce href="' . $attr{URL} . '"]';
-			}
-			$template ||= <<'EOF';
-<H1>{TITLE}</h1>
-{PROMPT}
-<p>
-<blockquote>
-<A HREF="{URL}"{EXTRA}>{ANCHOR}</A>
-</blockquote>
-EOF
-			$Tmp->{auto_wizard} = $Tag->attr_list( { hash => \%attr }, $template);
-			return $Tmp->{auto_wizard} if $opt->{show};
+			my $otype = $opts{output_type};
+			$otype ||= 'auto_bounce' if $ref->{auto};
+			my $sub = $survey_action{$otype} || $survey_action{default};
+			$$dest = $sub->($wizname, $ref, \%opts, \@vals);
+			return $$dest if $opt->{show};
 			return;
+#Debug("finished, page ref=" . uneval($ref));
+
 	}
 
 #Debug("we have a wiz=$wizname! current_page = $current_page");
@@ -438,7 +855,7 @@
 	$opts{no_meta} = 1;
 	$opts{defaults} = 1;
 	$opts{mv_cancelpage} ||= 'admin/index';
-	$opts{row_template} ||= <<'EOF';
+	$opts{row_template} ||= <<'EOF' unless $opts{display_type};
 {HELP?}<td>&nbsp;</td><td>
      <span style="color: blue">{HELP}</span>
 	 {HELP_URL?}<BR><A HREF="{HELP_URL}">more help</A>{/HELP_URL?}
@@ -465,9 +882,9 @@
 	my $mod = $optref->{_modifier} || '';
 	for(keys %$optref) {
 		next if /^_/;
+		next if $overall_opt{$_};
 		next unless ref($optref->{$_}) eq 'HASH';
-		$opts{$_} ||= {};
-		next unless ref($opts{$_}) eq 'HASH';
+		$opts{$_} = {} if ref($opts{$_}) ne 'HASH';
 		Vend::Util::copyref($optref->{$_}, $opts{$_});
 		my $m;
 		if($mod and $m = $mod->{$_}) {
@@ -492,14 +909,13 @@
 
 	delete $opts{type};
 #::logDebug("calling table_editor opts=" . ::uneval(\%opts));
-	$Tmp->{auto_wizard} = $Tag->table_editor( {all_opts => \%opts });
-	if($Tmp->{auto_wizard} !~ /<form\s+/i) {
-		$attr{auto_wizard} .= "\n";
+	$$dest = $Tag->table_editor( {all_opts => \%opts });
+	if($$dest !~ /<form\s+/i) {
 		my $msg = errmsg("Auto wizard failed to run wizard %s.", $name);
-		$Tmp->{auto_wizard} .= $Tag->error({ show => 1, set => $msg });
+		$$dest .= $Tag->error({ show => 1, set => $msg });
 	}
 
-	return $Tmp->{auto_wizard} if $opt->{show};
+	return $$dest if $opt->{show};
 	return;
 }
 EOR



2.1       +7 -0      interchange/dist/foundation/pages/customerservice.html


rev 2.1, prev_rev 2.0
Index: customerservice.html
===================================================================
RCS file: /var/cvs/interchange/dist/foundation/pages/customerservice.html,v
retrieving revision 2.0
retrieving revision 2.1
diff -u -r2.0 -r2.1
--- customerservice.html	18 Jul 2001 02:21:14 -0000	2.0
+++ customerservice.html	20 Nov 2002 18:52:17 -0000	2.1
@@ -43,6 +43,13 @@
 
     Below are our automated customer service options.
     If you need to talk to someone please [page contact]click here</a>.
+	<p>
+	We would also like you to take our
+		[page
+			href=survey/standard
+			form="survey_start=customer_satisfaction"
+		]Customer Satisfaction Survey</A>.
+	</p>
 
     <br><br>
 



2.1       +10 -0     interchange/dist/foundation/pages/index.html


rev 2.1, prev_rev 2.0
Index: index.html
===================================================================
RCS file: /var/cvs/interchange/dist/foundation/pages/index.html,v
retrieving revision 2.0
retrieving revision 2.1
diff -u -r2.0 -r2.1
--- index.html	18 Jul 2001 02:21:14 -0000	2.0
+++ index.html	20 Nov 2002 18:52:17 -0000	2.1
@@ -54,6 +54,16 @@
     <br><br>
   </td>
 </tr>
+<tr> 
+  <td>
+    <br>
+    Take our 
+		[page
+			href=survey/standard
+			form="survey_start=customer_satisfaction"
+		]Customer Satisfaction Survey</A>.
+  </td>
+</tr>
 </table>
 
 <!-- END CONTENT -->



1.1                  interchange/dist/foundation/pages/survey/standard.html


rev 1.1, prev_rev 1.0
Index: standard.html
===================================================================
[comment]
ui_template: Yes
ui_template_name: noleft
[/comment]

<style type="text/css">
.cerror {
	color: red
}
</style>

[if cgi survey_start]
	[calc]
		delete $Session->{auto_wizard}{$CGI->{survey_start}};
		return;
	[/calc]
	[tmp survey_id]survey::[cgi survey_start][/tmp]
[/if]


[control reset=1]

[control reset=1]

[auto-wizard
	compile=auto
	show=0
	scratch=survey_output
	interpolate=1
	db_id="[scratch survey_id]"
/]

@_LEFTONLY_TOP_@

<!-- BEGIN CONTENT -->

<blockquote style="color: red">
	[warnings]
</blockquote>

<div style="text-align: left; padding: 5">
<h1>[scratch page_title]</h1>
[scratch survey_output]
</div>

<!-- END CONTENT -->

@_LEFTONLY_BOTTOM_@



2.17      +5 -48     interchange/dist/lib/UI/pages/admin/flex_select.html


rev 2.17, prev_rev 2.16
Index: flex_select.html
===================================================================
RCS file: /var/cvs/interchange/dist/lib/UI/pages/admin/flex_select.html,v
retrieving revision 2.16
retrieving revision 2.17
diff -u -r2.16 -r2.17
--- flex_select.html	11 Oct 2002 18:42:47 -0000	2.16
+++ flex_select.html	20 Nov 2002 18:52:17 -0000	2.17
@@ -68,39 +68,6 @@
 	$Scratch->{ui_class} = $CGI->{ui_class}
 		if $CGI->{ui_class}
 		&&  $CGI->{ui_class} =~ /^\w+$/;
-	if($CGI->{ui_sequence_edit}) {
-		my $doit;
-		if($CGI->{item_id_left} =~ s/^(.*?),//) {
-			$CGI->{item_id} = $1;
-			$doit = 1;
-		}
-		elsif ($CGI->{item_id_left}) {
-			$CGI->{item_id} = delete $CGI->{item_id_left};
-			delete $CGI->{ui_sequence_edit};
-			$doit = 1;
-		}
-		else {
-			delete $CGI->{item_id};
-			delete $CGI->{ui_sequence_edit};
-		}
-		return unless $doit;
-		$Scratch->{ui_location}
-				= $Tag->area( {
-						href => '__UI_BASE__/flex_editor',
-						secure => $Scratch->{page_secure},
-						form => qq{
-							mv_data_table=$CGI->{mv_data_table}
-							item_id=$CGI->{item_id}
-							item_id_left=$CGI->{item_id_left}
-							ui_sequence_edit=$CGI->{ui_sequence_edit}
-							ui_return_to=__UI_BASE__/flex_select
-							ui_return_to=mv_data_table=$CGI->{mv_data_table}
-							ui_return_to=ui_sequence_edit=$CGI->{ui_sequence_edit}
-							ui_page_banner=Edit next key $CGI->{item_id}
-						},
-					});
-		return;
-	}
 
 	my $tab = $CGI->{mv_data_table} or return;
 	if($tab =~ s/\.(txt|asc)$/_$1/) {
@@ -443,11 +410,12 @@
 	<INPUT TYPE=hidden NAME=mv_data_table    VALUE="[cgi mv_data_table]">
 	[if cgi ui_meta_view]
 	[return-to]
+	<!-- got a return-to -->
 	[else]
+	<!-- got no return-to -->
 	<INPUT TYPE=hidden NAME=ui_meta_specific VALUE="[cgi ui_meta_specific]">
 	<INPUT TYPE=hidden NAME=ui_page_title    VALUE="[cgi ui_page_title]">
-	<INPUT TYPE=hidden NAME=ui_page_title    VALUE="[cgi ui_page_banner]">
-	<INPUT TYPE=hidden NAME=ui_meta_specific VALUE="[cgi ui_meta_specific]">
+	<INPUT TYPE=hidden NAME=ui_page_banner   VALUE="[cgi ui_page_banner]">
 	<INPUT TYPE=hidden NAME=ui_limit_fields VALUE="[cgi ui_limit_fields]">
 	<INPUT TYPE=hidden NAME=ui_show_fields VALUE="[cgi ui_show_fields]">
 	<INPUT TYPE=hidden NAME=ui_return_to     VALUE="@@MV_PAGE@@">
@@ -586,18 +554,7 @@
 [on-match]
 [if !cgi ui_meta_view]
 [button text="[L]Edit checked records in sequence[/L]"]
-ui_sequence_edit=[calc]
-	$CGI->{item_id_left} = $CGI->{item_id};
-	$CGI->{item_id_left} =~ s/\0+/,/g;
-	if($CGI->{item_id_left} =~ s/^(.*?),//) {
-		$CGI->{item_id} = $1;
-		return 1;
-	}
-	else {
-		delete $CGI->{item_id_left};
-		return '';
-	}
-[/calc]
+ui_sequence_edit=1
 mv_nextpage=__UI_BASE__/flex_editor
 mv_todo=return
 [/button]
@@ -621,4 +578,4 @@
 [update values]
 
 @_UI_STD_FOOTER_@
-<!-- page: @@MV_PAGE@@ Revision: $Id: flex_select.html,v 2.16 2002/10/11 18:42:47 mheins Exp $ -->
+<!-- page: @@MV_PAGE@@ Revision: $Id: flex_select.html,v 2.17 2002/11/20 18:52:17 mheins Exp $ -->



2.5       +9 -13     interchange/dist/lib/UI/pages/admin/item_edit.html


rev 2.5, prev_rev 2.4
Index: item_edit.html
===================================================================
RCS file: /var/cvs/interchange/dist/lib/UI/pages/admin/item_edit.html,v
retrieving revision 2.4
retrieving revision 2.5
diff -u -r2.4 -r2.5
--- item_edit.html	7 Nov 2002 19:15:55 -0000	2.4
+++ item_edit.html	20 Nov 2002 18:52:17 -0000	2.5
@@ -1,17 +1,13 @@
-[perl tables="__UI_META_TABLE__"]
+[calc]
 	$CGI->{mv_data_table} = $Config->{ProductFiles}[0];
 	$CGI->{ui_hide_key} = 1 unless $CGI->{ui_new_item};
-
-	if(! $CGI->{ui_return_to} or $CGI->{ui_sequence_edit}) {
-		my @args = (
-			 '__UI_BASE__/item',
-			 "item_id_left=$CGI->{item_id_left}",
-			 "ui_sequence_edit=$CGI->{ui_sequence_edit}",
-		);
-		$CGI->{ui_return_to} = join "\0", @args;
-	}
+	$CGI->{ui_return_to} ||= '__UI_BASE__/item';
+	$Tag->tmpn('tmp_item_id');
+	$Scratch->{tmp_item_id} = $CGI->{item_id} || $CGI->{item_id_left};
+	$Scratch->{tmp_item_id} =~ s/\0.*//
+		or $Scratch->{tmp_item_id} =~ s/,.*//;
 	return;
-[/perl]
+[/calc]
 
 [if cgi ui_new_item]
 	[loop list="__MV_ITEM_TABLES__"]
@@ -33,7 +29,7 @@
 [/if]
 
 [set ui_class]Items[/set]
-[seti page_title][L]Item editor[/L]: [cgi item_id][/seti]
+[seti page_title][L]Item editor[/L]: [scratch tmp_item_id][/seti]
 [set help_name]edit.item[/set]
 [set icon_name]icon_item.gif[/set]
 
@@ -41,7 +37,7 @@
 [if cgi ui_new_item]
 	[msg]New item[/msg]
 [else]
-	[msg arg.0="<B>[cgi item_id]</B>"]edit item %s[/msg]
+	[msg arg.0="<B>[scratch tmp_item_id]</B>"]edit item %s[/msg]
 [/else]
 [/if]
 [/tmp]
@@ -80,4 +76,4 @@
 [/if-mm]
 
 @_UI_STD_FOOTER_@
-<!-- page: @@MV_PAGE@@ version: $Revision: 2.4 $ -->
+<!-- page: @@MV_PAGE@@ version: $Revision: 2.5 $ -->



1.1                  interchange/dist/lib/UI/pages/admin/survey/index.html


rev 1.1, prev_rev 1.0
Index: index.html
===================================================================
[calc]
	$Values->{mv_data_table} = $CGI->{mv_data_table} = 'survey_q';
	$CGI->{no_dbmenu} = 1;
	return;
[/calc]
[set table_perm]1[/set]
[set ui_class]Admin[/set]
[set page_title][L]Set up a survey[/L][/set]
[set help_name]survey.main[/set]
[set icon_name]icon_config.gif[/set]
@_UI_STD_HEAD_@

<!-- BEGIN REAL STUFF -->

<blockquote>

<form action="[area __UI_BASE__/survey/overall]">
<input type=hidden name=mv_action value=back>
<input type=hidden name=mv_session_id value="[data session_id]">
<input type=hidden name="mv_filter:item_id" value=word>
New survey name: <input type=text size=16 name=item_id>
<br>
<input type=submit value="[L]Create[/L]">
</form>

Edit an existing survey:
<ul>
[loop search="
		ml=1000
		fi=survey
		st=db
		co=yes
		se=master
		sf=type
		op=eq
		rf=code,label
	  "]
<li>[page href="__UI_BASE__/survey/overall" form="item_id=[loop-code]"][loop-code] -- [loop-param label]</A></li>
[/loop]
</ul>
</blockquote>

<blockquote>
<h2>Access survey results</h2>

	[file-navigator initial_dir="logs/survey" no-up=1 no-new-file=1]

</blockquote>
<!-- ----- END REAL STUFF ----- -->

@_UI_STD_FOOTER_@
<!-- page: @@MV_PAGE@@ version: $Id: index.html,v 1.1 2002/11/20 18:52:17 mheins Exp $ -->



1.1                  interchange/dist/lib/UI/pages/admin/survey/overall.html


rev 1.1, prev_rev 1.0
Index: overall.html
===================================================================
[set table_perms]survey[/set]
[if !cgi item_id]
	[cgi name=item_id set="[cgi code]" hide=1]
[/if]
[cgi name=mv_data_table set=survey hide=1]
[tmp page_title]
	Edit survey: [cgi item_id]
[/tmp]
[set ui_class]Admin[/set]

@_UI_STD_HEAD_@

[if !value formatter]
[page href=@@MV_PAGE@@
	  form=|
	  	item_id=[cgi item_id]
		mv_action=return
		formatter=1
	  |]Use option formatter</A>
	[tmpn options_extra]
		ui_te_widget:options=textarea_12_80
		ui_te_filter:options=line2options
		ui_te_pre_filter:options=options2line
		ui_te_help:options=One option per line, value to left of = sign.
		ui_te_default:options==--select one--
	[/tmpn]
[else]
[page href=@@MV_PAGE@@
	  form=|
	  	item_id=[cgi item_id]
		mv_action=return
		formatter=0
	  |]Use freeform option type</A>
	[tmpn options_extra]
		ui_te_widget:options=option_format
		ui_te_filter:options=option_format
		ui_te_help:options=Value on left, label on right.
		ui_te_default:options==--select one--
	[/tmpn]
[/else]
[/if]

[if type=data term="survey::code::[cgi item_id]"]
[tmpn survey_hide_key]1[/tmpn]
[tmp list_questions][data table=survey col=extended.ui_data_fields key="[cgi item_id]" serial=1][/tmp]
[calc]
	my $string = $Scratch->{list_questions} or return;
#::logDebug("fields were=$opt->{ui_data_fields}");
	my $ids = $CGI->{item_id} . '::';
	$string =~ s/\r\n/\n/g;
	$string =~ s/\r/\n/g;
	$string =~ s/^[ \t]+//mg;
	$string =~ s/[ \t]+$//mg;

	my %break;

	if($string =~ /\n\n/) {
		my @breaks;
		my @break_labels;
		my $fstring = "\n\n$string";
		while ($fstring =~ s/\n+(?:\n[ \t]*=(.*))?\n+[ \t]*(\w[:.\w]+)/\n$2/) {
			$break{$2} = $1;
		}
		$breaks = join(" ", @breaks);
		$breaks = join(",", @break_labels);
		$string = $fstring;
	}
	$string =~ s/^[\s,\0]+//;
	$string =~ s/[\s,\0]+$//;
	$string =~ s/[,\0\s]+/ /g;
	my @fields = split /\s+/, $string;
	my @out = "code\tname\tlabel";
	for(@fields) {
		push @out, join "\t", "$ids$_", $_, $break{$_} || '';
	}
	$Scratch->{list_questions} = join "\n", @out;
	return;
[/calc]
[/if]


<table>
	<tr>
[loop lr=1 head-skip=1 list="[scratch list_questions]"]
[on-match]
		<td valign=top>
<table>
<tr class=rmarq>
	<td>
		Question field
	</td>
	<td>
		Question
	</td>
</tr>
[/on-match]
[list]
[if-loop-param label]
<tr class=rbreak>
	<td colspan=2 style="border: 1px solid  #996633;">
		[loop-param label]
	</td>
</tr>
[/if-loop-param]
<tr class="[item-alternate 2]rnorm[else]ralt[/else][/item-alternate]">
	<td>
		[page href="__UI_BASE__/flex_editor"
				form="
					mv_data_table=survey
					item_id=[loop-code]
					ui_te_override:name=[loop-param name]
					[scratch options_extra]
					ui_return_to=@@MV_PAGE@@
					ui_return_to=item_id=[cgi item_id]
				"][loop-param name]</A>
	</td>
	<td>
		[if-loop-data survey label]
			[loop-filter 30.][loop-data survey label][/loop-filter]
		[else]
			(not yet input)
		[/else]
		[/if-loop-data]
	</td>
</tr>
[/list]
[on-match]
</table>
[/on-match]
		</td>
[/loop]

		<td>

[table-editor
	table=survey
	no-table-meta=1
	tabbed=1
	table_width=620
	tab_width=100
	break_row_class=rmarq
	panel_width=600
	panel_height=500
	no-meta=1
	left_width=130
	label_cell_valign=top
	help_cell_width=150
	start_at="[cgi start_at]"
	item_id="[cgi item_id]"
	ui_hide_key="[scratch survey_hide_key]"

	ui_data_fields="

		=General

		code
		label
		type
		extended.display_type
		extended.intro_text

		=Questions

		extended.ui_data_fields

		=Display page

		extended.bottom_buttons
		extended.top_buttons
		extended.table_width
		extended.left_width

		=HTML Classes

		extended.data_row_class
		extended.break_row_class
		extended.spacer_row_class
		extended.combo_row_class
		extended.border_cell_class
		extended.label_cell_class
		extended.data_cell_class
		extended.widget_cell_class
		extended.help_cell_class

		=Survey Output

		extended.output_type
		extended.output_href
		extended.output_parm
		extended.output_email
		extended.email_template
		extended.email_from
		extended.email_cc
		extended.output_repeated

		=Thanks

		extended.thanks_title
		extended.thanks_message
		extended.already_title
		extended.already_message

	"

	label=`{
		code							=> 'Survey key',
		label							=> 'Main title',
		'extended.already_message'		=> 'Message to show when already completed',
		'extended.already_title'		=> 'Title when already completed',
		'extended.border_cell_class'	=> 'Border cell class',
		'extended.bottom_buttons'		=> 'Buttons only on bottom',
		'extended.break_row_class'		=> 'Break row class',
		'extended.combo_row_class'		=> 'User widget row class',
		'extended.data_cell_class'		=> 'Data cell class (standard row)',
		'extended.data_row_class'		=> 'Data row class',
		'extended.display_type'			=> 'Display type',
		'extended.email_cc'				=> 'Who to Cc: on email response',
		'extended.email_from'			=> 'Address emailed response is from',
		'extended.email_template'		=> 'Email template or file',
		'extended.help_cell_class'		=> 'Help cell class (standard row)',
		'extended.intro_text'			=> 'Intro Text',
		'extended.label_cell_class'		=> 'Label cell class (standard row)',
		'extended.left_width'			=> 'Width specification for label column',
		'extended.other_fields'			=> 'Other information to collect',
		'extended.output_email'			=> 'Target email address',
		'extended.output_href'			=> 'Forward-to page or URL',
		'extended.output_parm'			=> 'Forward-to extra parameters',
		'extended.output_repeated'		=> 'Allow repeated survey?',
		'extended.output_type'			=> 'Output Type',
		'extended.restrict_allow'		=> 'Allow these ITL tags',
		'extended.spacer_row_class'		=> 'Spacer row class',
		'extended.table_width'			=> 'Width specification for editor table',
		'extended.thanks_message'		=> 'Body of finished page',
		'extended.thanks_title'			=> 'Title for finished page',
		'extended.top_buttons'			=> 'Buttons only on top',
		'extended.ui_data_fields'		=> 'Question fields',
		'extended.ui_display_only'		=> 'Fields for display only',
		'extended.widget_cell_class'	=> 'Widget cell class (standard row)',

	}`

	help=`{
		'extended.output_email'		    => 'Address for sending email fulfillment.',
		'extended.email_template'		=> 'Template for email fulfillment. Looks for a file if one line, uses default template if empty.',
		'extended.output_href'			=> 'Page base for forwarded URL, will have form paramters added. Use http:// only if outside IC catalog.',
		'extended.output_parm'			=> 'Extra parameters for forwarded url, key=value, one per line.',
		'extended.output_repeated'		=> 'Set to yes to allow more than one response per session or per user',
		'extended.intro_text'			=> 'Introduction to survey (if any). Shown on first page only.',
		'extended.ui_data_fields'		=> 'Page divisions can be embedded in the fields by placing &quot;=Title String&quot; on a line by itself and surrounding with blank lines.',
		'extended.ui_display_only'		=> 'Will not be set, only shown.',
	}`

	widget=`{
		code							=> 'text_20',
		label							=> 'text_60',
		type							=> 'hidden',
		'extended.already_message'		=> 'textarea_4_60',
		'extended.already_title'		=> 'text_60',
		'extended.bottom_buttons'		=> 'yesno',
		'extended.display_type'			=> 'select',
		'extended.email_cc'			    => 'text_40',
		'extended.email_from'		    => 'text_40',
		'extended.email_template'		=> 'textarea_4_60',
		'extended.intro_text'		    => 'textarea_8_50',
		'extended.left_width'			=> 'text_8',
		'extended.output_email'		    => 'text_40',
		'extended.output_href'		    => 'text_40',
		'extended.output_parm'		    => 'textarea_2_40',
		'extended.output_repeated'	    => 'yesno',
		'extended.output_type'		    => 'select',
		'extended.panel_height'			=> 'text_5',
		'extended.panel_width'			=> 'text_5',
		'extended.table_width'		    => 'text_8',
		'extended.thanks_message'		=> 'textarea_4_60',
		'extended.thanks_title'			=> 'text_60',
		'extended.top_buttons'		=> 'yesno',
		'extended.ui_data_fields'		=> 'textarea_20_60',
		'extended.view_from'			=> 'select',
	}`

	override.type=master

	filter=`{
		height							=> 'digits',
	}`

	database=`{
		'extended.ui_sort_field'		=> $CGI->{ui_table},
		'extended.ui_show_fields'		=> $CGI->{ui_table},
		'extended.ui_data_fields'		=> $CGI->{ui_table},
		'extended.view_from'			=> $CGI->{ui_table},
		'extended.spread_fields'		=> $CGI->{ui_table},
		'extended.spread_meta'			=> $CGI->{ui_table},
		'extended.spread_textarea'		=> $CGI->{ui_table},
	}`

	height=`{
		'extended.ui_sort_field'		=> 8,
		'extended.ui_show_fields'		=> 8,
		'extended.ui_data_fields'		=> 16,
		'extended.spread_fields'		=> 8,
	}`

	width=`{
		'extended.ui_data_fields'		=> 30,
		'extended.ui_show_fields'		=> 30,
	}`

	form=`{
			fieldmeta => '',
	}`

	wid_href=`{
			fieldmeta => 'meta_editor',
	}`

	options=`{
		'extended.display_type'		=> q{
over_under=Question on one line&#44; answer on line below,
0=Question in left column and answer in right column,
			},
		'extended.output_type'		=> q{
survey_log=Standard survey log,
email_only=Email response,
auto_bounce=Automatic bounce to page (requires page below),
0=none (use wizard default -- need page below),
			},
	}`

]
	</td>
</tr>
</table>
@_UI_STD_FOOTER_@
<!-- page: @@MV_PAGE@@ version: $Revision: 1.1 $ -->



1.1                  interchange/dist/lib/UI/pages/admin/survey/question.html


rev 1.1, prev_rev 1.0
Index: question.html
===================================================================
[if cgi fieldmeta]
	[cgi name=item_id set="[cgi fieldmeta]"]
[/if]
[if !cgi item_id]
	[bounce page="__UI_BASE__/gentable"]
[/if]
[calc]
	my $location = $CGI->{item_id};
	my @parts = split /::/, $location;
	if($Config->{Database}{$parts[0]}) {
		($m_table, $m_col, $m_key) = @parts;
	}
	else {
		($m_view, $m_table, $m_col, $m_key) = @parts;
	}
	my @frags;
	push(@frags,errmsg('Meta field edit') . ':');
    push(@frags,errmsg('view=%s', $m_view)) if $m_view;
    push(@frags,errmsg('table=%s column=%s', $m_table, $m_col));
	push(@frags,errmsg('key=%s', $m_key)) if $m_key;
	$Scratch->{page_title} = join(' ',@frags);

	my $string = <<EOF;
	<B>Meta information edit&nbsp;&nbsp;&nbsp;</b><BR>
	<table>
EOF

	$string .= <<EOF if $m_view;
	<tr>
	<td align=right>view:</td>
	<td><B>$m_view</b></td>
	</tr>
EOF

	$string .= <<EOF;
	<tr>
	<td align=right>table:</td>
	<td><B>$m_table</b></td>
	</tr>
	<tr>
	<td align=right>column:</td>
	<td><B>$m_col</b></td>
	</tr>
	</table>
EOF

	$Scratch->{page_banner} = $string;
	$CGI->{ui_meta_view} = 'metaconfig';
	if(! $CGI->{mv_data_table}) {
		$CGI->{mv_data_table} = '__UI_META_TABLE__';
	}
	if(! $CGI->{ui_data_fields}) {
		$CGI->{ui_data_fields} = 'code label help help_url type width height options filter lookup field db lookup_exclude outboard pre_filter prepend append';
										
	}
	if(! $CGI->{ui_break_before}) {
		$CGI->{ui_break_before} = 'help type lookup outboard prepend';
		$CGI->{ui_break_before_label} = 'type=Display control, help=Help information, lookup=Database lookup, outboard=Advanced';
	}
	return;
[/calc]

[set ui_class]Admin[/set]
[set help_name]meta.edit[/set]
[set icon_name][/set]

@_UI_STD_HEAD_@

[table-editor
	item_id="[cgi item_id]"
	table="[cgi mv_data_table]"
	no-table-meta=1
	no-meta=1
	ui_data_fields="
		=Label

		code
		label

		=Widget

		type
		filter
		width
		height
		options

	   =Help

	   help
	   help_url

	   =Database lookup

	   lookup
	   field
	   db
	   lookup_query
	   lookup_exclude

	   =Advanced

	   outboard
	   pre_filter
	   prepend
	   append

	   =Extended

	   extended
	"
	widget.extended="textarea_5_50"
	tabbed=1
	panel_width=800
	panel_height=700
	table_width=800
	][/table-editor]

@_UI_STD_FOOTER_@
<!-- page: @@MV_PAGE@@ version: $Revision: 1.1 $ -->



1.5       +1 -1      interchange/dist/lib/UI/pages/include/menus/Admin.txt


rev 1.5, prev_rev 1.4
Index: Admin.txt
===================================================================
RCS file: /var/cvs/interchange/dist/lib/UI/pages/include/menus/Admin.txt,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Admin.txt	12 Sep 2002 05:09:44 -0000	1.4
+++ Admin.txt	20 Nov 2002 18:52:17 -0000	1.5
@@ -7,7 +7,7 @@
 006	Admin	x006					admin/preferences		Preferences		0								
 007	Admin	x007		`$CGI->{mv_data_table} eq 'variable' or $CGI->{mv_data_table} && return -1`			admin/flex_select	mv_data_table=variable&page_title=Knar%20editor&ui_meta_specific=1&doing_knar=1&help_name=knar.main&ui_description_fields=code&ui_return_to=admin/flex_select&ui_return_to=mv_data_table=variable&ui_return_to=page_title=Knar%20Editor	Knar	1	1								1
 008	Admin	x008					admin/gentable		Tables		0								
-009	Admin	x009					admin/auto_wizard		Wizard		0								
+009	Admin	x009					admin/survey/index		Surveys		0	Create polls, surveys, and mail forms	survey						
 010	Admin	x010					admin/test_code		Test code		0								
 011	Admin	x011					admin/reconfig		&nbsp;&nbsp;&nbsp;Apply Changes		0								
 012	Admin	x012	1		no_dbmenu	mv_data_table	admin/flex_select	mv_data_table=[cgi mv_data_table]	Edit		0								



1.19      +147 -59   interchange/lib/Vend/Table/Editor.pm


rev 1.19, prev_rev 1.18
Index: Editor.pm
===================================================================
RCS file: /var/cvs/interchange/lib/Vend/Table/Editor.pm,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Editor.pm	15 Nov 2002 13:43:11 -0000	1.18
+++ Editor.pm	20 Nov 2002 18:52:17 -0000	1.19
@@ -1,6 +1,6 @@
 # Vend::Table::Editor - Swiss-army-knife table editor for Interchange
 #
-# $Id: Editor.pm,v 1.18 2002/11/15 13:43:11 mheins Exp $
+# $Id: Editor.pm,v 1.19 2002/11/20 18:52:17 mheins Exp $
 #
 # Copyright (C) 2002 ICDEVGROUP <interchange@icdevgroup.org>
 # Copyright (C) 2002 Mike Heins <mike@perusion.net>
@@ -26,7 +26,7 @@
 package Vend::Table::Editor;
 
 use vars qw($VERSION);
-$VERSION = substr(q$Revision: 1.18 $, 10);
+$VERSION = substr(q$Revision: 1.19 $, 10);
 
 use Vend::Util;
 use Vend::Interpolate;
@@ -162,8 +162,9 @@
 #::logDebug("meta_record: item=$item view=$view mdb=$mdb");
 	return undef unless $item;
 
+	my $mtable;
 	if(! ref ($mdb)) {
-		my $mtable = $mdb || $::Variable->{UI_META_TABLE} || 'mv_metadata';
+		$mtable = $mdb || $::Variable->{UI_META_TABLE} || 'mv_metadata';
 #::logDebug("meta_record mtable=$mtable");
 		$mdb = database_exists_ref($mtable)
 			or return undef;
@@ -174,7 +175,7 @@
 
 	my $mkey = $view ? "${view}::$item" : $item;
 
-	if(ref $mdb eq 'HASH') {
+	if(! $mtable) {
 		$record = $mdb;
 	}
 	else {
@@ -182,7 +183,7 @@
 #::logDebug("used mkey=$mkey to select record=$record");
 	}
 
-	$record ||= $mdb->row_hash($item) if $view;
+	$record ||= $mdb->row_hash($item) if $view and $mdb;
 #::logDebug("meta_record  record=$record");
 
 	return undef if ! $record;
@@ -982,6 +983,55 @@
 	push @hmap, [ qr/ui_te_$_:/, $_ ];
 }
 
+my %ignore_cgi = qw/
+					item_id				1
+					item_id_left		1
+					mv_pc				1
+					mv_action           1
+					mv_todo             1
+					mv_ui               1
+					mv_data_table       1
+					mv_session_id       1
+					mv_nextpage         1
+					ui_sequence_edit	1
+				  /;
+sub save_cgi {
+	my $ref = {};
+	my @k; 
+	if($CGI::values{save_cgi}) {
+		@k = split /\0/, $CGI::values{save_cgi};
+	}
+	else {
+		@k = grep ! $ignore_cgi{$_}, keys %CGI::values;
+	}
+
+	# Can be an array because of produce_hidden
+	$ref->{save_cgi} = \@k;
+
+	for(@k) {
+		$ref->{$_} = $CGI::values{$_};
+	}
+	return $ref;
+}
+
+sub produce_hidden {
+	my ($key, $val) = @_;
+	return unless length $val;
+	my @p; # pieces of var
+	my @o; # output
+	if(ref($val) eq 'ARRAY') {
+		@p = @$val;
+	}
+	else {
+		@p = split /\0/, $val;
+	}
+	for(@p) {
+		s/"/&quot;/g;
+		push @o, qq{<input type=hidden name="$key" value="$_">\n};
+	}
+	return join "", @o;
+}
+
 sub resolve_options {
 	my ($opt, $CGI, $data) = @_;
 
@@ -1109,6 +1159,7 @@
 		data_row_class
 		data_row_style
 		default_widget
+		display_type
 		file_upload
 		help_cell_class
 		help_cell_style
@@ -1117,6 +1168,7 @@
 		include_form
 		include_form_expand
 		include_form_interpolate
+		intro_text
 		label_cell_class
 		label_cell_style
 		left_width
@@ -1407,13 +1459,36 @@
 
 	my @messages;
 	my @errors;
+	my $pass_return_to;
 
 #::logDebug("key at beginning: $key");
 	$opt->{mv_data_table} = $table if $table;
-	$opt->{item_id}		  = $key if $key;
 	$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 ||= delete $CGI->{item_id};
+		$opt->{item_id_left} ||= delete $CGI::values{item_id_left};
+		$opt->{ui_sequence_edit} ||= delete $CGI::values{ui_sequence_edit};
+	}
+
+	if($key =~ /\0/ or (! $key and $key = delete $opt->{item_id_left}) ) {
+		delete $opt->{ui_sequence_edit};
+		if($key =~ s/\0(.*)//s or $key =~ s/,(.*)//s ) {
+			$opt->{item_id_left} = $1;
+			$opt->{ui_sequence_edit} = 1;
+		}
+	}
+
+	$opt->{item_id} = $key;
+
+	$pass_return_to = save_cgi() if $opt->{ui_sequence_edit};
+
+#::logDebug("item_id_left=" . ::uneval($opt->{item_id_left}));
+#::logDebug("pass_return_to=" . ::uneval($pass_return_to));
+#::logDebug("ui_sequence_edit=$opt->{ui_sequence_edit}");
 	my $data;
 	my $exists;
 	my $db;
@@ -1424,7 +1499,7 @@
 	unless($opt->{notable}) {
 		# From Vend::Data
 		my $tab = $table || $opt->{mv_data_table} || $CGI->{mv_data_table};
-		my $key = $key || $opt->{item_id} || $CGI->{item_id};
+		my $key = $opt->{item_id} || $CGI->{item_id};
 		$db = database_exists_ref($tab);
 
 		if($db) {
@@ -1486,11 +1561,15 @@
 	my $blabel = $opt->{blabel};
 	my $elabel = $opt->{elabel};
 	my $mlabel = '';
+	my $hidden = $opt->{hidden} ||= {};
 
 	my $ntext;
 	my $btext;
 	my $ctext;
-	unless ($opt->{wizard} || $opt->{nosave}) {
+	if($pass_return_to) {
+		delete $::Scratch->{$opt->{next_text}};
+	}
+	elsif (! $opt->{wizard} and ! $opt->{nosave}) {
 		$::Scratch->{$opt->{next_text}} = $Tag->return_to('click', 1);
 	}
 	else {
@@ -1556,12 +1635,12 @@
 	if($opt->{ui_profile} or $check) {
 		$Tag->error( { all => 1 } )
 			unless $CGI->{mv_form_profile} or $opt->{keep_errors};
-		my $prof = $opt->{ui_profile} || '';
+		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"} || '';
+			$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) {
@@ -1606,7 +1685,6 @@
 				$prof .= "$_=mandatory\n";
 			}
 		}
-		$opt->{hidden} = {} if ! $opt->{hidden};
 		$opt->{hidden}{mv_form_profile} = 'ui_profile';
 		my $fail = $opt->{mv_failpage} || $Global::Variable->{MV_PAGE};
 
@@ -1940,15 +2018,7 @@
 	$opt->{href} = "$url_base/$opt->{href}"
 		if $opt->{href} !~ m{^(https?:|)/};
 
-	my $sidstr;
-	if ($opt->{get}) {
-		$opt->{method} = 'GET';
-		$sidstr = '';
-	} else {
-		$opt->{method} = 'POST';
-		$sidstr = qq{<INPUT TYPE=hidden NAME=mv_session_id VALUE="$Vend::Session->{id}">
-};
-	}
+	$opt->{method} = $opt->{get} ? 'GET' : 'POST';
 
 	my $wo = $opt->{widgets_only};
 
@@ -1965,12 +2035,16 @@
 	chunk 'FORM_BEGIN', <<EOF; # unless $wo;
 $restrict_begin<FORM METHOD=$opt->{method} ACTION="$opt->{href}"$opt->{enctype}$opt->{form_extra}>
 EOF
+
+    $hidden->{mv_click}      = $opt->{process_filter};
+    $hidden->{mv_todo}       = $opt->{action};
+    $hidden->{mv_nextpage}   = $opt->{mv_nextpage};
+    $hidden->{mv_data_table} = $table;
+    $hidden->{mv_data_key}   = $keycol;
+
 	chunk 'HIDDEN_ALWAYS', <<EOF;
-$sidstr<INPUT TYPE=hidden NAME=mv_todo VALUE="$opt->{action}">
+<INPUT TYPE=hidden NAME=mv_session_id VALUE="$Vend::Session->{id}">
 <INPUT TYPE=hidden NAME=mv_click VALUE="process_filter">
-<INPUT TYPE=hidden NAME=mv_nextpage VALUE="$opt->{mv_nextpage}">
-<INPUT TYPE=hidden NAME=mv_data_table VALUE="$table">
-<INPUT TYPE=hidden NAME=mv_data_key VALUE="$keycol">
 EOF
 
 	my @opt_set = (qw/
@@ -1985,36 +2059,23 @@
 						mv_update_empty
 						mv_data_auto_number
 						mv_data_function
-				/ );
+				/);
 
 	my @cgi_set = ( qw/
 						item_id_left
 						ui_sequence_edit
 					/ );
 
-	push(@opt_set, splice(@cgi_set, 0)) if $opt->{cgi};
-
-  OPTSET: {
-  	my @o;
-	for(@opt_set) {
-		next unless length $opt->{$_};
-		my $val = $opt->{$_};
-		$val =~ s/"/&quot;/g;
-		push @o, qq{<INPUT TYPE=hidden NAME=$_ VALUE="$val">\n}; # unless $wo;
+	for my $k (@opt_set, @cgi_set) {
+		$opt->{hidden}{$k} = $opt->{$k};
 	}
-	chunk 'HIDDEN_OPT', '', join("", @o);
-  }
 
-  CGISET: {
-	my @o;
-	for (@cgi_set) {
-		next unless length $CGI->{$_};
-		my $val = $CGI->{$_};
-		$val =~ s/"/&quot;/g;
-		push @o, qq{<INPUT TYPE=hidden NAME=$_ VALUE="$val">\n}; # unless $wo;
+	if($pass_return_to) {
+		while( my($k, $v) = each %$pass_return_to) {
+			next if defined $opt->{hidden}{$k};
+			$opt->{hidden}{$k} = $pass_return_to->{$k};
+		}
 	}
-	chunk 'HIDDEN_CGI', '', join("", @o);
-  }
 
 	if($opt->{mailto}) {
 		$opt->{mailto} =~ s/\s+/ /g;
@@ -2024,7 +2085,7 @@
 
 	$Vend::Session->{ui_return_stack} ||= [];
 
-	if($opt->{cgi}) {
+	if($opt->{cgi} and ! $pass_return_to) {
 		my $r_ary = $Vend::Session->{ui_return_stack};
 
 #::logDebug("ready to maybe push/pop return-to from stack, stack = " . ::uneval($r_ary));
@@ -2043,7 +2104,7 @@
 		my ($hk, $hv);
 		my @o;
 		while ( ($hk, $hv) = each %{$opt->{hidden}} ) {
-			push @o, qq{<INPUT TYPE=hidden NAME="$hk" VALUE="$hv">\n};
+			push @o, produce_hidden($hk, $hv);
 		}
 		chunk 'HIDDEN_USER', join("", @o); # unless $wo;
 	}
@@ -2061,8 +2122,17 @@
 </tr>
 EOF
 
-	  #### Extra buttons
-      my $extra_ok =	$blob_widget
+	if ($opt->{intro_text}) {
+#::logDebug("intro_text=$opt->{intro_text}");
+		chunk ttag(), <<EOF;
+<tr> 
+	<td colspan=$span class=$opt->{title_cell_class}>$opt->{intro_text}</td>
+</tr>
+EOF
+	}
+
+	#### Extra buttons
+	my $extra_ok =	$blob_widget
 	  					|| $linecount > 4
 						|| defined $opt->{include_form}
 						|| $mlabel;
@@ -2336,15 +2406,15 @@
 	$keycol = $cols[0] if ! $keycol;
 
 	if($opt->{defaults}) {
-			if($opt->{force_defaults}) {
+		if($opt->{force_defaults}) {
 			$default->{$_} = $def->{$_} for @cols;
-			}
-			elsif($opt->{wizard}) {
+		}
+		elsif($opt->{wizard}) {
 			for(@cols) {
 				$default->{$_} = $def->{$_} if defined $def->{$_};
 			}
 		}
-			else {
+		else {
 			for(@cols) {
 				next if defined $default->{$_};
 				next unless defined $def->{$_};
@@ -2401,9 +2471,11 @@
 	}
 
  	my $row_template = convert_old_template($opt->{row_template});
-	
+
+#::logDebug("display_type='$opt->{display_type}' row_template length=" . length($row_template));
+
 	if(! $row_template) {
-		if($opt->{simple_row}) {
+		if($opt->{simple_row} || $opt->{display_type} eq 'simple_row') {
 			$row_template = <<EOF;
    <td$opt->{label_cell_extra}> 
      {BLABEL}{LABEL}{ELABEL}
@@ -2430,6 +2502,24 @@
    </td>
 EOF
 		}
+		elsif($opt->{display_type} eq 'over_under') {
+			$row_template = <<EOF;
+{HELP?}
+	<td colspan=2$opt->{help_cell_extra}>
+		{HELP}
+	</td>
+</tr>
+<tr>
+{/HELP?}	<td colspan=2$opt->{label_cell_extra}>
+		{LABEL}
+	</td>
+</tr>
+<tr>
+	<td colspan=2$opt->{widget_cell_extra}>
+		{WIDGET}
+	</td>
+EOF
+		}
 		else {
 			$row_template = <<EOF;
    <td$opt->{label_cell_extra}> 
@@ -2763,7 +2853,7 @@
 		elsif (defined $default->{$c} and ! length($data->{$c}) ) {
 			$currval = $default->{$c};
 			$overridden = 1;
-#::logDebug("hit default setting for $col,currval=$currval");
+#::logDebug("hit preload for $col,currval=$currval");
 		}
 		else {
 #::logDebug("hit data->col for $col, t=$t, c=$c, k=$k, currval=$currval");
@@ -3151,9 +3241,7 @@
 	}
 	chunk_alias 'HIDDEN_FIELDS', qw/
 										HIDDEN_ALWAYS
-										HIDDEN_OPT
-										HIDDEN_CGI
-										HIDDEN_USER
+										HIDDEN_AUTO
 										HIDDEN_EXTRA
 										/;
 	chunk_alias 'BOTTOM_BUTTONS', qw/



2.61      +1 -2      interchange/scripts/interchange.PL


rev 2.61, prev_rev 2.60
Index: interchange.PL
===================================================================
RCS file: /var/cvs/interchange/scripts/interchange.PL,v
retrieving revision 2.60
retrieving revision 2.61
diff -u -r2.60 -r2.61
--- interchange.PL	25 Oct 2002 01:49:36 -0000	2.60
+++ interchange.PL	20 Nov 2002 18:52:17 -0000	2.61
@@ -3,7 +3,7 @@
 #
 # Interchange version 4.9.3
 #
-# $Id: interchange.PL,v 2.60 2002/10/25 01:49:36 mheins Exp $
+# $Id: interchange.PL,v 2.61 2002/11/20 18:52:17 mheins Exp $
 #
 # Copyright (C) 1996-2002 Red Hat, Inc. and others.
 # http://www.icdevgroup.org/
@@ -254,7 +254,6 @@
 #											add_items
 #											check_order
 #											check_required
-#											cyber_charge
 #   										encrypt_standard_cc
 #   										mail_order
 #   										onfly



2.3       +3 -1      interchange/scripts/update.PL


rev 2.3, prev_rev 2.2
Index: update.PL
===================================================================
RCS file: /var/cvs/interchange/scripts/update.PL,v
retrieving revision 2.2
retrieving revision 2.3
diff -u -r2.2 -r2.3
--- update.PL	27 Jun 2002 18:55:50 -0000	2.2
+++ update.PL	20 Nov 2002 18:52:17 -0000	2.3
@@ -3,7 +3,7 @@
 #
 # Interchange database updater
 #
-# $Id: update.PL,v 2.2 2002/06/27 18:55:50 jon Exp $
+# $Id: update.PL,v 2.3 2002/11/20 18:52:17 mheins Exp $
 #
 # Copyright (C) 1996-2002 Red Hat, Inc. <interchange@redhat.com>
 #
@@ -208,6 +208,8 @@
 global_config();
 
 chdir $dir or die "Couldn't change directory to $dir: $!\n";
+
+$Vend::ExternalProgram = $Vend::Quiet = 1;
 
 $Vend::Cfg = config($name, $dir, "$dir/etc", ($subconfig || undef));
 $::Variable = $Vend::Cfg->{Variable};