RT#27396: Why does it take so long for the New/Edit billing event pages to load?...
authorJonathan Prykop <jonathan@freeside.biz>
Tue, 2 Aug 2016 05:07:01 +0000 (00:07 -0500)
committerJonathan Prykop <jonathan@freeside.biz>
Tue, 2 Aug 2016 05:07:01 +0000 (00:07 -0500)
httemplate/edit/elements/edit.html
httemplate/edit/part_event.html
httemplate/elements/selectlayersx.html [new file with mode: 0644]
httemplate/elements/tr-selectlayersx.html [new file with mode: 0644]

index bbc9797..8dd15dc 100644 (file)
@@ -650,7 +650,7 @@ Example:
           var newrow =  <% include(@layer_opt, html_only=>1) |js_string %>;
 
 %         #until the rest have html/js_only
           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_/ ) {
+%         if ( ($type eq 'selectlayers') || ($type eq 'selectlayersx') || ($type =~ /^select-cgp_rule_/) ) {
             var newfunc = <% include(@layer_opt, js_only=>1) |js_string %>;
 %         } else {
             var newfunc = '';
             var newfunc = <% include(@layer_opt, js_only=>1) |js_string %>;
 %         } else {
             var newfunc = '';
index 47b8c1a..c8072e9 100644 (file)
@@ -31,7 +31,7 @@
                               value   => 'Event Conditions',
                             },
                             { field   => 'conditionname',
                               value   => 'Event Conditions',
                             },
                             { field   => 'conditionname',
-                              type    => 'selectlayers',
+                              type    => 'selectlayersx',
                               options => [ keys %all_conditions ],
                               labels  => \%condition_labels,
                               onchange => 'condition_changed(what);',
                               options => [ keys %all_conditions ],
                               labels  => \%condition_labels,
                               onchange => 'condition_changed(what);',
@@ -51,7 +51,7 @@
                               value   => 'Event Action',
                             },
                             { field   => 'action',
                               value   => 'Event Action',
                             },
                             { field   => 'action',
-                              type     => 'selectlayers',
+                              type     => 'selectlayersx',
                               options  => [ keys %all_actions ],
                               labels   => \%action_labels,
                               onchange => 'action_changed(what);',
                               options  => [ keys %all_actions ],
                               labels   => \%action_labels,
                               onchange => 'action_changed(what);',
diff --git a/httemplate/elements/selectlayersx.html b/httemplate/elements/selectlayersx.html
new file mode 100644 (file)
index 0000000..41f3cb0
--- /dev/null
@@ -0,0 +1,248 @@
+<%doc>
+
+Example:
+
+  include( '/elements/selectlayers.html',
+    'field'        => $key, # SELECT element NAME (passed as form field)
+                            # also used as ID and a unique key for layers and
+                            # functions
+    'curr_value'   => $selected_layer,
+    'options'      => [ 'option1', 'option2' ],
+    'labels'       => { 'option1' => 'Option 1 Label',
+                        'option2' => 'Option 2 Label',
+                      },
+
+    #XXX put this handling it its own selectlayers-fields.html element?
+    'layer_prefix' => 'prefix_', #optional prefix for fieldnames
+    'layer_fields' => { 'layer'  => [ 'fieldname',
+                                      { label => 'fieldname2',
+                                        type  => 'text', #implemented:
+                                                         # text, money, fixed,
+                                                         # hidden, checkbox,
+                                                         # checkbox-multiple,
+                                                         # select, select-agent,
+                                                         # select-pkg_class,
+                                                         # select-part_referral,
+                                                         # select-taxclass,
+                                                         # select-table,
+                                                         #XXX tbd:
+                                                         # more?
+                                      },
+                                      ...
+                                    ],
+                        'layer2' => [ 'l2fieldname',
+                                      ...
+                                    ],
+                      },
+
+    #current values for layer fields above
+    'layer_values' => { 'layer'  => { 'fieldname'  => 'current_value',
+                                      'fieldname2' => 'field2value',
+                                      ...
+                                    },
+                        'layer2' => { 'l2fieldname' => 'l2value',
+                                      ...
+                                    },
+                        ...
+                      },
+
+    #or manual control, instead of layer_fields and layer_values above
+    #called with args: my( $layer, $layer_fields, $layer_values, $layer_prefix )
+    'layer_callback' => 
+
+    'html_between  => '', #optional HTML displayed between the SELECT and the
+                          #layers, scalar or coderef ('field' passed as a param)
+    'onchange'     => '', #javascript code run when the SELECT changes
+                          # ("what" is the element)
+    'js_only'      => 0, #set true to return only the JS portions
+    'html_only'    => 0, #set true to return only the HTML portions
+    'select_only'  => 0, #set true to return only the <SELECT> HTML
+    'layers_only'  => 0, #set true to return only the layers <DIV> HTML
+  )
+
+</%doc>
+% unless ( grep $opt{$_}, qw(html_only js_only select_only layers_only) ) {
+<SCRIPT TYPE="text/javascript">
+% }
+% unless ( grep $opt{$_}, qw(html_only select_only layers_only) ) {
+
+%   unless ($selectlayersx_init) {
+
+var selectlayerx_info = {};
+
+function selectlayersx_changed (field) {
+
+  var what = document.getElementById(field);
+  selectlayerx_info[field]['onchange'](what);
+
+  var selectedlayer = what.options[what.selectedIndex].value;
+  for (i=0; i < selectlayerx_info[field]['layers'].length; i++) {
+    var iterlayer = selectlayerx_info[field]['layers'][i];
+    var iterobj   = document.getElementById(field+'d'+iterlayer);
+    if (selectedlayer == iterlayer) {
+      iterobj.style.display = "";
+      iterobj.style.zIndex  = 1;
+    } else {
+      iterobj.style.display = "none";
+      iterobj.style.zIndex  = 0;
+    }
+  }
+
+}
+
+%     $selectlayersx_init = 1;
+%   } #selectlayersx_init
+
+selectlayerx_info['<% $key %>'] = {};
+selectlayerx_info['<% $key %>']['onchange'] = function (what) { <% $opt{'onchange'} %> };
+selectlayerx_info['<% $key %>']['layers']   = <% encode_json(\@layers) %>;
+
+
+% } #unless html_only/select_only/layers_only
+% unless ( grep $opt{$_}, qw(html_only js_only select_only layers_only) ) {
+</SCRIPT>
+% }
+%
+% unless ( grep $opt{$_}, qw(js_only layers_only) ) {
+
+    <SELECT NAME          = "<% $key %>"
+            ID            = "<% $key %>"
+            previousValue = "<% $selected %>"
+            previousText  = "<% $options{$selected} %>"
+            onChange="selectlayersx_changed('<% $key %>')"
+    >
+
+%     foreach my $option ( keys %$options ) {
+
+        <OPTION VALUE="<% $option %>"
+                <% $option eq $selected ? ' SELECTED' : '' %>
+        ><% $options->{$option} |h %></OPTION>
+
+%     }
+
+    </SELECT>
+
+% }
+% unless ( grep $opt{$_}, qw(js_only select_only layers_only) ) {
+
+<% ref($between) ? &{$between}($key) : $between %>
+
+% }
+%
+% unless ( grep $opt{$_}, qw(js_only select_only) ) {
+
+%   foreach my $layer ( @layers ) {
+%     my $selected_layer;
+%     $selected_layer = $selected;
+
+      <DIV ID="<% $key %>d<% $layer %>"
+           STYLE="<% $selected_layer eq $layer
+                       ? 'display: block; z-index: 1'
+                       : 'display: none; z-index: 0'
+                  %>"
+      >
+
+        <% &{$layer_callback}($layer, $layer_fields, $layer_values, $layer_prefix) %>
+
+      </DIV>
+
+%   }
+
+% }
+<%once>
+
+my $conf = new FS::Conf;
+my $money_char = $conf->config('money_char') || '$';
+my $date_noinit = 0;
+
+</%once>
+<%shared>
+
+my $selectlayersx_init = 0;
+
+</%shared>
+<%init>
+
+my %opt = @_;
+
+#use Data::Dumper;
+#warn Dumper(%opt);
+
+my $key = $opt{field}; # || 'generate_one' #?
+
+tie my %options, 'Tie::IxHash',
+   map { $_ => $opt{'labels'}->{$_} }
+       @{ $opt{'options'} }; #just arrayref for now
+
+my $between = exists($opt{html_between}) ? $opt{html_between} : '';
+my $options = \%options;
+
+my @layers = ();
+@layers = keys %options;
+
+my $selected = exists($opt{curr_value}) ? $opt{curr_value} : '';
+
+#XXX eek.  also eek $layer_fields in the layer_callback() call...
+my $layer_fields = $opt{layer_fields};
+my $layer_values = $opt{layer_values};
+my $layer_prefix = $opt{layer_prefix};
+
+my $layer_callback = $opt{layer_callback} || \&layer_callback;
+
+sub layer_callback {
+  my( $layer, $layer_fields, $layer_values, $layer_prefix ) = @_;
+
+  return  '' unless $layer && exists $layer_fields->{$layer};
+  tie my %fields, 'Tie::IxHash', @{ $layer_fields->{$layer} };
+
+  #XXX this should become an element itself... (false laziness w/edit.html)
+  # but at least all the elements inside are the shared mason elements now
+
+  return '' unless keys %fields;
+  my $html = "<TABLE>";
+
+  foreach my $field ( keys %fields ) {
+
+    my $lf = ref($fields{$field})
+               ? $fields{$field}
+               : { 'label'=>$fields{$field} };
+
+    my $value = $layer_values->{$layer}{$field};
+
+    my $type = $lf->{type} || 'text';
+
+    my $include = $type;
+
+    if ( $include eq 'date' ) {
+      # several important differences from other tr-*
+      $html .= include( '/elements/tr-input-date-field.html',
+        {
+          'name'  => "$layer_prefix$field",
+          'value' => $value,
+          'label' => $lf->{label},
+          'format'=> $lf->{format},
+          'noinit'=> $date_noinit,
+        }
+      );
+      $date_noinit = 1;
+    }
+    else {
+      $include = "input-$include" if $include =~ /^(text|money|percentage)$/;
+      $include = "tr-$include" unless $include eq 'hidden';
+      $html .= include( "/elements/$include.html",
+                        %$lf,
+                        'field'      => "$layer_prefix$field",
+                        'id'         => "$layer_prefix$field", #separate?
+                        #don't want field0_label0...?
+                        'label_id'   => $layer_prefix.$field."_label",
+
+                        'value'      => ( $lf->{'value'} || $value ), #hmm.
+                        'curr_value' => $value,
+                    );
+    }
+  } #foreach $field
+  $html .= '</TABLE>';
+  return $html;
+}
+
+</%init>
diff --git a/httemplate/elements/tr-selectlayersx.html b/httemplate/elements/tr-selectlayersx.html
new file mode 100644 (file)
index 0000000..ca7a360
--- /dev/null
@@ -0,0 +1,25 @@
+% unless ( $opt{js_only} ) {
+
+  <% include('tr-td-label.html', @_ ) %>
+
+    <TD <% $style %>>
+
+% }
+
+      <% include('selectlayersx.html', @_ ) %>
+
+% unless ( $opt{js_only} ) {
+
+    </TD>
+
+  </TR>
+
+% }
+
+<%init>
+
+my %opt = @_;
+
+my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+</%init>