abstract stupid HTML layer trick out to HTML::Widgets::SelectLayers
authorivan <ivan>
Tue, 12 Mar 2002 15:33:22 +0000 (15:33 +0000)
committerivan <ivan>
Tue, 12 Mar 2002 15:33:22 +0000 (15:33 +0000)
README.1.4.0pre12
htetc/global.asa
htetc/handler.pl
httemplate/docs/install.html
httemplate/docs/upgrade8.html
httemplate/edit/part_pkg.cgi
httemplate/edit/part_svc.cgi

index 0b453a4..824b7fd 100644 (file)
@@ -7,6 +7,8 @@ httemplate/docs/upgrade8.html instead
 
 ----
 
+install HTML-Widgets-SelectLayers from CPAN or http://www.420.am/selectlayers
+
 install the FS perl modules and httemplate as per install.html or upgrade8.html
 
 ALTER TABLE cust_bill_event ADD status varchar(80);
index 339f01d..083f225 100644 (file)
@@ -9,6 +9,7 @@ use HTML::Entities;
 use IO::Handle;
 use IO::File;
 use String::Approx qw(amatch);
+use HTML::Widgets::SelectLayers;
 use FS::UID qw(cgisuidsetup dbh getotaker datasrc);
 use FS::Record qw(qsearch qsearchs fields dbdef);
 use FS::Conf;
@@ -45,6 +46,8 @@ use FS::svc_domain;
 use FS::svc_forward;
 use FS::svc_www;
 use FS::type_pkgs;
