Populate Total on catalog item from multi row variable set from onChange NOT onSubmit

twooton
Giga Contributor

I have seen several posts about pulling variables from the catalog item fields into a Multi Row Variable Set, as well as adding a row into the MRVS with an onSubmit for totaling the rows. Neither of these is what I want to do as I need onChange timing. So here is the problem:

I can fire off an onChange catalog client script from the field(s) in the MRVS, and I can total the columns/rows in my script. What I can't seem to do is then to be able to access the fields on the catalog item to update with my total.

The goal here is to have a live total of the MRVS columns. One that changes anytime any value within the MRVS is changed. Now, I can add a totaled row at the end of the MRVS, however there is no way for me to mark it read only, or ensure the user filling out the form doesn't delete the totaled row. So data integrity is not possible.

This is form is not accessible in the portal, only in the UI, so UI widgets and Jelly are not an option. 

My thought was to have read only fields on the catalog item I populate with my onChange script totals. However if I am not able to get from the Variable Set to the catalog item fields, then this is a dead end as well. So does anyone have a suggestion on how to have live updating totals derived from a MRVS?

1 ACCEPTED SOLUTION

Michael Jones -
Giga Sage

So, to be clear, you are only worried about using this item in the UI, not in the Service Portal, correct? If I may be so bold as to suggest the following - acknowledging that this solution violates the best-practice avoidance of utilizing globals (window) and would not function in the Service Portal (only the UI - in fact throws an error in the portal). 

Create a string field on your catalog item, name it count, default value of 0. 

On Load set this field to Read Only. 

function onLoad() {
   g_form.setReadOnly('count', true);
}

Now, in your MRVS, in your On Change script, you need to either configure the form to display the Isolate script checkbox (or you can set this value via the list view). You need this to be False (unchecked). It is checked by default so you need to alter this!

Then, your script would look like this: 

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }

   //Type appropriate comment here, and begin script below
	
	var count = window.parent.g_form.getValue('count');
	count = count * 1;
	count++;
	window.parent.g_form.setValue('count', count);
	
   
}

And so....

find_real_file.png

find_real_file.png

find_real_file.png

find_real_file.png

Again, not a best-practice solution and not one that would be supported, but...it's functional. 

 

If this was helpful or correct, please be kind and remember to click appropriately!

Michael Jones - Proud member of the CloudPires team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

View solution in original post

3 REPLIES 3

Uncle Rob
Kilo Patron

I spent days on this with some of the best in the business.
I just don't think it can be done.

Michael Jones -
Giga Sage

So, to be clear, you are only worried about using this item in the UI, not in the Service Portal, correct? If I may be so bold as to suggest the following - acknowledging that this solution violates the best-practice avoidance of utilizing globals (window) and would not function in the Service Portal (only the UI - in fact throws an error in the portal). 

Create a string field on your catalog item, name it count, default value of 0. 

On Load set this field to Read Only. 

function onLoad() {
   g_form.setReadOnly('count', true);
}

Now, in your MRVS, in your On Change script, you need to either configure the form to display the Isolate script checkbox (or you can set this value via the list view). You need this to be False (unchecked). It is checked by default so you need to alter this!

Then, your script would look like this: 

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }

   //Type appropriate comment here, and begin script below
	
	var count = window.parent.g_form.getValue('count');
	count = count * 1;
	count++;
	window.parent.g_form.setValue('count', count);
	
   
}

And so....

find_real_file.png

find_real_file.png

find_real_file.png

find_real_file.png

Again, not a best-practice solution and not one that would be supported, but...it's functional. 

 

If this was helpful or correct, please be kind and remember to click appropriately!

Michael Jones - Proud member of the CloudPires team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

Thank you very much! While I'm not totaling the number of rows, this got me to a position where I can show a total of the specific variables within the MRVS.

For those looking in the future, you have to have an onChange script on each field you want to total, as the onChange fires before saving the row. Grab the existing row(s) total as well as the newValue which you just added for your final total.

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}

// get your MRVS
var breakdown = window.parent.g_form.getValue('breakdown');
var charges = 0;
var brdown = breakdown.substring(3,breakdown.length);
var brk = brdown.substring(0,brdown.length - 3);
var b = brk.split("}");
for (var i = 0; i < b.length; i++)
{
if(i == 0) // first row
{
var o = b[i].split(",");
for (var j = 0; j < o.length; j++) {
var p = o[j].split(":");
if(p[0] == '"charges"')
{
charges += parseFloat(p[1].replace(/['"]+/g, ''));
}
}
}
else
{
var r = b[i].substring(3,b[i].length);
var s = r.split(",");
for (var k = 0; k < s.length; k++) {
var t = s[k].split(":");
if(t[0] == '"charges"')
{
charges += parseFloat(t[1].replace(/['"]+/g, ''));
}
}
}
}

// now add up your values for a final total
var subtotal = 0;
if(parseFloat(newValue) > 0)
{
subtotal = charges + parseFloat(newValue);
subtotal = subtotal.toFixed(2);
}
else
{
subtotal = charges;
}

// set your form field to the total
window.parent.g_form.setValue('charges_total', subtotal);
}