Forums

Creating a Line Total in a Repeater Area

tshirley 02 Jan, 2019
Hi there,

I am not very experienced with Javascript, and I am trying to create a function that will multiply two fields and place the result in a third field, within a Repeater area.

So I have a working Repeater Area with data loaded from array M[Name] and M[Price]. The other fields are M[Qty] (entered by the user) and M[LineTotal] (which I want to calculate). Field names in the repeater are:

M[{var:area_repeater1.key}][Name]
M[{var:area_repeater1.key}][Price]
M[{var:area_repeater1.key}][Qty]
M[{var:area_repeater1.key}][LineTotal]

When the user enters a Qty, I want the script to calculate a Line total by multiplying Price and Qty.

So I created a JS function like
function linetotal() {

var total = 0,
linetotal = 0
;
jQuery('input[name^="M"]').each(function() {
linetotal = $(this.Qty).val() * $(this.Price).val();
   jQuery($(this.LineTotal).val(linetotal));
total += parseFloat($(this.LineTotal).val());
});
jQuery('input[name="total_field"]').val(total);

}

I expect that my problem is in the syntax that references the array elements Qty and Price, but I can find no reference or example that shows how to do it.

Any assistance greatly appreciated as always.

Cheers

Tim
healyhatman 03 Jan, 2019
If you console.dir the selections generated by jQuery('input[name^="M"]') I think you might find it's an array of every field starting with M. I think that might be the problem but dunno.
tshirley 03 Jan, 2019
Thank you,

Well I have tried many different ways ti do this now and searched a lot of sites, but nothing seems to work.

I think the basic problem is still how to reference the array elements in JS. The array M exists in the "data" - I can see it in a debugger and it populates the Repeater fields named as indicated in the manual. I can execute a JS function on Change of the Qty field. If the field id wasn't an array I can use jQuery('#Qty').val() in JS. But how do I reference it when the field Id is Qty{var:area_repeater1.key} ?

I think this is mainly my lack of JS experience. I am more familiar with PHP and so this is a fairly new area for me.

Cheers

Tim
healyhatman 03 Jan, 2019
jQuery('*[id^="M"] [name$="Qty]"]')
Try that selector. Maybe. Note the extra square bracket.
tshirley 03 Jan, 2019
Not much luck with that syntax I'm afraid.

It is strange, this is the sort of process (Line Total = price * Quantity ) that I thought would be fairly straighforward CF6 functionality when a Repeater is used.

I will keep searching for a solution. I can get around it for now by calculating the total in page 2 of a multipage form.

Thanks for your help as always.

Tim
healyhatman 04 Jan, 2019
Here's one way.
1) Give all your fields the ID of fieldname{var:area_repeater#} and leave the name as you have it already.
2) Have a custom html block, containing for example TOTAL: <span id = "grandtotal"></span>
jQuery("input[id^='qty']").change(function(event) {
var index = this.id.substr(this.id.indexOf("qty") + 3);
var qty = parseInt(jQuery("#qty" + index).val());
var price = parseInt(jQuery("#price" + index).val());
jQuery("#total" + index).val((qty ? qty : 0) * (price ? price : 0));

var sum = 0;
jQuery("input[name*='total']").each(function() {
linetotal = parseInt(jQuery(this).val());
sum = sum + (linetotal ? linetotal : 0);
});

jQuery("#grandtotal").html("$" + sum);
});

Just to be clear though, you should ONLY be using this to DISPLAY a total to the user. You should ABSOLUTELY 100% NOT USE THIS CALCULATED TOTAL to do anything with, like decide how much a customer owes. Because if they're clever, they can just edit the values to make the total price $0.


You should instead calculate the total in the backend with PHP.
healyhatman 04 Jan, 2019
[file=11349]Repeater_04_Jan_2019_09_55_45.cf6bak[/file]
tshirley 05 Jan, 2019
Wow.. thank you so much both for the solution and the demo form.

A big job though, and one that obviously needed far more JS skills than I possess (I'm an old-school programmer, not a web developer) and even now I am not certain that I understand your code in every aspect.

What this does suggest to me is that what I thought would be routine, obviously isn't, so in CF6 I am probably better to solve the problem in another way. Clearly the repeater collects the data well, and what is probably best is to use a popup "shopping cart" form to show the user the items they have selected and the total cost.

Again many thanks for your support.

Cheers

Tim
This topic is locked and no more replies can be posted.