0

I have an lwc form that consists of a lightning-record-edit-form and some lightning-input-fields

I have to override the submit button with apex as I have to perform some custom logic.

There are some validation rules defined against the lightning-input-field which I am trying to fire using reportValidity() which fires correctly. But after the rule fires, I want to stop execution. This is not happening and the code is still going to apex. How can I stop execution if reportValidity() throws up errors on lightning-input-field?

Here is the code HTML

<lightning-record-edit-form object-api-name={objName} onsubmit={handleSubmit} onsuccess={handleSuccess} record-id={recordId}>

    <lightning-input-field field-name={fieldName} name = {fieldName}  onchange={handleChange}></lightning-input-field>

     <lightning-button variant="brand" type="submit" name="save" label="Submit" onclick={validateFields}>
     </lightning-button>

</lightning-record-edit-form>

JS:

validateFields(event) {
    this.template.querySelectorAll('lightning-input-field').forEach(element => {
                element.reportValidity();
            });

    //check if there is an error. not sure how to check if reportValidity throws an error as the code proceeds to execute apex even when there is an error
        
     let isError = this.template.querySelector(".slds-has-error");
    
    //if no error then only call apex from handleSubmit
     if(!isError) {
            this.template.querySelector("lightning-record-edit-form").submit();
        }
    }
1
  • Can you post some relevant code so we can help identify the issue if there is any
    – manjit5190
    Commented Feb 21, 2021 at 13:07

2 Answers 2

2

EDIT 2: You can't call validation rules separately from DML operations: Fire Validation Rule from Apex

Please see Trigger Order of Execution: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

If you are attempting to use lightning-record-edit-form as a form to collect valid input without saving to the DB, and then handle it via another Apex class, then you can't do that: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.data_salesforce_write. Instead, create a custom lookup component, use input fields, handle all the logic client side, and then pass the input to your class, otherwise lightning-record-edit-form must save to the database to run "reportValidity" and return Validation Rule errors.


Please see the section "Overriding Default Behaviours": https://developer.salesforce.com/docs/component-library/bundle/lightning-record-edit-form/documentation

You'll want to use event.preventDefault() in your custom event handlers and then after all validation succeeds, call the .submit() or custom Apex

EDIT: My mistake, you can't set custom error messages on input-field like you can with input setCustomValidity() see: Lightning Web Component Custom Errors

But, you can handle the errors in a separate component / UI feature -- here I add errors to an array.

customErrors = [];

handleSubmit(event) {
    event.preventDefault();
    this.customErrors = [];
    let isValid = [...this.template.querySelectorAll('lightning-input-field')].reduce( (val, inp) => {
        let inpVal = true;
        // Custom Logic
        switch (inp.fieldName) {
            case 'Name':
                inpVal = inp.value == 'Logic' ? true : false;
                if (!inpVal) { this.customErrors.push('Custom Error'); }
                break;
            default:
                inpVal = true;
                break;
        }
        return val && inpVal;
    }, true);

    if (isValid) {
        this.template.querySelector('lightning-record-edit-form').submit();
        // Validation Rules will run and return errors after the submit / DML operation
    }
}
10
  • I tried this, but checkValidity doesnt work on lightning-input-field
    – Nevds
    Commented Feb 23, 2021 at 5:54
  • Thanks, I've updated the answer. You'll have to handle the logic per input field and specify the errors / messages outside of the input-field Commented Feb 24, 2021 at 18:18
  • ok, currently with reportValidity(), any validation rules defined on the object and having error location as 'fieldname' will show up and the field will get highlighted. So you are suggesting not to create validation rules, instead check the errors in the lwc itself with switch and create custom errors?
    – Nevds
    Commented Feb 25, 2021 at 13:50
  • @Nevds please elaborate on your logic and requirements. It seems you are asking for functionality not available with input-fields, please review: developer.salesforce.com/docs/component-library/documentation/… Commented Feb 25, 2021 at 22:09
  • Hi @gale-force-wizard, the default submit behaviour of lightning-record-edit-form is report-validity and then save. In Report Validity, if there are any validation rules defined on a field, then the error is thrown on the field and save is stopped. Now I have to override this default submit behaviour. I still need report-validity to execute, but after that if no errors come, I want to call apex and save the record, due to some modifications that I have to perform on the data prior to save.
    – Nevds
    Commented Feb 26, 2021 at 5:01
4

You need to record the result of all the reportValidity()'s, which you can do easily via the reduce function mentioned in the other answer. Depending on that result, you either throw an error message or submit the save.

handleSave() {
    // If all fields aren't validated, throw error message
    if (!this.validateFields()) {
        const toast = new ShowToastEvent({
            message: "Review all error messages below to correct your data.",
            variant: "error",
        });
        this.dispatchEvent(toast);
    }
    // Otherwise submit save
    else {
        this.template.querySelector("lightning-record-edit-form").submit();
    }
}

validateFields() {
    return [...this.template.querySelectorAll("lightning-input-field")].reduce((validSoFar, field) => {
        // Return whether all fields up to this point are valid and whether current field is valid
        // reportValidity returns validity and also displays/clear message on element based on validity
        return (validSoFar && field.reportValidity());
    }, true);
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .