Public
Snippet $440 authored by Jérome Perrin

Dynamic totals in matrixbox

matrixbox_totals.js
Raw
/**
 * This is an old hack from "erp5_popup_ui" time so that matrixbox displays a total line/column.
 */


var sRegExp = new RegExp('(-?[0-9]+)([0-9]{3})');
function format(num) {
  // format a number to string, only 1 234 format is supported.
  num = num.toString()

  while(sRegExp.test(num)) {
     num = num.replace(sRegExp, '$1 $2');
  }
  return num;
}

function parse(str) {
  // parse a string to a number
  // \s is for opera, others are for chrome / firefox
  return parseFloat(
      str.replace(/\s/g, "")
         .replace(/ /g, "")
         .replace(/ /g, "")
      )
}

/* matrixbox sums */
// XXX must also add a class to the matrixbox, not to apply on all mb
if ($(".MatrixBoxSumColumn").length == 0 ) {
  $(".MatrixContent").each(function(idx, element) {
     var matrixbox = $(element)

      // initialise:
      
      nb_columns = matrixbox.find("tr:first td").length
      // add td for summary column (only if having more than one column)
      if (nb_columns > 2) {
        $('<td style="text-align: right"><span class="MatrixBoxSumColumn input figure" disabled="disabled"/></td>').appendTo(
          matrixbox.find('tr.DataA, tr.DataB')
        )
        $('<td/>').appendTo(matrixbox.find('tr.matrixbox_label_line'))
      }
      // add tr for summary line (only if having more than one line)
      if (matrixbox.find("tr.DataA, tr.DataB").length > 1) {
        var last_line = matrixbox.find('tr:last')
        var sumline = $('<tr class="MatrixBoxSumLine" style="border-top: 1px solid #3D6474"/>').insertBefore(last_line)
        // add as many td in the summary line
        $('<td class="Data footer"/>').appendTo(sumline) // ( + 1 for the title column )
        // once again, if we only have one column, we do not add a summary
        // column
        for (i=0; i< (nb_columns == 2 ? 1 : nb_columns); i++) {
          $('<td class="Data footer" style="text-align: right"><span class="input figure"></span></td>').appendTo(sumline)
        }
      }

  function recalculateSumColumn(idx, element) {
    // recalculates the value of a sum column. `element` must be the td with class
    // .MatrixBoxSumColumn
    var me = jQuery(element);
    
    var sum = 0;
    inputs = me.parent().siblings().find('.figure');
    for (i=0; i<inputs.length; i++) {
      var input = inputs[i];
      if (typeof input.value != "undefined") {
        v = parse(input.value)
      } else {
        v = parse(input.innerHTML)
      }
      if (v) { sum += v }
    }
    me.text(format(sum));
  }

  function recalculateSumLine(idx, element) {
    // recalculates the sum line. `element` must be the tr with class
    // .MatrixBoxSumLine
    jQuery(element).find('span.input').each(function(idx, element){
      var sum=0,
      inputs = matrixbox.find('tr').find('td:eq(' + (idx+1) + ') .figure')
      for (i=0; i<inputs.length-1; i++) {
        var input = inputs[i]
        if (typeof input.value != "undefined") {
          v = parse(input.value)
        } else {
          v = parse(input.innerHTML)
        }
        if (v) { sum += v }
      }
      jQuery(element).text(format(sum))
    })
  }

  function recalculateMatrixSumContent() {
    // recalculates a matrixbox sum. Self must be the <div class="MatrixContent">
    // surrounding the table.
    // XXX matrixbox is from outer scope
    matrixbox.find('.MatrixBoxSumColumn').each(recalculateSumColumn);
    matrixbox.find('.MatrixBoxSumLine').each(recalculateSumLine);
  }

  recalculateMatrixSumContent();
  matrixbox.find('input').change(recalculateMatrixSumContent);

  })
}
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!