+use FS::part_export;
+#use FS::part_export_option;
 
 sub Script_OnStart {
   $Response->AddHeader('Pragma' => 'no-cache');
index 680d11e..5f24492 100644 (file)
@@ -66,6 +66,7 @@ sub handler
       use IO::Handle;
       use IO::File;
       use String::Approx qw(amatch);
+      use HTML::Widgets::SelectLayers;
       use FS::UID qw(cgisuidsetup dbh getotaker datasrc);
       use FS::Record qw(qsearch qsearchs fields dbdef);
       use FS::Conf;
@@ -102,6 +103,8 @@ sub handler
       use FS::svc_forward;
       use FS::svc_www;
       use FS::type_pkgs;
+      use FS::part_export;
+      #use FS::part_export_option;
 
       *CGI::redirect = sub {
         my( $self, $location ) = @_;
index d7c014f..1a4942b 100644 (file)
@@ -50,6 +50,7 @@ Before installing, you need:
       <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>
       <li><a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a>
       <li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>
+      <li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>
     </ul>
 </ul>
 Install the Freeside distribution:
index 4b0c493..2640be4 100644 (file)
@@ -7,7 +7,7 @@
   <li>If migrating from less than 1.3.1, see these <a href="upgrade7.html">instructions</a> first.
   <li><font size="+2" color="#ff0000">Backup your database and current Freeside installation.</font> (with&nbsp;<a href="http://www.ca.postgresql.org/devel-corner/docs/postgres/backup.html">PostgreSQL</a>) (with&nbsp;<a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Backup">MySQL</a>)
   <li><a href="http://perl.apache.org/">mod_perl</a> is now required.
-  <li>Install <a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>, and <a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a>
+  <li>Install <a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>, <a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a> and <a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>.
   <li>Install <a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>.
   <li>Install <a href="http://rsync.samba.org/">rsync</a>
 </ul>
index 8e7a6c5..d3213dd 100755 (executable)
@@ -42,24 +42,12 @@ unless ( $part_pkg->plan ) { #backwards-compat
 $action ||= $part_pkg->pkgpart ? 'Edit' : 'Add';
 my $hashref = $part_pkg->hashref;
 
-%>
-
-<SCRIPT>
-function visualize(what) {
-  if (document.getElementById) {
-    document.getElementById('d<%= $part_pkg->plan %>').style.visibility = "visible";
-  } else {
-    document.l<%= $part_pkg->plan %>.visibility = "visible";
-  }
-}
-</SCRIPT>
-
-<% 
 
 print header("$action Package Definition", menubar(
   'Main Menu' => popurl(2),
   'View all packages' => popurl(2). 'browse/part_pkg.cgi',
-), ' onLoad="visualize()"');
+));
+#), ' onLoad="visualize()"');
 
 print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
       "</FONT>"
@@ -164,8 +152,12 @@ unless ( 0 ) {
   #print "</TR></TABLE>";
 }
 
+foreach my $f ( qw( clone pkgnum ) ) {
+  print qq!<INPUT TYPE="hidden" NAME="$f" VALUE="!. $cgi->param($f). '">';
+}
+print '<INPUT TYPE="hidden" NAME="pkgpart" VALUE="'. $part_pkg->pkgpart. '">';
+
 # prolly should be in database
-use Tie::IxHash;
 tie my %plans, 'Tie::IxHash',
   'flat' => {
     'name' => 'Flat rate',
@@ -314,159 +306,99 @@ tie my %plans, 'Tie::IxHash',
 
 ;
 
-%>
-
-<SCRIPT>
-var layer = null;
-
-function changed(what) {
-  layer = what.options[what.selectedIndex].value;
-<% foreach my $layer ( keys %plans ) { %>
-  if (layer == "<%= $layer %>" ) {
-    <% foreach my $not ( grep { $_ ne $layer } keys %plans ) { %>
-      if (document.getElementById) {
-        document.getElementById('d<%= $not %>').style.visibility = "hidden";
-      } else {
-        document.l<%= $not %>.visibility = "hidden";
-      }
-    <% } %>
-    if (document.getElementById) {
-      document.getElementById('d<%= $layer %>').style.visibility = "visible";
-    } else {
-      document.l<%= $layer %>.visibility = "visible";
-    }
-  }
-<% } %>
-}
-
-</SCRIPT>
-<BR>
-Price plan <SELECT NAME="plan" SIZE=1 onChange="changed(this);">
-<OPTION>
-<% foreach my $layer (keys %plans ) { %>
-<OPTION VALUE="<%= $layer %>"<%= ' SELECTED'x($layer eq $part_pkg->plan) %>><%= $plans{$layer}->{'name'} %>
-<% } %>
-</SELECT></FORM>
-
-<SCRIPT>
-function fchanged(what) {
-  fixup(what.form);
-}
-
-function fixup(what) {
-<% foreach my $f ( qw( pkg comment freq ), @fixups ) { %>
-  what.<%= $f %>.value = document.dummy.<%= $f %>.value;
-<% } %>
-<% foreach my $f ( qw( setuptax recurtax disabled ) ) { %>
-  if (document.dummy.<%= $f %>.checked)
-    what.<%= $f %>.value = 'Y';
-  else
-    what.<%= $f %>.value = '';
-<% } %>
-  what.plan.value = document.dummy.plan.options[document.dummy.plan.selectedIndex].value;
-<% foreach my $p ( keys %plans ) { %>
-  if ( what.plan.value == "<%= $p %>" ) {
-    what.setup.value = <%= $plans{$p}->{setup} %>;
-    what.recur.value = <%= $plans{$p}->{recur} %>;
-  }
-<% } %>
-}
-</SCRIPT>
-
-<% my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
+my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
                     split("\n", $part_pkg->plandata );
-   #foreach my $layer ( 'konq_kludge', keys %plans ) { 
-   foreach my $layer ( 'konq_kludge', keys %plans ) {
-     my $visibility = "hidden";
-%>
-<SCRIPT>
-if (document.getElementById) {
-    document.write("<DIV ID=\"d<%= $layer %>\" STYLE=\"visibility: <%= $visibility %>; position: absolute\">");
-} else {
-<% $visibility="show" if $visibility eq "visible"; %>
-    document.write("<LAYER ID=\"l<%= $layer %>\" VISIBILITY=\"<%= $visibility %>\">");
-}
-</SCRIPT>
-
-<FORM NAME="<%= $layer %>" ACTION="process/part_pkg.cgi" METHOD=POST onSubmit="fixup(this)">
-<INPUT TYPE="hidden" NAME="plan" VALUE="<%= $part_pkg->plan %>">
-<INPUT TYPE="hidden" NAME="pkg" VALUE="<%= $hashref->{pkg} %>">
-<INPUT TYPE="hidden" NAME="comment" VALUE="$<%= $hashref->{comment} %>">
-<INPUT TYPE="hidden" NAME="freq" VALUE="<%= $hashref->{freq} %>">
-<INPUT TYPE="hidden" NAME="setuptax" VALUE="<%= $hashref->{setuptax} %>">
-<INPUT TYPE="hidden" NAME="recurtax" VALUE="<%= $hashref->{recurtax} %>">
-<INPUT TYPE="hidden" NAME="disabled" VALUE="<%= $hashref->{disabled} %>">
-<% foreach my $f ( @fixups ) { %>
-<INPUT TYPE="hidden" NAME="<%= $f %>" VALUE="">
-<% } %>
 
-<%
-if ( $cgi->param('clone') ) {
-  print qq!<INPUT TYPE="hidden" NAME="clone" VALUE="!, $cgi->param('clone'), qq!">!;
-}
-if ( $cgi->param('pkgnum') ) {
-  print qq!<INPUT TYPE="hidden" NAME="pkgnum" VALUE="!, $cgi->param('pkgnum'), qq!">!;
-}
-%>
+tie my %options, 'Tie::IxHash', map { $_=>$plans{$_}->{'name'} } keys %plans;
+
+my $widget = new HTML::Widgets::SelectLayers(
+  'selected_layer' => $part_pkg->plan,
+  'options'        => \%options,
+  'form_name'      => 'dummy',
+  'form_action'    => 'process/part_pkg.cgi',
+  'form_text'      => [ qw(pkg comment freq clone pkgnum pkgpart), @fixups ],
+  'form_checkbox'  => [ qw(setuptax recurtax disabled) ],
+  'fixup_callback' => sub {
+                        #my $ = @_;
+                        my $html = '';
+                        for my $p ( keys %plans ) {
+                          $html .= "if ( what.plan.value == \"$p\" ) {
+                                      what.setup.value = $plans{$p}->{setup} ;
+                                      what.recur.value = $plans{$p}->{recur} ;
+                                    }\n";
+                        }
+                        $html;
+                      },
+  'layer_callback' => sub {
+    my $layer = shift;
+    my $html = qq!<INPUT TYPE="hidden" NAME="plan" VALUE="$layer">!.
+               ntable("#cccccc",2);
+    my $href = $plans{$layer}->{'fields'};
+    foreach my $field ( exists($plans{$layer}->{'fieldorder'})
+                          ? @{$plans{$layer}->{'fieldorder'}}
+                          : keys %{ $href }
+                      ) {
+
+      $html .= '<TR><TD ALIGN="right">'. $href->{$field}{'name'}. '</TD><TD>';
+
+      if ( ! exists($href->{$field}{'type'}) ) {
+        $html .= qq!<INPUT TYPE="text" NAME="$field" VALUE="!.
+                 ( exists($plandata{$field})
+                     ? $plandata{$field}
+                     : $href->{$field}{'default'} ).
+                 qq!" onChange="fchanged(this)">!;
+      } elsif ( $href->{$field}{'type'} eq 'select_multiple' ) {
+        $html .= qq!<SELECT MULTIPLE NAME="$field" onChange="fchanged(this)">!;
+        foreach my $record (
+          qsearch( $href->{$field}{'select_table'},
+                   $href->{$field}{'select_hash'}   )
+        ) {
+          my $value = $record->getfield($href->{$field}{'select_key'});
+          $html .= qq!<OPTION VALUE="$value"!.
+                   (  $plandata{$field} =~ /(^|, *)$value *(,|$)/
+                        ? ' SELECTED'
+                        : ''          ).
+                   '>'. $record->getfield($href->{$field}{'select_label'})
+        }
+        $html .= '</SELECT>';
+      }
 
-<INPUT TYPE="hidden" NAME="pkgpart" VALUE="<%= $hashref->{pkgpart} %>">
-<%= ntable("#cccccc",2) %>
+      $html .= '</TD></TR>';
+    }
+    $html .= '</TABLE>';
+
+    $html .= '<INPUT TYPE="hidden" NAME="plandata" VALUE="'.
+             join(',', keys %{ $href } ). '">'.
+             '<BR><BR>';
+             
+    $html .= '<INPUT TYPE="submit" VALUE="'.
+             ( $hashref->{pkgpart} ? "Apply changes" : "Add package" ).
+             '" onClick="fchanged(this)">';
+
+    $html .= '<BR><BR>don\'t edit this unless you know what you\'re doing '.
+             '<INPUT TYPE="button" VALUE="refresh expressions" '.
+               'onClick="fchanged(this)">'.
+             ntable("#cccccc",2).
+             '<TR><TD>'.
+             '<FONT SIZE="1">Setup expression<BR>'.
+             '<INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="'.
+               $hashref->{setup}. '" onLoad="fchanged(this)">'.
+             '</FONT><BR>'.
+             '<FONT SIZE="1">Recurring espression<BR>'.
+             '<INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="'.
+               $hashref->{recur}. '" onLoad="fchanged(this)">'.
+             '</FONT>'.
+             '</TR></TD>'.
+             '</TABLE>';
+
+    $html;
 
-<% my $href = $plans{$layer}->{'fields'};
-   foreach my $field ( exists($plans{$layer}->{'fieldorder'})
-                         ? @{$plans{$layer}->{'fieldorder'}}
-                         : keys %{ $href }
-                     ) {
-%>
-  <TR><TD ALIGN="right"><%= $href->{$field}{'name'} %></TD>
-  <TD>
-  <% if ( ! exists($href->{$field}{'type'}) ) { %>
-       <INPUT TYPE="text" NAME="<%= $field %>" VALUE="<%= exists($plandata{$field}) ? $plandata{$field} : $href->{$field}{'default'} %>" onChange="fchanged(this)">
-  <% } elsif ( $href->{$field}{'type'} eq 'select_multiple' ) { %>
-       <SELECT MULTIPLE NAME="<%= $field %>" onChange="fchanged(this)">
-       <% foreach my $record ( qsearch( $href->{$field}{'select_table'}, $href->{$field}{'select_hash'} ) ) {
-          my $value = $record->getfield($href->{$field}{'select_key'}); %>
-         <OPTION VALUE="<%= $value %>"<%= $plandata{$field} =~ /(^|, *)$value *(,|$)/ ? ' SELECTED' : '' %>><%= $record->getfield($href->{$field}{'select_label'}) %>
-       <% } %>
-       </SELECT>
-  <% } %>
-  </TD></TR>
-<% } %>
-
-</TABLE>
-<INPUT TYPE="hidden" NAME="plandata" VALUE="<%= join(',', keys %{ $href } ) %>">
-<BR><BR>
+  },
+);
 
-<%
-print qq!<INPUT TYPE="submit" VALUE="!,
-      $hashref->{pkgpart} ? "Apply changes" : "Add package",
-      qq!" onClick="fchanged(this)">!;
 %>
 
-<BR><BR>don't edit this unless you know what you're doing <INPUT TYPE="button" VALUE="refresh expressions" onClick="fchanged(this)"><%= ntable("#cccccc",2) %><TR><TD>
-<FONT SIZE="1">Setup expression<BR><INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="<%= $hashref->{setup} %>" onLoad="fchanged(this)"></FONT><BR>
-<FONT SIZE="1">Recurring espression<BR><INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="<%= $hashref->{recur} %>" onLoad="fchanged(this)"></FONT>
-</TR></TD>
-</TABLE>
-
-</FORM>
-
-<SCRIPT>
-if (document.getElementById) {
-  document.write("</DIV>");
-} else {
-  document.write("</LAYER>");
-}
-</SCRIPT>
-
-<% } %>
-
-<TAG onLoad="
-    if (document.getElementById) {
-      document.getElementById('d<%= $part_pkg->plan %>').style.visibility = 'visible';
-    } else {
-      document.l<%= $part_pkg->plan %>.visibility = 'visible';
-    }
-">
+<BR>
+Price plan <%= $widget->html %>
   </BODY>
 </HTML>
index 57ab398..3292a9b 100755 (executable)
    }
    my $action = $part_svc->svcpart ? 'Edit' : 'Add';
    my $hashref = $part_svc->hashref;
-   my $p_svcdb = $part_svc->svcdb || 'svc_acct';
+#   my $p_svcdb = $part_svc->svcdb || 'svc_acct';
 
-%>
 
-<SCRIPT>
-function visualize(what) {
-  if (document.getElementById) {
-    document.getElementById('d<%= $p_svcdb %>').style.visibility = "visible";
-  } else {
-    document.l<%= $p_svcdb %>.visibility = "visible";
-  }
-}
-</SCRIPT>
+           #" onLoad=\"visualize()\""
+%>
 
 <%= header("$action Service Definition",
            menubar( 'Main Menu'         => $p,
                     'View all service definitions' => "${p}browse/part_svc.cgi"
                   ),
-           " onLoad=\"visualize()\""
            )
 %>
 
@@ -47,6 +38,7 @@ function visualize(what) {
 <BR><BR>
 Service  <INPUT TYPE="text" NAME="svc" VALUE="<%= $hashref->{svc} %>"><BR>
 Disable new orders <INPUT TYPE="checkbox" NAME="disabled" VALUE="Y"<%= $hashref->{disabled} eq 'Y' ? ' CHECKED' : '' %>><BR>
+<INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $hashref->{svcpart} %>">
 <BR>
 Services are items you offer to your customers.
 <UL><LI>svc_acct - Shell accounts, POP mailboxes, SLIP/PPP and ISDN accounts
@@ -64,37 +56,6 @@ values.  For example, a SLIP/PPP account may have a default (or perhaps fixed)
 blank <B>slipip</B> as well as a fixed shell something like <B>/bin/true</B> or
 <B>/usr/bin/passwd</B>.
 <BR><BR>
-<SCRIPT>
-var svcdb = null;
-function changed(what) {
-  svcdb = what.options[what.selectedIndex].value;
-<% foreach my $svcdb ( qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www ) ) { %>
-  if (svcdb == "<%= $svcdb %>" ) {
-    <% foreach my $not ( grep { $_ ne $svcdb } (
-                           qw(svc_acct svc_domain svc_acct_sm svc_forward svc_www) ) ) { %>
-      if (document.getElementById) {
-        document.getElementById('d<%= $not %>').style.visibility = "hidden";
-      } else {
-        document.l<%= $not %>.visibility = "hidden";
-      }
-    <% } %>
-    if (document.getElementById) {
-      document.getElementById('d<%= $svcdb %>').style.visibility = "visible";
-    } else {
-      document.l<%= $svcdb %>.visibility = "visible";
-    }
-  }
-<% } %>
-}
-</SCRIPT>
-<% my @dbs = $hashref->{svcdb}
-             ? ( $hashref->{svcdb} )
-             : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www ); %>
-Table<SELECT NAME="svcdb" SIZE=1 onChange="changed(this)">
-<% foreach my $svcdb (@dbs) { %>
-<OPTION VALUE="<%= $svcdb %>" <%= ' SELECTED'x($svcdb eq $hashref->{svcdb}) %>><%= $svcdb %>
-<% } %>
-</SELECT></FORM>
 
 <%
 #these might belong somewhere else for other user interfaces 
