Validate Form Data Before Saving

In case inputs on a form are invalid for some reason, I want to test them before saving the record. I notice the OnComplete event is said to fire after clicking the save button but before the data is sent to the server.

I can’t find an example in the docs for OnComplete. Can you show me an example that verifies inputs and either allows the save to happen, or gives an error message and exits with no save?

Also, if this is the place to validate various inputs, can I also use it to change other field values? For example, on my BoardPositions form, I can check IsPortfolioVp to turn it on, which makes the drop-down PortfolioKey lookup field visible so I can choose which portfolio. If instead I turn IsPortfolioVp off, can I use this event/function to clear the value in the PortfolioKey field before saving?

Thanks…

Hi Ron,

The function should be the same any other, the only difference is that you must generate an error when it fails on any validation, so the form won’t try to save the data.

The example attached applied a few validations using the event ‘On Complete‘.
If you run this app, there is a label for each field explain which validation that it is been applied, please, try yourself.

In your function, you can apply the validation against the property: five.field.

AppOnCompleteValidations.fdf (3.4 MB)

Regards,
Elton S

Thanks for the quick answer Elton,

Here is what I came up with:

function ValidateBoardPositions(five, context, result)  {

// validate board group
if (!five.field.BoardGroupsKey) {
    return five.createError(result, 'BoardGroup is a required field');
}

// validate IsPresident
if (five.field.IsPresident) {
    five.field.IsOverseenByPresident = false;
}

// if IsOverseenByPresident, require OverseenByPresident
// otherwise, clear OverseenByPresident
if (five.field.IsOverseenByPresident) {
    if (!five.field.OverseenByPresident) {
        return five.createError(result, 'You must select a president to oversee this position');
    }
} else {
    five.field.OverseenByPresident = null;
}

// if portfolio vp or registrar, error if no portfolio chosen
// otherwise, clear portfolio
if (five.field.IsPortfolioVp || five.field.IsPortfolioRegistrar) {
    if (!five.field.PortfolioKey) {
        return five.createError(result, 'You must select a portfolio');
    }
} else {
    five.field.PortfolioKey = null;
}

    return five.success(result);
}

I don’t think your fdf addressed the last part of my question. there are some cases where fields should be updated based on the value of other fields. Please note the places with else blocks in above code.

That doesn’t seem to do anything. Can you explain why, or how I do accomplish updating a field based on another field value?

Hi Ron,

If you intend to update the value of a field based on another field.

The best approach is to handle the logic within the individual form fields’ events rather than using the form’s events.

Therefore, the event ‘On Complete‘ will be your final check before saving the data.

In the documentation, there is a sample app and an example/explanation on how you can assign a value to a field based on another field:

https://help.five.org/2.9/docs/learning-resources/training-plans/advanced/execute-a-calculation

Regards,
Elton S

Hi Elton,

Thanks, this was a good answer. I see the way the logic works. Even though the example triggers the new function when you click into the total field, this workflow is not good for my GenerateEmails form. would it also work if I attach a function call in the OnValidate event? I know the purpose of this event is to make sure you entered a valid value into a field, but can’t the event also trigger code that will modifiy an other field based on what the user typed into the first field? Or will it only work to validate the one field?

Thanks…

Hi Ron,

The event ‘On validate‘ will be triggered after data has been entered into a form field, and you leave the field, such as clicking on another field or outside the field.

If the value is based on a lookup, you could use the event ‘On list Selected’.

Regards,
Elton S

Thanks Elton

my Board positions table/form has 3 fields, IsPresident, IsOverseenByPresident, and OverseenByPresident. First 2 are boolean, last one is a lookup of the multiple co-presidents. So if someone is marked as a president the other 2 should be set false and null respectively. If someone is marked as overseen by a president then the user chooses which one. Now if user unchecks IsOverseenByPresident, we want the OverseenByPresident set to null. Basically we don’t want incorrect values to remain.

Choices that would affect these fields are both checkboxes. Does that change the fact that normally you have to move to another field before the OnValidate event fires?

Or is there another event for form fields I could use, such as OnChange?

I’m already hiding/showing fields based on these choices, but I don’t want incorrect data left in the record.

Thanks…

Ron Mittelman

Hi Ron,

For checkbox fields, you can use the event ‘On Click‘, which will be triggered as soon as you click on the checkbox, turning it ON or OFF.

However, this event in this field is triggered before the value changes. For example, if the checkbox is OFF and you want to change the value of another field when it is ON, you need to compare with the previous value. because the function is triggered before the value changes.

This is one example of how to achieve it. Notice that the field CheckResult will have the value of the field Name if the check box CheckField is turned ON, otherwise, it will empty.

if (!five.field.CheckField == 1 || !five.field.CheckField == true){

    five.field.CheckResult = five.field.Name;

}else{

    five.field.CheckResult = '';

}

Regards,
Elton S

thanks for the suggestion. however, as you say, when the event function is running, the field hasn’t been updated yet. So this will work if this “feature” is dependable. I can, in the function, get the value of the boolean field, then NOT it manually, then use that value to set the other fields. Can you assure me that that technique will work for a checkbox?

Otherwise, using OnValidate will also work, but as you said, I have to go to another field or even the save button first. I believe this will also work if I click on another form page instead of another field, right?

It would be VERY handy if Five exposed an AfterUpdate event for the field itself. That would be more user-friendly. Do you agree?

Hi Ron,

Have you tried the solution I previously suggested? and did it work?

As mentioned, the function will be triggered any time you click on the checkbox button, but you need to check for the previous value in this case.

You can also try another event, but you need to click outside the field (On Validate/On Exit events) to trigger it.

I will forward your event suggestion to our team.

Regards,

Elton S

I like your suggestion, however don’t know if it’s dependable yet. if the first click turns the already-on checkbox to “off”, can you assure me that it will still be “on” when the function is triggered by OnClick?

Conversely, if it was off, and I click it “on”, is it dependable that the prior value of “off” will show up in the function?

If this is true, I can NOT the values and proceed accordingly in the function code.

One complication:

As mentioned, there are IsPresident (checkbox), IsOverseenByPresident (checkbox) and OverseenByPresident (lookup list).

If I turn IsPresident ON, I want the code to turn IsOverseenByPresident OFF. I also need to test for the condition of IsOverseenByPresident and if I turned it OFF (or if the above logic did), I then want to set OverseenByPresident to NULL.

I was hoping to do this with one single function, but since I need to “reverse” the state of IsPresident before using it, what do I do about reversing the state of IsOverseenByPresident? It seems like I either need a separate function for that one, or somehow by testing sender then only reverse the value if sender is the one I clicked. Then even if the code changes the value of the IsOverseenByPresident field, I would only reverse its value if it was the one clicked.

That last paragraph seemed simple enough when I thought of it, but now it looks very complex.

So the quick question is: can you show me how to use sender to identify exactly which checkbox was clicked?

Thanks…

Hi Ron,

You can check which checkbox was clicked by using the ‘five.sender()‘, an object will return, and from it, you can navigate to the property ‘formField.params.fieldId‘.

Example:
const x = five.sender()
x.formField.params.fieldId

Regards,
Elton S

That worked perfectly Elton.
Thanks!!!