You need to sign in to do that
Don't have an account?
Lightning Components Basics Input Data Using Forms
I had so much trouble with this one section that I feel like I have to post this to help out those who are struggling as much as me. Three hours for a simple controller... The problem is the way trailhead tests the challenge is hard for them and they have very strict criteria that is not implicit in the challenge directions.
camingList.cmp
campingList.Controller
campingHeader.cmp
campingListItem.cmp
Any other controllers or helper classes are not needed. That is the trick here. Using helper classes when not specified fails the challenge. I hope you will read through and understand this code as I have to realize why it is this way and not simply copypasta.
Enjoy!
camingList.cmp
<aura:component > <aura:attribute name="newItem" type="Camping_Item__c" default="{'sobjectType': 'Camping_Item__c', 'Quantity__c': 0, 'Price__c': 0.00}" required="true"/> <aura:attribute name="items" type="Camping_Item__c[]"/> <lightning:layout class="slds-page-header slds-page-header--object-home"> <lightning:layoutItem > <lightning:icon iconName="standard:scan_card" alternativeText="My Campign Items"/> </lightning:layoutItem> <lightning:layoutItem padding="horizontal-small"> <div class="page-section page-header"> <h1 class="slds-text-heading--label">Camping Items</h1> <h2 class="slds-text-heading--medium">My Camping Items</h2> </div> </lightning:layoutItem> </lightning:layout> <!-- / PAGE HEADER --> <!-- NEW EXPENSE FORM --> <lightning:layout > <lightning:layoutItem padding="around-small" size="6"> <!-- CREATE NEW EXPENSE --> <div aria-labelledby="newitemform"> <!-- BOXED AREA --> <fieldset class="slds-box slds-theme--default slds-container--small"> <legend id="newitemform" class="slds-text-heading--small slds-p-vertical--medium"> Add Camping Item </legend> <!-- CREATE NEW EXPENSE FORM --> <form class="slds-form--stacked"> <lightning:input aura:id="itemform" label="Item Name" name="itemname" value="{!v.newitem.Name}" required="true"/> <lightning:input type="itemform" aura:id="itemform" label="Amount" name="itemprice" min="0.1" formatter="currency" step="0.01" value="{!v.newitem.Price__c}" messageWhenRangeUnderflow="Enter an amount that's at least $0.10."/> <lightning:input aura:id="itemform" label="Quantity" name="itemquantity" value="{!v.newitem.Quantity__c}" min="1" type="number" required="true" messageWhenRangeUnderflow="Enter minimum 1 Quantity"/> /> <lightning:input type="checkbox" aura:id="itemform" label="Packed?" name="packed" class="slds-checkbox" checked="{!v.newitem.Packed__c}"/> <lightning:button label="Create Camping Item" class="slds-m-top--medium" variant="brand" onclick="{!c.clickCreateItem}"/> </form> <!-- / CREATE NEW EXPENSE FORM --> </fieldset> <!-- / BOXED AREA --> </div> <!-- / CREATE NEW EXPENSE --> </lightning:layoutItem> </lightning:layout> <!-- / NEW EXPENSE FORM --> <div class="slds-card slds-p-top--medium"> <header class="slds-card__header"> <h3 class="slds-text-heading--small">Camping</h3> </header> <section class="slds-card__body"> <div id="list" class="row"> <aura:iteration items="{!v.items}" var="cmp"> <c:campingListItem item="{!cmp}"/> </aura:iteration> </div> </section> </div> </aura:component>
campingList.Controller
({ handleAddItem: function(component, event, helper) { var addItm = event.getParam("item"); helper.createItem(component, addItm); }, createItem: function(component, newItem) { var action = component.get("c.clickCreateItem"); action.setParams({ "item": newItem }); action.setCallback(this, function(response){ var state = response.getState(); if (component.isValid() && state === "SUCCESS") { var items = component.get("v.items"); items.push(response.getReturnValue()); component.set("v.items", items); } }); $A.enqueueAction(action); }, clickCreateItem: function(component, event, helper) { var validItem = component.find('itemform').reduce(function (validSoFar, inputCmp) { // Displays error messages for invalid fields inputCmp.showHelpMessageIfInvalid(); return validSoFar && inputCmp.get('v.validity').valid; }, true); // ... hint: more error checking here ... // If we pass error checking, do some real work if(validItem){ // Create the new expense var newItem = component.get("v.newItem"); console.log("Create Camping Item: " + JSON.stringify(newCamping)); handleAddItem(component, newItem); } component.set("v.newItem",{'sobjectType':'Camping_Item__c', 'Name': '', 'Quantity__c': 0, 'Price__c': 0, 'Packed__c': false}); } })camping.cmp
<aura:component implements="flexipage:availableForRecordHome"> <br/><br/><br/> <c:campingHeader /> <c:campingList /> </aura:component>
campingHeader.cmp
<aura:component > <lightning:layout class="slds-page-header"> <lightning:layoutItem > <lightning:icon iconName="action:goal"/> </lightning:layoutItem> <div class="slds-page-header"> <h1 class="slds-text-heading--label"> Camping List </h1> </div> </lightning:layout> </aura:component>
campingListItem.cmp
<aura:component > <aura:attribute name="item" type="Camping_Item__c"/> <p>Name: <ui:outputText value="{!v.item.Name}"/> </p> <p>Price: <ui:outputCurrency value="{!v.item.Price__c}"/> </p> <p>Quantity: <ui:outputNumber value="{!v.item.Quantity__c}"/> </p> <p>Packed: <ui:outputCheckbox value="{!v.item.Packed__c}"/> </p> </aura:component>
Any other controllers or helper classes are not needed. That is the trick here. Using helper classes when not specified fails the challenge. I hope you will read through and understand this code as I have to realize why it is this way and not simply copypasta.
Enjoy!
All Answers