Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

This works but is clumsy

Status
Not open for further replies.

struth

Programmer
Aug 26, 2001
114
0
0
GB
Looks like a soduku but it's not! I have 8 sections made up with tables of 7 rows and three (sometimes four) columns. Each row is totalled up as is each column. The script below works but is going to end up very long. Is there a way to condense itthat would still work if even if more columns/rows were added to a section as long as the relevant textfields were named something like S1_R2_C1 (SECTION 1, ROW2, COLUMN 1)?

The table looks like this

SECTION 1

C1 C2 C3
---+---+---+
R1 6 1 4 = 11
---+---+---+
R2 3 1 4 = 8
---+---+---+
R3 2 7 1 = 10
---+---+---+

11 9 9 29 (COLUMN TOTALS)

SECTION 2 ETC

<script language="JavaScript">

// ROWS ARRAYS SECTION 1
A_S1_R1 = new Array(
"S1_R1_C1",
"S1_R1_C2",
"S1_R1_C3"
);
A_S1_R2 = new Array(
"S1_R2_C1",
"S1_R2_C2",
"S1_R2_C3"
);
A_S1_R3 = new Array(
"S1_R3_C1",
"S1_R3_C2",
"S1_R3_C3"
);
// COLUMNS ARRAYS
A_S1_C1 = new Array(
"S1_R1_C1",
"S1_R2_C1",
"S1_R3_C1"
);

A_S1_C2 = new Array(
"S1_R1_C2",
"S1_R2_C2",
"S1_R3_C2"
);

A_S1_C3 = new Array(
"S1_R1_C3",
"S1_R2_C3",
"S1_R3_C3"
);
// SECTION2
A_S2_R1 = new Array(
"S1_R1_C1",
"S1_R1_C2",
"S1_R1_C3"
);
A_S2_R2 = new Array(
"S1_R2_C1",
"S1_R2_C2",
"S1_R2_C3"
);
A_S2_R3 = new Array(
"S1_R3_C1",
"S1_R3_C2",
"S1_R3_C3"
);


A_S2_C1 = new Array(
"S2_R1_C1",
"S2_R2_C1",
"S2_R3_C1"
);

A_S2_C2 = new Array(
"S2_R1_C2",
"S2_R2_C2",
"S2_R3_C2"
);

A_S2_C3 = new Array(
"S2_R1_C3",
"S2_R2_C3",
"S2_R3_C3"
);



function sumSection(theForm) {

// SUM ROWS ARRAYS
var S1_R1 = sum(A_S1_R1,theForm);
var S1_R2 = sum(A_S1_R2,theForm);
var S1_R3 = sum(A_S1_R3,theForm);
// SUM COLUMNS ARRAYS
var S1_C1 = sum(A_S1_C1,theForm);
var S1_C2 = sum(A_S1_C2,theForm);
var S1_C3 = sum(A_S1_C3,theForm);

// SECTION 2
var S2_R1 = sum(A_S2_R1,theForm);
var S2_R2 = sum(A_S2_R2,theForm);
var S2_R3 = sum(A_S2_R3,theForm);

var S2_C1 = sum(A_S2_C1,theForm);
var S2_C2 = sum(A_S2_C2,theForm);
var S2_C3 = sum(A_S2_C3,theForm);

//GET ROW TOTALS
theForm.elements['S1_R1_TOTAL'].value=S1_R1;
theForm.elements['S1_R2_TOTAL'].value=S1_R2;
theForm.elements['S1_R3_TOTAL'].value=S1_R3;
//GET COLUMN TOTALS
theForm.elements['S1_C1_TOTAL'].value=S1_C1;
theForm.elements['S1_C2_TOTAL'].value=S1_C2;
theForm.elements['S1_C3_TOTAL'].value=S1_C3;

theForm.elements['S1_TOTAL'].value=S1_R1 + S1_R2 + S1_R3;

//SECTION 2
theForm.elements['S2_R1_TOTAL'].value=S2_R1;
theForm.elements['S2_R2_TOTAL'].value=S2_R2;
theForm.elements['S2_R3_TOTAL'].value=S2_R3;

theForm.elements['S2_C1_TOTAL'].value=S2_C1;
theForm.elements['S2_C2_TOTAL'].value=S2_C2;
theForm.elements['S2_C3_TOTAL'].value=S2_C3;

theForm.elements['S2_TOTAL'].value=S2_R1 + S2_R2 + S2_R3;

}

function sum(list,theForm) {
var total=0;
var val=0;
for (i=0;i<list.length;i++) {
val = theForm.elements[list].value;
if (val=='') val=0;
else val=parseInt(val);
if (isNaN(val)) {
alert('Please enter a valid number');
theForm.elements[list].focus();
return 0;
}
total += val;
}
return total;
}

