0

I have a Lightning component with input fields with some mandatory.

At the end of the page, I have button when clicked, gathers all the info entered and creates a record in back end.

I assumed when I use, mandatory="True" on input filed, upon button click it will throw error messages and force user to fill in.

But it doesn't throw errors and send null data to apex class.

Example: Lightning cmp:

<div>
                                    <lightning:select name="Type" label="C Type:" required="True" aura:id="Type" >
                                        <option value="">Choose One</option>
                                        <option value="1">One</option>
                                        <option value="2">Two</option>
                                        <option value="3">Three</option>
                                        <option value="4">Four</option>
                                        <option value="5">Five</option>
                                    </lightning:select>
                                </div>
<lightning:button variant="brand" class="buttoncss slds-float_right" label="Create" onclick="{!c.createRecord}"/>

Controller:

createRecord: function(component, event, helper) {


        var filters = {};
filters.param1 = component.find("Type").get("v.value");

//Pass this filters to apex

When The drop down is left empty, upon button click null is passed to apex.

What am I missing here to fire mandatory field error message?

3

You'll want to read Validating Fields for more information, but generally speaking, you need to check the validity before sending the data off to the server. Nothing in the framework prevents calling the server while in an error status.


createRecord: function(component, event, helper) {
  if(component.find("Type").get("v.value")) {
    // send to server
  } else {
    component.find("Type").set("v.errors", [{message:"A value is required"}]);
  }
}
4

The attribute is called required,

Lightning:input documentation

<lightning:input aura:id="field" label="Last name" placeholder="Last name" required="true" />  

However, i dont see a lightning:input field in your code, but rather a lightning:Select . (should be the same though)

would be good to know if your form is wrapped in a lightning:recordEditForm and to see your controller method,

I tested with a Lightning:recordEditForm, and the component behaves as expected and does not create the record:

    <lightning:select aura:id="product" name="Product" label="Select a Product" onchange="{!c.itemsChange}" required="true" >
            <option value="" title="">choose one...</option>
            <aura:iteration items="{!v.ProductList}" var="product">
                <option text="{!product.label}" value="{!product.value}" title="{!product.index}" selected="{!product.selected}"/>
            </aura:iteration>
    </lightning:select>

enter image description here

I would actually suggest you use it, as it handles most of these things for you =)

lightning:recordEditForm

1

Lets get in-depth for lightning: select . It has "required" attribute. How does it work? Well to answer, it works on value change. When your component is loaded first time, there is no value change and thats why even if the default value is null, it won't indicate user to input it.

Can we do something to trigger that mechanism? Yes we can.

https://developer.salesforce.com/docs/component-library/bundle/lightning:select/specification

According to lightning:select documentation, we have showHelpMessageIfInvalid() method which will give user the error message if the input provided by him is invalid. In our case required.

Similary, we have "validity" attribute present in lightning:select which we can use to find if the values are valid.

Thus your code will be.

({
    createRecord : function(component, event, helper) {

        let sltCmp = component.find("Type");
        if(sltCmp.get("v.validity").valid){ //Magic happens here
            //Do your job, send to apex, Ride unicorns
        }else{
            sltCmp.showHelpMessageIfInvalid(); //This will show validation messages for user. 
            return;
        }

    }
})
1

Marking field as required only helps for showing * symbol but the when you click on save lightning doesn't validate that and passes the data to server.

So you have to validate the data before passing to server. This could create so much validation code in javascript controller if you have many required fields. For this very same reason, I created a utility which will take care of putting required message.

To use this you need to create a Lightning Component

LightningUtil.cmp

<aura:component description="LightningUtil" >


    <!-- Form validation -->
    <aura:method name="validateForm"
                 description="This method will help to validate form elements">
        <aura:attribute name="config" type="Object" />
    </aura:method>

</aura:component>

LightningController.js

({

     validateForm : function(component,event,helper){
        return helper.validateFormHelper(component,event);
     }

})

LightningHelper.js

({

     validateFormHelper : function(component,event){
         var params = event.getParam('arguments');
         if(params && params.config && params.config.validationFieldAuraIds ){
             let isValidationPassed = true;
             let passedComponent = params.config.component;
             params.config.validationFieldAuraIds.split(',').forEach(function(auraIdOfInputsToBeValidated){
                 if(passedComponent.find(auraIdOfInputsToBeValidated) && passedComponent.find(auraIdOfInputsToBeValidated).length){//if there are any records to iterate
                     (passedComponent.find(auraIdOfInputsToBeValidated)).forEach(function(inputField){
                                      if(inputField.get('v.required') && !inputField.get('v.value')){
                                         inputField.showHelpMessageIfInvalid();
                                         isValidationPassed = false;
                                      }
                     });
                 }else{
                     var singleInputField = passedComponent.find(auraIdOfInputsToBeValidated);
                     if(singleInputField){
                         if(singleInputField.get('v.required') && !singleInputField.get('v.value')){
                              singleInputField.showHelpMessageIfInvalid();
                              isValidationPassed = false;
                         }
                     }
                 }
             });

             return isValidationPassed;
         }
     }


})

Usage:

Add this to the component:

<c:LightningUtil aura:id="LightningUtility"/>

In Controller before calling the controller method, call validateForm method as below:

var lightningUtil = component.find('lightingUtility');
var isValidationPassed = lightningUtil.validateForm({
    'component':component,
    'validationFieldAuraIds':'<field1AuraId>,<field2AuraId>'
});
if(isValidationPassed){
//now call the controller method
}

Now this utility can be used in any lightning form where you would like to validate the fields before calling the server method.

  • This is not true for all components, Lightning:recordEditForm handles the validation for you and the error message, and FLS and CRUD.... – glls Jun 29 '18 at 0:28
  • @glls Agreed, but this could be used whenever we go with custom solution. – Kiran Machhewar Jun 29 '18 at 4:37
  • @glls Most of the times I am falling to the custom approach because it is way faster than lighting:recordEditForm. Literally it takes 2 to 3 seconds to load form and the custom form comes right away. – Kiran Machhewar Jun 29 '18 at 4:49
  • @KiranMachhewar simplest option would be to just look at the "validity" attribute of lightning:select /input. works every time. – Pranay Jaiswal Jun 30 '18 at 1:15
  • @PranayJaiswal Yes, thats the quickest. But I wanted to have something generic which can be used everywhere, instead of checking for each and every field. I have few forms with more than 10 fields, when I completed code, nearly 20, 30 lines were only for validating data. Initial setup looks too much but it pays off in long run. – Kiran Machhewar Jun 30 '18 at 1:27

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.