function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Siva SakthiSiva Sakthi 

Email and Number, Text Input Field Validation Error in LWC

Hi All, 
    How to give the cusotm validation in LWC. I have added the JS function for each Lightning-Input field Validation. How to check fiels Value != Null or Not Empty.I am getting this below error. Please guide me where I made mistake and how to solve this.
Validation
HTML:
---------

<div class="container-fluid">        
            <table class="slds-table slds-table_bordered slds-table_cell-buffer"> 
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate">#</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact FirstName">Contact FirstName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact LastName">Contact LastName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Email">Email</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Phone">Phone</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Maximum">Maximum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Minimum">Minimum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Action">Action</div>
                        </th>
                    </tr>
                </thead>   
                <tbody>      
                    
                    <template for:each={contactList} for:item="con" for:index="indx">
                        <tr key={con.key} id={con.key}> 
                            <td>{indx}</td>                                                  
                            <td>
                                <lightning-input name="firstName" data-id={indx} value={con.FirstName} onchange={handleFirstNameChange} onblur={handleCustomValidationFirstName}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input name="lastName" data-id={indx} value={con.LastName} onchange={handleLastNameChange} onblur={handleCustomValidationLastName}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Email} onchange={handleEmailChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Phone} onchange={handlePhoneChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Maximum__c} onchange={handleMaximumChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Minimum__c} onchange={handleMinimumChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-button-icon icon-name="utility:delete"
																		  data-id={indx}       
																		  alternative-text="Delete"     
																		  class="slds-m-left_xx-small"
																		  onclick={removeRow} 
																		  title="Delete"></lightning-button-icon>
                            </td>
                        </tr>
                    </template>
                     
                </tbody>
            </table>
            <div class="slds-align_absolute-center slds-p-top_small">                
                <lightning-button name="Save" label="Save" onclick={saveRecord} if:true={addSaveNewRow}></lightning-button>
            </div>
        </div>  

JS:
------

handleCustomValidationFirstName(event) {
    let element = this.template.querySelector("[data-id='firstName']");
    let value = element.value;

    if (value == '' || value ==  null ) {
    element.setCustomValidity("Error!");
    } else {
    element.setCustomValidity("");
    }

    element.reportValidity();
}
handleCustomValidationLastName(event) {
    let element = this.template.querySelector("[data-id='lastName']");
    let value = element.value;

    if (value == '' || value ==  null) {
    element.setCustomValidity("Error!");
    } else {
    element.setCustomValidity("");
    }

    element.reportValidity();
}

handleSave(event) {

    let element = this.template.querySelector("lightning-input");
    let value = element.value;

    if (value == '' || value == null)  {
        element.setCustomValidity("Error!");
    } else {
        element.setCustomValidity("");
    }

    element.reportValidity();

    const recordInputs = event.detail.draftValues.slice().map(draft => {
        const fields = Object.assign({}, draft);
        return {fields};
    });

    //const recordInput = {fields};
    const promises = recordInputs.map(recordInput => updateRecord(recordInput));
        Promise.all(promises).then(() => {
            // Clear all draft values
            this.draftValues = [];
            // Display fresh data in the datatable
            return refreshApex(this.wiredDataResult);
        }).catch(error => {
            // Handle error
        });
}

Thanks
Siva

   
Best Answer chosen by Siva Sakthi
Siva SakthiSiva Sakthi
Hi All,
 
    I have found the solution for custom validation in LWC lightning-input  tag. 
HTML:
---------

<div class="container-fluid">        
            <table class="slds-table slds-table_bordered slds-table_cell-buffer"> 
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate">#</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact FirstName">Contact FirstName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact LastName">Contact LastName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Email">Email</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Phone">Phone</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Maximum">Maximum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Minimum">Minimum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Action">Action</div>
                        </th>
                    </tr>
                </thead>   
                <tbody>      
                    
                    <template for:each={contactList} for:item="con" for:index="indx">
                        <tr key={con.key} id={con.key}> 
                            <td>{indx}</td>                                                  
                            <td>
                                <lightning-input class="firstNameCmp" data-id={indx} value={con.FirstName} onchange={handleFirstNameChange}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input class="lastNameCmp" data-id={indx} value={con.LastName} onchange={handleLastNameChange}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Email} onchange={handleEmailChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Phone} onchange={handlePhoneChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Maximum__c} onchange={handleMaximumChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Minimum__c} onchange={handleMinimumChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-button-icon icon-name="utility:delete"
																		  data-id={indx}       
																		  alternative-text="Delete"     
																		  class="slds-m-left_xx-small"
																		  onclick={removeRow} 
																		  title="Delete"></lightning-button-icon>
                            </td>
                        </tr>
                    </template>
                     
                </tbody>
            </table>
            <div class="slds-align_absolute-center slds-p-top_small">                
                <lightning-button name="Save" label="Save" onclick={saveRecord} if:true={addSaveNewRow}></lightning-button>
            </div>
        </div>  

JS:
------

saveRecord(){   
    // Validation
    let fnameCmp = this.template.querySelector(".firstNameCmp");
    let lnameCmp = this.template.querySelector(".lastNameCmp");
    let fnamevalue = fnameCmp.value;
    let lnameValue = lnameCmp.value;
   
    if (!fnamevalue) {
        fnameCmp.setCustomValidity("First Name is required");
    } else {
        fnameCmp.setCustomValidity(""); // clear previous value
    }
    fnameCmp.reportValidity();

    if (!lnameValue) {
        lnameCmp.setCustomValidity("Last Name is required");
    } else {
        lnameCmp.setCustomValidity(""); // clear previous value
    }
    lnameCmp.reportValidity();

    saveContacts({conList : this.contactList})
        .then(result => {
            this.message = result;
            this.error = undefined;
            if(this.message !== undefined) {
                this.con.FirstName = '';
                this.con.LastName = '';
                this.con.Email = '';
                this.con.Phone = '';
                this.con.Maximum__c = '';
                this.con.Minimum__c = '';
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Contact created successfully',
                        variant: 'success',
                    }),                        
                );                   
            }            
            console.log(JSON.stringify(result));
            console.log("result", this.message);
            this.contactList = [];
            this.addSaveNewRow = false;
            return refreshApex(this.wiredDataResult);
        })            

        .catch(error => {
            this.message = undefined;
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error creating record',
                    message: error.body.message,
                    variant: 'error',
                }),
            );
            console.log("error", JSON.stringify(this.error));
        });
}

 

