Detecting Change by User

Good Afternoon,

We are in the process of recreating our Forms Designer forms within Plumsail Forms and we have discovered that the OnChange handler in Plumsail Forms will trigger when a change is made to a field by the user or by Javascript, this was not the case within Forms Designer the OnChange was only triggered by user input, this is causing us some issues and in essence creating loops.
For example we have 2 Lookups on a form setup as cascading, so the top lookup filters the second.
So Lookup 1 = Category and Lookup 2 = Product

If a user selects a Category Javascript runs to clear fields on the form (including Product) and filter the Product Lookup.

When a user selects a Product a Rest call is triggered to go to the Products list and retrieve additional data for the selected Product and post into required fields on the form. This includes the Category as the user does not have to select a Category if they already know the product code, but we need the Category to be filled in on selection of a product.

On Forms Designer this worked as the OnChange to Clear fields on Category selection only triggered when the user interacted with the field, on Plumsail Forms when a Product is selected the code posts to the Category field which then in turn triggers the OnChange which then runs the code to clear and filter again.

Is there a way of only detecting if the OnChange event was triggered by user input or by script??

Thanks

Dear Tony,

You can use Kendo UI “change” event fired when the value of the widget is changed by the user: https://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist/events/change

fd.field("Lookup").widget.bind("change", function(){
    console.log("Lookup is changed by user")
})

Hi Alex,

I’m still struggling with this issue, I haven’t been able to get the above working, for the previous issue with the lookups I managed to come up with an alternative solution, but I have now come up against the same issue again this time with number fields.

I have three fields one is a Read Only Field (salesPrice) the next is a percentage (depositPercentage) the other an amount (depositAmount), the user needs to be able to enter a value into the percentage field and a function should then calculate the depositAmount. The user should also be able to enter a value into the amount field and a function should then calculate the depositPercentage. The issue is the on change is triggers as soon as the first change is made on the field as opposed to when a user leaves the field (I believe this is how Forms Designer worked).

The code is below, hopefully you have some ideas…

var salesPrice = fd.field('Sales_x0020_Price').value != '' ? parseFloat(fd.field('Sales_x0020_Price').value.replace("£","").replace(/\,/g,'')) : 0;

fd.field('Deposit_x0020__x0025_').$on('change',calculateDepositAmount);
fd.field('Deposit_x0020_Amount').$on('change',calculateDepositPercentage);

// Function to Calculate the Deposit Amount on change of Deposit %
function calculateDepositAmount () {
	debugger;
	var depositPercentage = fd.field('Deposit_x0020__x0025_').value;
	if (depositPercentage != '') {
		var depositPercentage = parseFloat(depositPercentage);
		if (depositPercentage != 0) {
			var percentageMultiplier = 100 / depositPercentage;
			var depositAmount = salesPrice / percentageMultiplier;
			fd.field('Deposit_x0020_Amount').value = depositAmount.toFixed(2);
			fd.field('Invoiced_x0020_to_x0020_Date').value = depositAmount.toFixed(2);
			var leftToInvoice = salesPrice - depositAmount;
			fd.field('Left_x0020_to_x0020_Invoice').value = leftToInvoice.toFixed(2);
			var leftToInvoicePercentage = 100 - depositPercentage;
			fd.field('Left_x0020_to_x0020_Invoice_x002').value = leftToInvoicePercentage.toFixed(0);
		} else {
			fd.field('Deposit_x0020__x0025_').value = '0';
			fd.field('Deposit_x0020_Amount').value = '0.00';
			fd.field('Left_x0020_to_x0020_Invoice_x002').value = '100';
			fd.field('Left_x0020_to_x0020_Invoice').value = salesPrice;
			fd.field('Invoiced_x0020_to_x0020_Date').value = '0.00';
			fd.field('Deposit_x0020_Required').value = 'No';
			//$('.depositPercentageCssClass').hide();
			//$('.depositAmountCssClass').hide();
		}
	} else {
		fd.field('Deposit_x0020__x0025_').value = '25';
		fd.field('Left_x0020_to_x0020_Invoice_x002').value = '75';
		var depositValue = salesPrice / 4;
		fd.field('Deposit_x0020_Amount').value = depositValue.toFixed(2);
		fd.field('Invoiced_x0020_to_x0020_Date').value = depositValue.toFixed(2);
		var leftToInvoice = depositValue*3;
		fd.field('Left_x0020_to_x0020_Invoice').value = leftToInvoice.toFixed(2);
	}
}

// Function to Calculate Deposit % on Change of Deposit Amount
function calculateDepositPercentage () {
	debugger;
	var depositAmount = fd.field('Deposit_x0020_Amount').value;
	if (depositAmount != '') {
		var depositAmount = parseFloat(depositAmount);
		if (depositAmount != 0) {	
			fd.field('Invoiced_x0020_to_x0020_Date').value = depositAmount.toFixed(2);
			var depositPercentage = (depositAmount / salesPrice)*100;
			fd.field('Deposit_x0020__x0025_').value = depositPercentage.toFixed(0);
			var leftToInvoice = salesPrice - depositAmount;
			fd.field('Left_x0020_to_x0020_Invoice').value = leftToInvoice.toFixed(2);
			var leftToInvoicePercentage = 100 - depositPercentage;
			fd.field('Left_x0020_to_x0020_Invoice_x002').value = leftToInvoicePercentage.toFixed(0);
		} else {
			fd.field('Deposit_x0020__x0025_').value = '0';
			fd.field('Deposit_x0020_Amount').value = '0.00';
			fd.field('Left_x0020_to_x0020_Invoice_x002').value = '100';
			fd.field('Left_x0020_to_x0020_Invoice').value(salesPrice)
			fd.field('Invoiced_x0020_to_x0020_Date').value = '0.00';
			fd.field('Deposit_x0020_Required').value = 'No';
			//$('.depositPercentageCssClass').hide();
			//$('.depositAmountCssClass').hide();
		}
	} else {
		fd.field('Deposit_x0020__x0025_').value = '25';
		fd.field('Left_x0020_to_x0020_Invoice_x002').value = '75';
		var depositValue = salesPrice / 4;
		fd.field('Deposit_x0020_Amount').value = depositValue.toFixed(2);
		fd.field('Invoiced_x0020_to_x0020_Date').value = depositValue.toFixed(2);
		var leftToInvoice = depositValue * 3;
		fd.field('Left_x0020_to_x0020_Invoice').value = leftToInvoice.toFixed(2);
	}
}

Thanks

Any update on this one?

Dear Tony,

I’m terribly sorry, I’ve missed this topic. Working on your issue.

Dear Tony,

The issue happens because of when the one event handler finishes it initiates the change event of the other field and vice versa. So this process will go forever until exceeds the limit of the number field.

As a workaround to prevent such behavior, I’d like to suggest to introduce the special boolean variables that will prevent the loop:

fd.field('depositPercentage').$on('change',calculateDepositAmount);
fd.field('depositAmount').$on('change',calculateDepositPercentage);

window.changeAmount = true;
window.changePercentage = true; 
function calculateDepositAmount () {
    if (changeAmount) {
        fd.field("depositAmount").value = ....
    } else {
        changePercentage = false;
        changeAmount = true;
    }
}

function calculateDepositPercentage () {
    if (changePercentage) {
        fd.field("depositPercentage").value = ...
    } else {
        changePercentage = true;
        changeAmount = false;
    }   
}