1

I have a text input field serial number and a toggle button.serial number is required by default. So, if serial number is left blank then it will display error message. But,If the toggle button is checked then error message from serial number should be removed. But it continues to display the error message.

html

<template>
<lightning-input class="serialnumber" label ="serial 
  number" name="serialnumber" onchange= {handleChange} required={isRequired}
                          message-when-value-missing="serial Number is req">
</lightning-input>
  <!--toggle html>
  <label class="slds-checkbox_toggle slds-truncate"> 
  <input type="checkbox" name="infoToggle" checked={infoToggleValue} 
                                           onchange={handleChange} />
  <span class="slds-checkbox_on slds-text-body_small">not required</span>
  <span class="slds-checkbox_off slds-text-body_small">required</span>
  </label>
</template>

js

import { LightningElement, track} from 'lwc';
export default class CmpInputScreen extends LightningElement {

@track serialNumber;
@track infoToggleValue = false;
get isRequired(){
    if(this.infoToggleValue){
        return false;
    } return true;
}
handleChange(event) {
    const inputName = event.target.name;
    if (inputName === 'serialnumber') {
        this.serialNumber= event.target.value;
    }else if(inputName === 'infoToggle'){
        //it gets set to true when checked and isRequired sets to false
        this.infoToggleValue = event.target.checked; 
        if(this.infoToggleValue){
           let inputEle = this.template.querySelector('.serialnumber');
            inputEle.setCustomValidity("");
            inputEle.reportValidity();
          }
        }
       }
} 
1

It's a matter of asynchronous rendering. When you update the value of this.infoToggleValue, you need to allow some time for the isRequired expression to get re-evaluated in your template before reporting validity.

You need to wrap your call to reportValidity in a resolved Promise to let the framework do a rerender in the meantime.

handleChange(event) {
    const inputName = event.target.name;
    if (inputName === 'serialnumber') {
        this.serialNumber = event.target.value;
    } else if (inputName === 'infoToggle') {
        //it gets set to true when checked and isRequired sets to false
        this.infoToggleValue = event.target.checked;
    }
    // Revalidate serial number
    Promise.resolve().then(() => {
        const inputEle = this.template.querySelector('.serialnumber');
        inputEle.reportValidity();
    });
}

Edit: force revalidation of serial number in all cases.

2
  • I was able to remove error message with your solution and I was also able to add error message in the similar way, when toggle is uncheked back again. However, at this point, when i put some value in the text field, it should have removed the error message since it is not longer blank. But it still displayed error message – devforce Feb 19 '20 at 15:43
  • Updated my answer to deal with that. – POZ Feb 19 '20 at 15:51
1

required attribute doesn't work like you use it. It doesn't get a value of true or false. If the required attribute exists in the tag the input is already required. So if you want to change it you must delete the requiredattribute from the element, e.g. like below:

this.template.querySelector('.serialnumber').removeAttribute('required');
2
  • Great answer! It works for me! Thanks Jakub. – Piotr Gajek Feb 19 '20 at 14:45
  • @Jakub, I tried this solution but it did not remove error message. – devforce Feb 19 '20 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.