X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=httemplate%2Felements%2Fcustomer-table.html;h=457157e6da0d402402f1d168264f840279fe1eda;hb=2554b11e48a7ec4567bf89f9a48f7a83ec925eea;hp=779b01c51e25b9ea69d582d61ce02807d5296b75;hpb=bb51c09147a727688b6cd49e8838b9219ff25d43;p=freeside.git diff --git a/httemplate/elements/customer-table.html b/httemplate/elements/customer-table.html index 779b01c51..457157e6d 100644 --- a/httemplate/elements/customer-table.html +++ b/httemplate/elements/customer-table.html @@ -4,23 +4,85 @@ Example: include( '/elements/customer-table.html', + ### + # required + ### + #listrefs... - 'header' => [ '#', 'Item' ], - 'fields' => [ - 'column', - sub { my ($row,$param) = @_; - $param->{"column$row"}; - }, - ], - 'sizes' => [], # sizes ignored for immutable - 'types' => ['immutable', ''], # immutable or ''/text - 'param' => { column0 => 1 }, # preset column of row 0 to 1 + 'header' => [ '#', 'Item' ], + 'fields' => [ + 'column', + sub { my ($row,$param) = @_; + $param->{"column$row"}; + }, + ], + + ### + # optional + ### + + 'name_singular' => 'customer', #label + 'custnum_update_callback' => 'name_of_js_callback' #passed a rownum + + #listrefs + 'type' => ['immutable', ''], # immutable, checkbox, date or ''/text + 'align' => [ 'c', 'l', 'r', '' ], + 'size' => [], # sizes ignored for immutable + 'color' => [], + 'footer' => ['string', '_TOTAL'], # strings or the special + #value _TOTAL + 'footer_align' => [ 'c', 'l', 'r', '' ], + + 'param' => { column0 => 1 }, # preset column of row 0 to 1 + ) - +Some incomplete notes for javascript programmers: + +On page load, existing rows are initialized by passing values to addRow +based on existing cgi values. An empty row (marked with the 'emptyrow' +attribute) is created by invoking addRow without values. After that, +to keep the non-empty row count (totalrows) accurate, use newEmptyRow to +create the next row. There should only be one empty row at a time. + +Global vars: +total_el - element for displaying total number of rows +totalrows - total number of non-empty rows +rownum - really more of a "next row" value, used by addRow +allrows - array of tr elements, one for each row + +Don't confuse the global rownum with the element attribute rownum +that is set as a reference point on some of the elements generated +by this script. They have different values. + +Some of the functions: +updateTotalRow() - updates total_el based on value of totalrows +addDeleteButton(searchrow) - adds delete button to searchrow +newEmptyRow() - replaces old empty row +deleteRow() - removes the row specified by this.rownum +addRow(values) - adds a new row (marked as empty if values aren't specified) +This mason element is currently only used by misc/batch-cust_pay.html, +and probably should be cleaned up more before being used by anything else. + + + + + + - - - - - - -% foreach my $header ( @{$opt{header}} ) { - -% } - -% my $row = 0; -% for ( $row = 0; exists($param->{"custnum$row"}); $row++ ) { - - - - - - + function update_status_text(rownum, newval) { + document.getElementById('status'+rownum).value = newval; + document.getElementById('status'+rownum+'_text').innerHTML = newval; + } -% my $col = 0; -% foreach my $field ( @{$opt{fields}} ) { -% my $value; -% if ( ref($field) eq 'CODE' ) { -% $value = &{$field}($row,$param); -% } else { -% $value = $param->{"$field$row"}; -% } -% my $name = (ref($field) eq 'CODE') ? "column${col}_$row" : "$field$row"; -% my $size = $sizes->[$col] || 10; - -% $col++; -% } + function update_status_color(rownum, newval) { + document.getElementById('statuscolor'+rownum).value = newval; + document.getElementById('status'+rownum+'_text').style.color = newval; + } - -% } + function update_balance_text(rownum, newval) { + document.getElementById('balance'+rownum).value = newval; + document.getElementById('balance'+rownum+'_text').innerHTML = newval; + } + function update_num_open(rownum, newval) { + document.getElementById('num_open'+rownum).value = newval; + num_open_invoices[rownum] = newval; + } -
Cust #Customer<% $header %>
- " rownum="<% $row %>"> - - - " rownum="<% $row %>"> - - - - -% if (! $types->[$col] || $types->[$col] eq 'text') { - -% } elsif ($types->[$col] eq 'immutable') { - <% $value %> - -% } else { - Cannot represent unknown type: <% $types->[$col] %> -% } -
+ // updates display of total rows based on value of totalrows + function updateTotalRow () { + if ( totalrows == 1 ) { + total_el.innerHTML = + 'Total ' + + totalrows + + ' <% $opt{name_singular} || 'customer' %>'; + } else { + total_el.innerHTML = + 'Total ' + + totalrows + + ' <% PL($opt{name_singular} || 'customer') %>'; + } + } -<% include('/elements/xmlhttp.html', - 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi', - 'subs' => [qw( custnum_search smart_search )], - ) -%> + var total_el, rownum, totalrows, allrows; + + function addDeleteButton (searchrow) { + var td_delete = document.getElementById('delete'+searchrow); + var button_delete = document.createElement('INPUT'); + button_delete.setAttribute('rownum', searchrow); + button_delete.setAttribute('type', 'button'); + button_delete.setAttribute('value', 'X'); + button_delete.onclick = deleteRow; + button_delete.style.color = '#ff0000'; + button_delete.style.fontWeight = 'bold'; + button_delete.style.paddingLeft = '2px'; + button_delete.style.paddingRight = '2px'; + td_delete.appendChild(button_delete); + } - + + + + + + + + + +% foreach my $header ( @{$opt{header}} ) { + +% } + + +% my @rownums = sort { $a <=> $b } map /^custnum(\d+)$/, keys %$param; + + +% my $col = 0; +% foreach my $footer ( @{$opt{footer}} ) { +% my $align = $align{ $opt{'footer_align'}->[$col] || 'c' }; +% if ($footer eq '_TOTAL' ) { +% my $id = $opt{'fields'}->[$col]; +% $id = ref($id) ? "column${col}_TOTAL" : "${id}_TOTAL"; + +% } else { + +% } +% $col++; +% } + + +
Inv #Cust #StatusCustomerBalance<% $header %>
+ Total <% @rownums || 0 %> + <% PL($opt{name_singular} || 'customer', ( @rownums || 0 ) ) %> +  <% sprintf('%.2f', $total[$col] ) %><% $footer %>
+ + +<% include('/elements/xmlhttp.html', + 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi', + 'subs' => [qw( custnum_search smart_search invnum_search )], + ) +%> + <%init> my(%opt) = @_; +my $conf = new FS::Conf; +my $date_format = $conf->config('date_format') || '%m/%d/%Y'; -$opt{prefix} = '' unless defined $opt{prefix}; -$opt{prefix} .= '_' if $opt{prefix}; - -my $types = $opt{'types'} ? [ @{$opt{'types'}} ] : []; -my $sizes = $opt{'sizes'} ? [ @{$opt{'sizes'}} ] : []; +my $types = $opt{'type'} ? [ @{$opt{'type'}} ] : []; +my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; my $param = $opt{param}; $param = $cgi->Vars if $cgi->param('error'); +$opt{$_} ||= [] foreach qw(align color footer footer_align); + +my @total = map 0, @{$opt{footer}}; + +my %align = ( + 'l' => 'left', + 'r' => 'right', + 'c' => 'center', +); + +my $money_char = $conf->config('money_char') || '$';