All Answers

AbhishekAbhishek (Salesforce Developers) 
Hi Siva,

Try the suggestions as mentioned in the below articles,

https://developer.salesforce.com/forums/?id=9060G0000005pzuQAA

https://success.salesforce.com/answers?id=9063A000000a1GYQAY

It might help you. 
Siva SakthiSiva Sakthi
Hi All,
 
    I have found the solution for custom validation in LWC lightning-input  tag. 
HTML:
---------

<div class="container-fluid">        
            <table class="slds-table slds-table_bordered slds-table_cell-buffer"> 
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate">#</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact FirstName">Contact FirstName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Contact LastName">Contact LastName</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Email">Email</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Phone">Phone</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Maximum">Maximum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Minimum">Minimum</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Action">Action</div>
                        </th>
                    </tr>
                </thead>   
                <tbody>      
                    
                    <template for:each={contactList} for:item="con" for:index="indx">
                        <tr key={con.key} id={con.key}> 
                            <td>{indx}</td>                                                  
                            <td>
                                <lightning-input class="firstNameCmp" data-id={indx} value={con.FirstName} onchange={handleFirstNameChange}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input class="lastNameCmp" data-id={indx} value={con.LastName} onchange={handleLastNameChange}></lightning-input>                               
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Email} onchange={handleEmailChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Phone} onchange={handlePhoneChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Maximum__c} onchange={handleMaximumChange}></lightning-input>                        
                            </td>
                            <td>
                                <lightning-input data-id={indx} value={con.Minimum__c} onchange={handleMinimumChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-button-icon icon-name="utility:delete"
																		  data-id={indx}       
																		  alternative-text="Delete"     
																		  class="slds-m-left_xx-small"
																		  onclick={removeRow} 
																		  title="Delete"></lightning-button-icon>
                            </td>
                        </tr>
                    </template>
                     
                </tbody>
            </table>
            <div class="slds-align_absolute-center slds-p-top_small">                
                <lightning-button name="Save" label="Save" onclick={saveRecord} if:true={addSaveNewRow}></lightning-button>
            </div>
        </div>  

JS:
------

saveRecord(){   
    // Validation
    let fnameCmp = this.template.querySelector(".firstNameCmp");
    let lnameCmp = this.template.querySelector(".lastNameCmp");
    let fnamevalue = fnameCmp.value;
    let lnameValue = lnameCmp.value;
   
    if (!fnamevalue) {
        fnameCmp.setCustomValidity("First Name is required");
    } else {
        fnameCmp.setCustomValidity(""); // clear previous value
    }
    fnameCmp.reportValidity();

    if (!lnameValue) {
        lnameCmp.setCustomValidity("Last Name is required");
    } else {
        lnameCmp.setCustomValidity(""); // clear previous value
    }
    lnameCmp.reportValidity();

    saveContacts({conList : this.contactList})
        .then(result => {
            this.message = result;
            this.error = undefined;
            if(this.message !== undefined) {
                this.con.FirstName = '';
                this.con.LastName = '';
                this.con.Email = '';
                this.con.Phone = '';
                this.con.Maximum__c = '';
                this.con.Minimum__c = '';
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Contact created successfully',
                        variant: 'success',
                    }),                        
                );                   
            }            
            console.log(JSON.stringify(result));
            console.log("result", this.message);
            this.contactList = [];
            this.addSaveNewRow = false;
            return refreshApex(this.wiredDataResult);
        })            

        .catch(error => {
            this.message = undefined;
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error creating record',
                    message: error.body.message,
                    variant: 'error',
                }),
            );
            console.log("error", JSON.stringify(this.error));
        });
}

 
This was selected as the best answer