@@ -152,121 +113,81 @@ my %defs = (
   },
 );
 
-#  svc_acct svc_domain svc_acct_sm svc_charge svc_wo
-foreach my $svcdb ( qw(
-  konq_kludge svc_acct svc_domain svc_acct_sm svc_forward svc_www
-) ) {
-
-#  my(@fields) = $svcdb eq 'konq_kludge'
-#                  ? ()
-#                  : grep { $_ ne 'svcnum' } fields($svcdb);
-  #yucky kludge
-  my(@fields) = defined( $FS::Record::dbdef->table($svcdb) )
-                  ? grep { $_ ne 'svcnum' } fields($svcdb)
-                  : ();
-  #my($rowspan)=scalar(@rows);
-
-  #my($ptmp)="<TD ROWSPAN=$rowspan>$svcdb</TD>";
-#  $visibility = $svcdb eq $part_svc->svcdb ? "SHOW" : "HIDDEN";
-#  $visibility = $svcdb eq $p_svcdb ? "visible" : "hidden";
-  my $visibility = "hidden";
-%>
-<SCRIPT>
-if (document.getElementById) {
-    document.write("<DIV ID=\"d<%= $svcdb %>\" STYLE=\"visibility: <%= $visibility %>; position: absolute\">");
-} else {
-<% $visibility="show" if $visibility eq "visible"; %>
-    document.write("<LAYER ID=\"l<%= $svcdb %>\" VISIBILITY=\"<%= $visibility %>\">");
-}
-
-function fixup(what) {
-  what.svc.value = document.dummy.svc.value;
-  what.svcdb.value = document.dummy.svcdb.options[document.dummy.svcdb.selectedIndex].value;
-  if (document.dummy.disabled.checked)
-    what.disabled.value = 'Y';
-  else
-    what.disabled.value = '';
-}
-</SCRIPT>
-<FORM NAME="<%= $svcdb %>" ACTION="process/part_svc.cgi" METHOD=POST onSubmit="fixup(this)">
-<INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $hashref->{svcpart} %>">
-<INPUT TYPE="hidden" NAME="svc" VALUE="<%= $hashref->{svc} %>">
-<INPUT TYPE="hidden" NAME="disabled" VALUE="<%= $hashref->{disabled} %>">
-<INPUT TYPE="hidden" NAME="svcdb" VALUE="<%= $svcdb %>">
-<%
-  #print "$svcdb<BR>" unless $svcdb eq 'konq_kludge';
-  print table(). "<TH>Field</TH><TH COLSPAN=2>Modifier</TH>" unless $svcdb eq 'konq_kludge';
-
-  foreach my $field (@fields) {
-    my $part_svc_column = $part_svc->part_svc_column($field);
-    my $value = $cgi->param('error')
-                  ? $cgi->param("${svcdb}__${field}")
-                  : $part_svc_column->columnvalue;
-    my $flag = $cgi->param('error')
-                 ? $cgi->param("${svcdb}__${field}_flag")
-                 : $part_svc_column->columnflag;
-    #print "<TR>$ptmp<TD>$field";
-    print "<TR><TD>$field";
-    my $def = $defs{$svcdb}{$field};
-    my $desc = ref($def) ? $def->{desc} : $def;
-    
-    print "- <FONT SIZE=-1>$desc</FONT>" if $desc;
-    print "</TD>";
-    print qq!<TD><INPUT TYPE="radio" NAME="${svcdb}__${field}_flag" VALUE=""!.
-      ' CHECKED'x($flag eq ''). ">Off</TD>";
-    print qq!<TD><INPUT TYPE="radio" NAME="${svcdb}__${field}_flag" VALUE="D"!.
-      ' CHECKED'x($flag eq 'D'). ">Default ";
-    print qq!<INPUT TYPE="radio" NAME="${svcdb}__${field}_flag" VALUE="F"!.
-      ' CHECKED'x($flag eq 'F'). ">Fixed ";
-    print '<BR>';
-    if ( ref($def) ) {
-      if ( $def->{type} eq 'select' ) {
-        print qq!<SELECT NAME="${svcdb}__${field}">!;
-        print '<OPTION> </OPTION>' unless $value;
-        foreach my $record ( qsearch( $def->{select_table}, {} ) ) {
-          my $rvalue = $record->getfield($def->{select_key});
-          print qq!<OPTION VALUE="$rvalue"!.
-                ( $rvalue==$value ? ' SELECTED>' : '>' ).
-                $record->getfield($def->{select_label}). '</OPTION>';
+  my @dbs = $hashref->{svcdb}
+             ? ( $hashref->{svcdb} )
+             : qw( svc_acct svc_domain svc_acct_sm svc_forward svc_www );
+
+  tie my %svcdb, 'Tie::IxHash', map { $_=>$_ } @dbs;
+  my $widget = new HTML::Widgets::SelectLayers(
+    #'selected_layer' => $p_svcdb,
+    'selected_layer' => $hashref->{svcdb} || 'svc_acct',
+    'options'        => \%svcdb,
+    'form_name'      => 'dummy',
+    'form_action'    => 'process/part_svc.cgi',
+    'form_text'      => [ qw( svc svcpart ) ],
+    'form_checkbox'  => [ 'disabled' ],
+    'layer_callback' => sub {
+      my $layer = shift;
+      my $html = qq!<INPUT TYPE="hidden" NAME="svcdb" VALUE="$layer">!.
+                 table(). "<TH>Field</TH><TH COLSPAN=2>Modifier</TH>";
+      #yucky kludge
+      my @fields = defined( $FS::Record::dbdef->table($layer) )
+                      ? grep { $_ ne 'svcnum' } fields($layer)
+                      : ();
+      foreach my $field (@fields) {
+        my $part_svc_column = $part_svc->part_svc_column($field);
+        my $value = $cgi->param('error')
+                      ? $cgi->param("${layer}__${field}")
+                      : $part_svc_column->columnvalue;
+        my $flag = $cgi->param('error')
+                     ? $cgi->param("${layer}__${field}_flag")
+                     : $part_svc_column->columnflag;
+        my $def = $defs{$layer}{$field};
+        my $desc = ref($def) ? $def->{desc} : $def;
+        
+        $html .= "<TR><TD>$field";
+        $html .= "- <FONT SIZE=-1>$desc</FONT>" if $desc;
+        $html .=  "</TD>";
+        $html .=
+          qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE=""!.
+          ' CHECKED'x($flag eq ''). ">Off</TD>".
+          qq!<TD><INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="D"!.
+          ' CHECKED'x($flag eq 'D'). ">Default ".
+          qq!<INPUT TYPE="radio" NAME="${layer}__${field}_flag" VALUE="F"!.
+          ' CHECKED'x($flag eq 'F'). ">Fixed ".
+          '<BR>';
+        if ( ref($def) ) {
+          if ( $def->{type} eq 'select' ) {
+            $html .= qq!<SELECT NAME="${layer}__${field}">!;
+            $html .= '<OPTION> </OPTION>' unless $value;
+            foreach my $record ( qsearch( $def->{select_table}, {} ) ) {
+              my $rvalue = $record->getfield($def->{select_key});
+              $html .= qq!<OPTION VALUE="$rvalue"!.
+                       ( $rvalue==$value ? ' SELECTED>' : '>' ).
+                       $record->getfield($def->{select_label}). '</OPTION>';
+            }
+            $html .= '</SELECT>';
+          } else {
+            $html .= '<font color="#ff0000">unknown type'. $def->{type};
+          }
+        } else {
+          $html .=
+            qq!<INPUT TYPE="text" NAME="${layer}__${field}" VALUE="$value">!;
         }
-        print '</SELECT>';
-      } else {
-        print '<font color="#ff0000">unknown type'. $def->{type};
+        $html .= "</TD></TR>\n";
       }
-    } else {
-      print qq!<INPUT TYPE="text" NAME="${svcdb}__${field}" VALUE="$value">!;
-    }
-    print "</TD></TR>\n";
-    #$ptmp='';
-  }
-  print "</TABLE>" unless $svcdb eq 'konq_kludge';
+      $html .= "</TABLE>";
 
-print qq!\n<BR><INPUT TYPE="submit" VALUE="!,
-      $hashref->{svcpart} ? "Apply changes" : "Add service",
-      qq!">! unless $svcdb eq 'konq_kludge';
+      $html .= '<BR><INPUT TYPE="submit" VALUE="'.
+               ($hashref->{svcpart} ? 'Apply changes' : 'Add service'). '">';
 
-  print "</FORM>";
-  print <<END;
-    <SCRIPT>
-    if (document.getElementById) {
-      document.write("</DIV>");
-    } else {
-      document.write("</LAYER>");
-    }
-    </SCRIPT>
-END
-}
-#print "</TABLE>";
-%>
+      $html;
 
-<TAG onLoad="
-    if (document.getElementById) {
-      document.getElementById('d<%= $p_svcdb %>').style.visibility = 'visible';
-    } else {
-      document.l<%= $p_svcdb %>.visibility = 'visible';
-    }
-">
+    },
+  );
 
+%>
+Table <%= $widget->html %>
   </BODY>
 </HTML>