</script>

Away from the actual ... everything is virtual
 
here's a quick script i threw together. you can tweak it to better meet your needs:

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[/URL]

<html>
<head>
<title>Untitled</title>

<script type="text/javascript"><!--

function updateTotals( srcObj ) {
    var r, c, rc, val, f, rt, ct, gt;
    
    f = srcObj.form;
    rc = srcObj.name.split(/[a-z]/);
    
    r = (rc[0].length == 0) ? rc[1] : rc[0];
    c = (rc[0].length == 0) ? rc[2] : rc[1];    
    
    rt = f.elements['r' + r + 'total'].value;
    rt = (rt.length > 0) ? parseInt(rt) : 0;
    
    ct = f.elements['c' + c + 'total'].value;
    ct = (ct.length > 0) ? parseInt(ct) : 0;
    
    gt = f.elements['grandtotal'].value;
    gt = (gt.length > 0) ? parseInt(gt) : 0;   
    
    val = parseInt( srcObj.value );
    
    f.elements['r' + r + 'total'].value = val + rt;
    f.elements['c' + c + 'total'].value = val + ct;
    f.elements['grandtotal'].value = val + gt;
}

//--></script>

</head>

<body>

<form name="myForm">
<table style="border: 1px dotted gray;"><tr>
    <th></th>
    <th>Col 1</th>
    <th>Col 2</th>
    <th>Col 3</th>
    <th>Total</th>
</tr><tr>
    <td>Row 1</td>
    <td><input type="text" name="r1c1" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r1c2" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r1c3" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r1total" readonly="readonly" /></td>
</tr><tr>
    <td>Row 2</td>
    <td><input type="text" name="r2c1" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r2c2" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r2c3" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r2total" readonly="readonly" /></td>
</tr><tr>
    <td>Row 3</td>
    <td><input type="text" name="r3c1" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r3c2" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r3c3" onchange="updateTotals(this);" /></td>
    <td><input type="text" name="r3total" readonly="readonly" /></td>
</tr><tr>
    <td><strong>Total</strong></td>
    <td><input type="text" name="c1total" readonly="readonly" /></td>
    <td><input type="text" name="c2total" readonly="readonly" /></td>
    <td><input type="text" name="c3total" readonly="readonly" /></td>
    <td><input type="text" name="grandtotal" readonly="readonly" /></td>
</tr></table>
</form>

</body>
</html>

*cLFlaVA
----------------------------
[tt]your mom goes to college[/tt]
[URL unfurl="true"]http://www.coryarthus.com/[/url]
[banghead]
 
This should do it:
Code:
<script>
var version=0, hasErrors;
function [b]getTotals()[/b]{
  version++;
  hasErrors = false;
  var f = document.formName;
  for(var i=0; i<f.elements.length;i++){
    var el = f.elements[i];
    if(el.type=='text' && el.name.indexOf("TOTAL")==-1){
      var section = el.name.match(/^[^_]*/)[0];
      var row = el.name.match(/_[^_]*/)[0].substring(1);
      var col = el.name.match(/[^_]*$/)[0];
      setValue(el,f[section+'_'+row+'_TOTAL'],version); [green]// Row total[/green]
      setValue(el,f[section+'_'+col+'_TOTAL'],version); [green]// Section column total[/green]
      setValue(el,f[section+'_TOTAL'],version);         [green]// Section total[/green]

      [green]/* If you have column totals across sections
         and a grand total, you can uncomment this.
      setValue(el,f[col+'_TOTAL'],version);             // Grand column total
      setValue(el,f['TOTAL'],version);                  // Grand total
      */[/green]

    }
  }
  if(hasErrors){
    alert('Please enter valid numbers in the red boxes');
  }
}
function setValue(cellBox,totalBox,version){
  cellBox.style.backgroundColor = '';
  if(isNaN(cellBox.value)){
    cellBox.style.backgroundColor = 'red';
    hasErrors = true;
  }else if(isNaN(totalBox.value) || totalBox.version!=version){
    totalBox.value = cellBox.value;
    totalBox.version = version;
  }else{
    totalBox.value = (totalBox.value-0) + (cellBox.value-0);
  }
}
</script>

Adam
 
Hmm, I guess we should have asked when you need the values totaled. If the user will be entering new values on a blank screen (or with the values already totaled on the server-side), cLFlaVA's script would be better. If you need to sum the values as soon as the page loads, mine would work better for that.

Adam
 
Many thanks cLFlaVA and adam0101. Great stuff. Again you were right adam0101, cLFlaVA's script suited my needs better this time but I have been taking both scripts apart to learn a bit more about how it all fits together.

I must explore regex more ...

thanks again

Struth

Away from the actual ... everything is virtual
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top