I am building a Lightning Component form with sections. I want to display a big check mark icon on the section if all the rendered lightning:input fields are filled out.
I have successfully tested this approach:
Markup:
<lightning:input aura:id="fieldId" type="number" name="input1" required="true"
label="Enter a number" />
<lightning:input aura:id="fieldId" type="number" name="input2" required="true"
label="Enter another number" />
<lightning:button variant="brand" label="Check" value="check"
onclick="{!c.testMe}"/>
Controller:
testMe : function(component) {
var allComplete = component.find('fieldId').reduce(function (validSoFar, inputCmp) {
return validSoFar && !inputCmp.get('v.validity').valueMissing;
}, true);
if (allComplete) {
console.log('All fields complete!');
} else {
console.log('Some fields are missing values.');
}
},
The problem arises when I start making the form dynamic using aura:if to conditionally hide lightning:input fields.
If I change my markup to this, the function fails and nothing shows up in the console:
<lightning:input aura:id="fieldId" type="number" name="input1" required="true" label="Enter a number" />
<aura:if isTrue="{! false }">
<lightning:input aura:id="fieldId" type="number" name="input2" required="true" label="Enter another number" />
</aura:if>
<lightning:button variant="brand" label="Check" value="check" onclick="{!c.testMe}"/>
Based on the helpful answer from itzmukeshy7, here is my revised, working controller function:
testMe : function(component) {
var rows = component.find('fieldId');
// The following row handles all return types for the find function:
// 1. A component
// 2. An array of components, or
// 3. Undefined (no matching components)
var elements = [].concat(rows || []);
var allComplete = elements.reduce(function (validSoFar, inputCmp) {
return validSoFar && !inputCmp.get('v.validity').valueMissing;
}, true);
if (allComplete) {
console.log('All fields complete!');
} else {
console.log('Some fields are missing values.');
}
},