While working on a client site utilizing Gravity Forms, I found myself wanting to use the aesthetic of the advanced list Gravity provides, but needed a bit more arithmetic firepower (read: any, arithmetic firepower; gravity doesn't enable calculations on their advanced list field without a plugin).
I found this: Which got me close to what I was after, but I also needed to do some pre-calculations within each row. That is, given I have cells A, B, C, and D. I needed to do math on A and B, and then store it in C. Then, I needed to find the sum of all C cells in all rows.
First the starting code:
// ************ Gravity Forms Dynamic List Summation ************** //
//EX: listFieldColumnTotal( 140, 1, 3, 3, true );
//The elements are described in the function, but are described in order as follows:
//
//The Form ID (ex. gform_wrapper_6)
//The list container's ID (ex. #field_6_7)
//The column item which we want to use as the dynamic value which lives beneath the list container
// (ex. .gfield_list_7_cell2)
//The id of the result input's container (ex. field_6_18)
//defines whether or not we're using a currency (I didn't experiment with this value set to "false",
// but I imagine it works the same
jQuery(document).ready(function(){
function calculateLFColumnTotal(formId, columnClass, totalFieldId, currency) {
var columnTotal = 0,
preField = '#field_' + formId + '_' + totalFieldId,
totalField = jQuery('#input_' + formId + '_' + totalFieldId),
cellValue;
currency = (currency && typeof gf_global !== 'undefined');
jQuery(columnClass).each(function () {
cellValue = jQuery(this).val();
cellValue = (currency) ? gformToNumber(cellValue) : cellValue;
columnTotal += parseFloat(cellValue) || 0;
});
if (jQuery(preField).hasClass('gfield_price')) {
columnTotal = gformFormatMoney(columnTotal);
if (jQuery(preField + ' input').length > 1) {
totalField.html(columnTotal);
totalField = jQuery('input[name="input_' + totalFieldId + '.2"]');
}
} else {
columnTotal = (currency) ? gformFormatMoney(columnTotal) : columnTotal;
}
totalField.val(columnTotal);
gformCalculateTotalPrice(formId);
}
function listFieldColumnTotal(formId, fieldId, column, totalFieldId, currency) {
var listField = '#field_' + formId + '_' + fieldId,
columnClass = '.gfield_list_' + fieldId + '_cell' + column + ' input';
jQuery(listField).on('focusout', columnClass, function () {
if (currency && typeof gf_global !== 'undefined') {
gformFormatPricingField(this);
}
calculateLFColumnTotal(formId, columnClass, totalFieldId, currency);
});
jQuery(listField).on('click', '.add_list_item', function () {
jQuery(listField + ' .delete_list_item').removeProp('onclick');
});
jQuery(listField).on('click', '.delete_list_item', function () {
gformDeleteListItem(this, 0);
calculateLFColumnTotal(formId, columnClass, totalFieldId, currency);
});
}
listFieldColumnTotal( 6, 120, 3, 47, true );
});
While working on a client site utilizing Gravity Forms, I found myself wanting to use the aesthetic of the advanced list Gravity provides, but needed a bit more arithmetic firepower (read: any, arithmetic firepower; gravity doesn't enable calculations on their advanced list field without a plugin).
I found this: https://stackoverflow/questions/35872452/gravity-forms-find-sum-of-list-column Which got me close to what I was after, but I also needed to do some pre-calculations within each row. That is, given I have cells A, B, C, and D. I needed to do math on A and B, and then store it in C. Then, I needed to find the sum of all C cells in all rows.
First the starting code:
// ************ Gravity Forms Dynamic List Summation ************** //
//EX: listFieldColumnTotal( 140, 1, 3, 3, true );
//The elements are described in the function, but are described in order as follows:
//
//The Form ID (ex. gform_wrapper_6)
//The list container's ID (ex. #field_6_7)
//The column item which we want to use as the dynamic value which lives beneath the list container
// (ex. .gfield_list_7_cell2)
//The id of the result input's container (ex. field_6_18)
//defines whether or not we're using a currency (I didn't experiment with this value set to "false",
// but I imagine it works the same
jQuery(document).ready(function(){
function calculateLFColumnTotal(formId, columnClass, totalFieldId, currency) {
var columnTotal = 0,
preField = '#field_' + formId + '_' + totalFieldId,
totalField = jQuery('#input_' + formId + '_' + totalFieldId),
cellValue;
currency = (currency && typeof gf_global !== 'undefined');
jQuery(columnClass).each(function () {
cellValue = jQuery(this).val();
cellValue = (currency) ? gformToNumber(cellValue) : cellValue;
columnTotal += parseFloat(cellValue) || 0;
});
if (jQuery(preField).hasClass('gfield_price')) {
columnTotal = gformFormatMoney(columnTotal);
if (jQuery(preField + ' input').length > 1) {
totalField.html(columnTotal);
totalField = jQuery('input[name="input_' + totalFieldId + '.2"]');
}
} else {
columnTotal = (currency) ? gformFormatMoney(columnTotal) : columnTotal;
}
totalField.val(columnTotal);
gformCalculateTotalPrice(formId);
}
function listFieldColumnTotal(formId, fieldId, column, totalFieldId, currency) {
var listField = '#field_' + formId + '_' + fieldId,
columnClass = '.gfield_list_' + fieldId + '_cell' + column + ' input';
jQuery(listField).on('focusout', columnClass, function () {
if (currency && typeof gf_global !== 'undefined') {
gformFormatPricingField(this);
}
calculateLFColumnTotal(formId, columnClass, totalFieldId, currency);
});
jQuery(listField).on('click', '.add_list_item', function () {
jQuery(listField + ' .delete_list_item').removeProp('onclick');
});
jQuery(listField).on('click', '.delete_list_item', function () {
gformDeleteListItem(this, 0);
calculateLFColumnTotal(formId, columnClass, totalFieldId, currency);
});
}
listFieldColumnTotal( 6, 120, 3, 47, true );
});
Share
Improve this question
asked Jun 27, 2020 at 6:40
sacredfaithsacredfaith
1114 bronze badges
1 Answer
Reset to default 0And now for the final, largely untested, code. In the end I wasn't sure which operations I'd need to be doing and so wanted to expand the functionality for whatever my client might throw at me in the future. I just got so excited that the ['*','+'] case worked after two days of trying to figure this out, I wanted to share it in hopes it might help someone else.
// ************ Gravity Forms Dynamic List Calculations ************** //
//EX: listFieldColumnTotal( 6, 120, 2, 3, 4,'*', '+', 47, true );
//EX: listFieldColumnTotal( FormID, listContainerID, FirstRowOperand, SecondRowOperand, RowResult, RowOperator, ColumnOperator, ColumnOperatorFieldID, isCurrency );;
//The elements are described in the function, but are described in order as follows:
//
//Form ID (ex. gform_wrapper_6)
//ListContainerID (ex. #field_6_120)
//FirstRowOperand: The first column we want to do math with
//SecondRowOperand: The first column we want to do math with
//RowResult: The column we want to store the result of the: FirstRowOperand [RowOperator] SecondRowOperand
//RowOperator: '*','+','-','/'
//ColumnOperator: '*','+','-','/'
//ColumnOperatorFieldID (ex. .gfield_list_7_cell2): "Take all of the results stored in the RowResul fields and [ColumnOperator] them together and put the result here"
//defines whether or not we're using a currency (I didn't experiment with this value set to "false", but I imagine it works the same
jQuery(document).ready(function(){
function calculateLFColumnTotal(formId, columnClassA,columnClassB, columnClassResult, operatorAB,operatorR, totalFieldId, currency) {
var subTotal = 0,
columnTotal = 0,
preField = '#field_' + formId + '_' + totalFieldId,
totalField = jQuery('#input_' + formId + '_' + totalFieldId),
cellValue;
currency = (currency && typeof gf_global !== 'undefined');
//Go through and get all of the values from the first column
var listA = [];
jQuery(columnClassA).each(function () {
cellValueA = jQuery(this).val();
cellValueA = (currency) ? gformToNumber(cellValueA) : cellValueA;
listA.push(cellValueA);
});
//Go through and get all of the values from the second column
var listB = [];
jQuery(columnClassB).each(function () {
cellValueB = jQuery(this).val();
cellValueB = (currency) ? gformToNumber(cellValueB) : cellValueB;
listB.push(cellValueB);
});
//Do the appropriate arithmetic on first column and second column values
var i = 0;
jQuery(columnClassResult).each(function () {
switch(operatorAB){
case "*":
subTotal = parseFloat(listA[i]) * parseFloat(listB[i]);
break;
case "+":
subTotal = parseFloat(listA[i]) + parseFloat(listB[i]);
break;
case "-":
subTotal = parseFloat(listA[i]) - parseFloat(listB[i]);
break;
case "/":
subTotal = parseFloat(listA[i]) / parseFloat(listB[i]);
break;
default:
subTotal = parseFloat(listA[i]) + parseFloat(listB[i]);
break;
}
jQuery(this).val(subTotal);
i += 1;
});
//Do the appropriate arithmetic on all of the resulting values
jQuery(columnClassResult).each(function () {
cellValue = jQuery(this).val();
cellValue = (currency) ? gformToNumber(cellValue) : cellValue;
switch(operatorR){
case "*":
columnTotal *= parseFloat(cellValue) || 0;
break;
case "+":
columnTotal += parseFloat(cellValue) || 0;
break;
case "-":
columnTotal -= parseFloat(cellValue) || 0;
break;
case "/":
columnTotal /= parseFloat(cellValue) || 0;
break;
default:
columnTotal += parseFloat(cellValue) || 0;
break;
}
});
if (jQuery(preField).hasClass('gfield_price')) {
columnTotal = gformFormatMoney(columnTotal);
if (jQuery(preField + ' input').length > 1) {
totalField.html(columnTotal);
totalField = jQuery('input[name="input_' + totalFieldId + '.2"]');
}
} else {
columnTotal = (currency) ? gformFormatMoney(columnTotal) : columnTotal;
}
totalField.val(columnTotal);
gformCalculateTotalPrice(formId);
}
function listFieldColumnTotal(formId, fieldId, columnOperandA, columnOperandB, columnResult, operatorAB, operatorR, totalFieldId, currency) {
var listField = '#field_' + formId + '_' + fieldId,
columnClassA = '.gfield_list_' + fieldId + '_cell' + columnOperandA + ' input';
columnClassB = '.gfield_list_' + fieldId + '_cell' + columnOperandB + ' input';
columnClassResult = '.gfield_list_' + fieldId + '_cell' + columnResult + ' input';
jQuery(listField).on('focusout', columnClassA, function () {
if (currency && typeof gf_global !== 'undefined') {
gformFormatPricingField(this);
}
calculateLFColumnTotal(formId, columnClassA,columnClassB, columnClassResult, operatorAB,operatorR, totalFieldId, currency);
});
jQuery(listField).on('focusout',columnClassB, function () {
if (currency && typeof gf_global !== 'undefined') {
gformFormatPricingField(this);
}
calculateLFColumnTotal(formId, columnClassA,columnClassB, columnClassResult, operatorAB,operatorR, totalFieldId, currency);
});
jQuery(listField).on('focusout',columnClassResult, function () {
if (currency && typeof gf_global !== 'undefined') {
gformFormatPricingField(this);
}
calculateLFColumnTotal(formId, columnClassA,columnClassB, columnClassResult, operatorAB,operatorR, totalFieldId, currency);
});
jQuery(listField).on('click', '.add_list_item', function () {
jQuery(listField + ' .delete_list_item').removeProp('onclick');
});
jQuery(listField).on('click', '.delete_list_item', function () {
gformDeleteListItem(this, 0);
calculateLFColumnTotal(formId,columnClassA,columnClassB, columnClassResult, operatorAB, operatorR, totalFieldId, currency);
});
}
// **Edit this line to reflect your situation!
listFieldColumnTotal( 1, 22, 2, 3, 4,'*', '+', 50, true );
});