I have a table and I want to allow submitting the form if and only if the total of each row must be =100 not less nor more
and the total of each column must be <=100 and not more than 100
This is the old scenario each row and each column must be = 100.
Demo CODE:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
disableSave();
$(".sum").on("input", function() {
sumThisClass("1");
sumThisClass("2");
sumThisClass("3");
sumThisClass("4");
sumThisClass("5");
sumThisClass("6");
sumThisClass("7");
validateForm();
});
function validateForm() {
var hasError = $(".error").length > 0;
if (hasError) {
disableSave();
return;
}
var expectedTotal = $(".total").length * 100;
console.log(expectedTotal, getCurrentTotal());
if (expectedTotal == getCurrentTotal()) {
enableSave();
}
else {
disableSave();
}
}
function getCurrentTotal() {
var sumTotal = 0;
$(".total").each(function (index, el) {
var elValue = parseInt($(el).text());
if (!isNaN(elValue)) {
sumTotal += parseInt($(el).text());
}
});
return sumTotal;
}
function disableSave() {
$("#btn-save").prop("disabled", true);
}
function enableSave() {
$("#btn-save").prop("disabled", false);
}
function sumThisClass(className) {
var sumTotal = 0;
$("." + className).each(function(index, el) {
var elValue = parseInt($(el).val());
if (!isNaN(elValue)) {
sumTotal += parseInt($(el).val());
}
});
$(".sum-" + className).text(sumTotal);
if (sumTotal > 100) {
$(".sum-" + className).append("<div class='error'>cannot be greater than 100</div>");
}
}
});
</script>
<form action="test.php" method="post">
<table>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Total</td>
</tr>
<tr>
<td></td>
<td>
<input type="number" class="sum 1 5" min="0" max="100">
</td>
<td>
<input type="number" class="sum 1 6" min="0" max="100">
</td>
<td>
<input type="number" class="sum 1 7" min="0" max="100">
</td>
<td class="total sum-1"></td>
</tr>
<tr>
<td></td>
<td>
<input type="number" class="sum 2 5" min="0" max="100">
</td>
<td>
<input type="number" class="sum 2 6" min="0" max="100">
</td>
<td>
<input type="number" class="sum 2 7" min="0" max="100">
</td>
<td class="total sum-2"></td>
</tr>
<tr>
<td>TOTAL</td>
<td class="total sum-5"></td>
<td class="total sum-6"></td>
<td class="total sum-7"></td>
</tr>
</table>
<input type="submit" name="save" value="SAVE" id="btn-save"/>
Demo Link
I tried to change it but I couldn't succeed.
var isvalid=true;
$( document ).ready(function() {
$("#test").prop("disabled",true);
$(".tabbody input[type=number]").blur(function(){
validateSubmit();
});
});
function validateSubmit()
{
var retval = sumRowVals();
$("#test").prop("disabled",!retval);
$("#msgdiv").html(retval ? "":"Invalid inputs!!!");
}
function sumRowVals()
{
isvalid=true;
resetFigs();
var rindx=1;
$(".tabbody tr").each(function(){
var temp=0;
var cindx=1;
$("input[type=number]",this).each(function(){
var elval = !isNaN($(this).val()) ? parseInt($(this).val()):0;
var sumcol = $("#ccol"+cindx);
$(sumcol).html(parseInt($(sumcol).html())+elval);
temp=temp+elval;
cindx++;
if(elval > 100){isvalid=false;}
if(parseInt($(sumcol).html()) > 100){isvalid=false;}
});
if(rindx != $('.tabbody tr').length)
{
if(temp != 100){isvalid=false;}
$("#rcol"+rindx).html(temp);
}
rindx++;
});
return isvalid;
}
function resetFigs()
{
$('*[id*=ccol]').each(function() {
$(this).html("0");
});
}
function SubmitForm()
{
// your form submit code
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="js/jquery2.0.2.min.js"></script>
</head>
<body>
<table border=1 cellpadding="5">
<tbody class='tabbody'>
<tr>
<td><input type="number" id="col1" min="0" max="100"></td>
<td><input type="number" id="col2" min="0" max="100"></td>
<td><input type="number" id="col3" min="0" max="100"></td>
<td id="rcol1"></td>
</tr>
<tr>
<td><input type="number" id="col1" min="0" max="100"></td>
<td><input type="number" id="col2" min="0" max="100"></td>
<td><input type="number" id="col3" min="0" max="100"></td>
<td id="rcol2"></td>
</tr>
<tr>
<td id="ccol1"></td>
<td id="ccol2"></td>
<td id="ccol3"></td>
<td>
<input type="button" name="test" id="test" value="Save" onclick="SubmitForm()" />
</td>
</tr>
</tbody>
</table>
<div id="msgdiv" style="color:red;line-height:30px"></div>
</body>
</html>
This is a rough idea:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="js/jquery2.0.2.min.js"></script>
<script>
var isvalid=true;
$( document ).ready(function() {
$("#test").prop("disabled",true);
$(".tabbody input[type=number]").blur(function(){
validateSubmit();
});
});
function validateSubmit()
{
var retval = sumRowVals();
$("#test").prop("disabled",!retval);
$("#msgdiv").html(retval ? "":"Invalid inputs!!!");
}
function sumRowVals()
{
isvalid=true;
resetFigs();
var rindx=1;
$(".tabbody tr").each(function(){
var temp=0;
var cindx=1;
$("input[type=number]",this).each(function(){
var elval = !isNaN($(this).val()) ? parseInt($(this).val()):0;
var sumcol = $("#ccol"+cindx);
$(sumcol).html(parseInt($(sumcol).html())+elval);
temp=temp+elval;
cindx++;
if(elval > 100){isvalid=false;}
if(parseInt($(sumcol).html()) > 100){isvalid=false;}
});
if(rindx != $('.tabbody tr').length)
{
if(temp != 100){isvalid=false;}
$("#rcol"+rindx).html(temp);
}
rindx++;
});
return isvalid;
}
function resetFigs()
{
$('*[id*=ccol]').each(function() {
$(this).html("0");
});
}
function SubmitForm()
{
// your form submit code
}
</script>
</head>
<body>
<table border=1 cellpadding="5">
<tbody class='tabbody'>
<tr>
<td><input type="number" id="col1" min="0" max="100"></td>
<td><input type="number" id="col2" min="0" max="100"></td>
<td><input type="number" id="col3" min="0" max="100"></td>
<td id="rcol1"></td>
</tr>
<tr>
<td><input type="number" id="col1" min="0" max="100"></td>
<td><input type="number" id="col2" min="0" max="100"></td>
<td><input type="number" id="col3" min="0" max="100"></td>
<td id="rcol2"></td>
</tr>
<tr>
<td id="ccol1"></td>
<td id="ccol2"></td>
<td id="ccol3"></td>
<td>
<input type="button" name="test" id="test" value="Save" onclick="SubmitForm()" />
</td>
</tr>
</tbody>
</table>
<div id="msgdiv" style="color:red;line-height:30px"></div>
</body>
</html>
Hope it's gonna work for you
$(document).ready(function(){
disableSave();
$(".sum").on("input", function() {
sumThisClass("1");
sumThisClass("2");
sumThisClass("3");
sumThisClass("4");
sumThisClass("5");
sumThisClass("6");
sumThisClass("7");
validateForm();
});
function validateForm() {
var hasError = $(".error").length > 0;
if (hasError) {
disableSave();
return;
}
if( tmp['sum_1'] <= 100 &&
tmp['sum_2'] <= 100 &&
tmp['sum_5'] <= 100 &&
tmp['sum_6'] <= 100 &&
tmp['sum_7'] <= 100) {
enableSave();
} else {
disableSave();
}
}
function getCurrentTotal() {
var sumTotal = 0;
$(".total").each(function (index, el) {
var elValue = parseInt($(el).text());
if (!isNaN(elValue)) {
sumTotal += parseInt($(el).text());
}
});
return sumTotal;
}
function disableSave() {
$("#btn-save").prop("disabled", true);
}
function enableSave() {
$("#btn-save").prop("disabled", false);
}
var tmp = {
sum_1:null,
sum_2:null,
sum_5:null,
sum_6:null,
sum_7:null
};
function sumThisClass(className) {
var sumTotal = 0;
$("." + className).each(function(index, el) {
var elValue = parseInt($(el).val());
if (!isNaN(elValue)) {
sumTotal += parseInt($(el).val());
}
});
$(".sum-" + className).text(sumTotal);
if (sumTotal > 100) {
$(".sum-" + className).append("<div class='error'>cannot be greater than 100</div>");
}
tmp['sum_'+className] = sumTotal;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form action="test.php" method="post">
<table>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Total</td>
</tr>
<tr>
<td></td>
<td>
<input type="number" class="sum 1 5" min="0" max="100">
</td>
<td>
<input type="number" class="sum 1 6" min="0" max="100">
</td>
<td>
<input type="number" class="sum 1 7" min="0" max="100">
</td>
<td class="total sum-1"></td>
</tr>
<tr>
<td></td>
<td>
<input type="number" class="sum 2 5" min="0" max="100">
</td>
<td>
<input type="number" class="sum 2 6" min="0" max="100">
</td>
<td>
<input type="number" class="sum 2 7" min="0" max="100">
</td>
<td class="total sum-2"></td>
</tr>
<tr>
<td>TOTAL</td>
<td class="total sum-5"></td>
<td class="total sum-6"></td>
<td class="total sum-7"></td>
</tr>
</table>
<input type="submit" name="save" value="SAVE" id="btn-save"/>
you will change the old condition by this:
if( tmp['sum_1'] == 100 &&
tmp['sum_2'] == 100 &&
tmp['sum_5'] <= 100 &&
tmp['sum_6'] <= 100 &&
tmp['sum_7'] <= 100) {
enableSave();
} else {
disableSave();
}
my code looks dirty, but i just want you to know what exactly i did in each line.
btw, you can try this
$(function(){
$('.btn-create').click(function(){
var col = parseInt($('.count-column').val());
var row = parseInt($('.count-row').val());
$('table').html('');
var head='<thead><tr><th></th>';
var foot='<tfoot><tr><th>TOTAL ROW</th>';
var tr = '';
for(a=0; a< row;a++){
tr += '<tr><td>row '+a+'</td>';
for(b=0; b< col;b++){
tr +='<td><input type="number" class="sum error-row" data-row="'+a+'" data-col="'+b+'" min="0" value="0" max="100"></td>';//all must have error row to prevent 0 0 0 0
if(a==0) {foot +='<th class="total sumcol-'+b+'">0</th>';
head +='<th>col '+b+'</th>';}
}
tr +='<td class="total sumrow-'+a+'">0</td>';
tr +='</tr>';
}
head +='<th>TOTAL COL</th></tr></thead>';
foot +='<th class=""><input type="submit" name="save" value="SAVE" disabled id="btn-save"/></th></tr></tfoot>';
$('table').append(head+tr+foot);
$('#btn-save').prop('disabled', true);
});
$("body").on('click', 'input[type="number"]',function () {
$(this).select();
});
$('.btn-show').click(function(){
console.log($('table').html());
})
$("table").on("change", '.sum', function() {
var val = parseInt($(this).val());
if(isNaN(val)) val= 0;
$(this).val(val); //parse int here, so you dont need parse all of them again
var col = $(this).data('col');
var row = $(this).data('row');
//count row
var rows = $('.sum[data-row="'+row+'"]');
var total = 0;
$.each(rows, function(i,e){
total += parseInt($(this).val());
});
$('.sumrow-'+row).text(total);
if(total == 100) rows.removeClass('error-row');
else{
rows.addClass('error-row');
}
//count col
var cols = $('.sum[data-col="'+col+'"]');
var total = 0;
$.each(cols, function(i,e){
total += parseInt($(this).val());
});
$('.sumcol-'+col).text(total);
if(total <= 100) cols.removeClass('error-col');
else{
cols.addClass('error-col');
}
validate();
});
function validate(){
if($('.error-col, .error-row').length > 0) $('#btn-save').prop('disabled', true);
else $('#btn-save').prop('disabled', false);
}
});
.error-row, .error-col{border: 1px solid red;}
table tfoot tr th:not(:first-child){font-weight: 400;}
how many rows x column <input type="number" min="1" value="2" class="count-row"> X <input min="1" value="3" type="number" class="count-column"> <button class="btn-create">create</button> <button class="btn-show">show DOM</button>
<form action="test.php" method="post">
<table></table>
</form>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
In this demo HTMLFormControlsCollection was used because it makes dealing with form controls easier with it's terse compact syntax. Added <output>
tags to each total cells. All <input>
s and <output>
s have an id that's associated with it's cell (<td>
).
Details are commented in Demo
Demo
/* Using old school HTMLFormControlsCollection */
// Reference the first (and only) form */
var f0 = document.forms[0];
// Collection of ALL form controls of f0
var F = f0.elements;
/* Handle any input events on f0 by calling
|| callback function tableCalc()
*/
f0.oninput = tableCalc;
function tableCalc(e) {
/* if the element receiving any user input (e.target)
|| is NOT the element that listens for input event
|| (e.currentTarget or f0) then...
*/
if (e.target !== e.currentTarget) {
/* Get e.target's id and determine the associated
|| outputs by e.target's id.
*/ // Example for <input id='r1c2'>
// 'r1c2'
var RC = e.target.id;
// '1'
var row = RC.charAt(1);
// '2'
var col = RC.charAt(3);
// 'R1'
var R = 'R' + row;
// 'C2'
var C = 'C' + col;
/* Calculate the sums for each row */
F[R].value = F['r' + row + 'c0'].valueAsNumber + F['r' + row + 'c1'].valueAsNumber + F['r' + row + 'c2'].valueAsNumber;
/* Calculate the sums for each col */
F[C].value = F['r0c' + col].valueAsNumber + F['r1c' + col].valueAsNumber;
}
/* if both rows === 100 AND none of the col exceed 100
|| enable the button
*/
if (Number(F.R0.value) === 100 && Number(F.R1.value) === 100 && Number(F.C0.value) < 101 && Number(F.C1.value < 101) && Number(F.C2.value) < 101) {
F.b0.disabled = false;
// Otherwise the button is disabled
} else {
F.b0.disabled = true;
}
/* Collect all output tags into a NodeList then
|| convert it into an array
*/
var totals = Array.from(document.querySelectorAll('output'));
// Run totals array through map() on each output...
totals.map(function(out, idx, totals) {
/* Get the associated error cell by matching
|| output.id to td.className
*/
var msg = document.querySelector('.' + out.id);
// Get output's value
var val = Number(out.value);
// if it exceeds 100...
if (val > 100) {
// Display message in associated error cell
msg.textContent = `Exceeds 100`;
out.style.color = 'red';
out.style.textAlign = 'center';
// Otherwise clear the error
} else {
msg.textContent = '';
out.style.color = 'black';
out.style.textAlign = 'right';
}
});
}
input,
output {
display: inline-block;
font: inherit;
text-align: right
}
output {
width: 7ch
}
button {
font: inherit
}
td {
max-width: 8ch;
}
.error {
color: red;
text-align: center
}
<form id='F0'>
<table id='T0'>
<thead>
<tr>
<th>C0</th>
<th>C1</th>
<th>C2</th>
<th>Total</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input id='r0c0' type='number' min='0' max='100' value='0'>
</td>
<td>
<input id='r0c1' type='number' min='0' max='100' value='0'>
</td>
<td>
<input id='r0c2' type='number' min='0' max='100' value='0'>
</td>
<td>
<!--Row 1 total-->
<output id='R0' for='r0c0 r0c1 r0c2'>0</output>
</td>
<!--Row 1 error cell-->
<td class='R0 error' style='max-width:12ch'></td>
</tr>
<tr>
<td>
<input id='r1c0' type='number' min='0' max='100' value='0'>
</td>
<td>
<input id='r1c1' type='number' min='0' max='100' value='0'>
</td>
<td>
<input id='r1c2' type='number' min='0' max='100' value='0'>
</td>
<td>
<!--Row 2 total-->
<output id='R1' for='r1c0 r1c1 r1c2'>0</output>
</td>
<!--Row 2 error cell-->
<td class='R1 error' style='max-width:12ch'></td>
</tr>
<tr>
<td>
<!--Column totals-->
<output id='C0' for='r0c0 r1c0'>0</output>
</td>
<td>
<output id='C1' for='r0c1 r1c1'>0</output>
</td>
<td>
<output id='C2' for='r0c2 r1c2'>0</output>
</td>
<td>
<!--Placed button here so it doesn't shift-->
<button id='b0' disabled>SAVE</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<!--Error cells for column totals-->
<td class='C0 error'></td>
<td class='C1 error'></td>
<td class='C2 error'></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
</form>