You need to sign in to do that
Don't have an account?

Lightning Components Basics - Input Data Using Forms
Problem Statement:
Create a form to enter new items and display the list of items entered. To make our camping list look more appealing, change the campingHeader component to use the SLDS. Similar to the unit, style the Camping List H1 inside the slds-page-header. Modify the campingList component to contain an input form and an iteration of campingListItem components for displaying the items entered.
My Code:
CampingList.cmp
Could anyone help pass and run the challenge.
Thanks.
Create a form to enter new items and display the list of items entered. To make our camping list look more appealing, change the campingHeader component to use the SLDS. Similar to the unit, style the Camping List H1 inside the slds-page-header. Modify the campingList component to contain an input form and an iteration of campingListItem components for displaying the items entered.
- The component requires an attribute named items with the type of an array of camping item custom objects.
- The component requires an attribute named newItem of type Camping_Item__c with default quantity and price values of 0.
- The component displays the Name, Quantity, Price, and Packed form fields with the appropriate input component types and values from the newItem attribute.
- The JavaScript controller checks to ensure that the Name, Quantity and Price values submitted are not null.
- If the form is valid, the JavaScript controller pushes the newItem onto the array of existing items, triggers the notification that the items value provider has changed, and resets the newItem value provider with a blank sObjectType of Camping_Item__c.
My Code:
CampingList.cmp
<aura:component > <ol> <li>Bug Spray</li> <li>Bear Repellant</li> <li>Goat Food</li> </ol> <aura:attribute name="items" type="Camping_Item__c[]"/> <aura:attribute name="newItem" type="Camping_Item__c" default="{'sobjectType': 'Camping_Item__c', 'Name': '', 'Price__c': 0, 'Quantity__c': 0, 'Packed__c': false }"/> <div style = "slds"> <div class="slds-col slds-col--padded slds-p-top--large"> <div aria-labelledby="newform"> <fieldset class="slds-box slds-theme--default slds-container--small"> <legend id="newform" class="slds-text-heading--small slds-p-vertical--medium">New Form</legend> <form class="slds-form--stacked"> <div class="slds-form-element slds-is-required"> <div class="slds-form-element__control"> <ui:inputText aura:id="formname" label="Name" class="slds-input" labelClass="slds-form-element__label" value="{!v.newItem.Name}" required="true"/> </div> </div> <div class="slds-form-element slds-is-required"> <div class="slds-form-element__control"> <ui:inputCurrency aura:id="formprice" label="Price" class="slds-input" labelClass="slds-form-element__label" value="{!v.newItem.Price__c}" placeholder="0"/> </div> </div> <div class="slds-form-element"> <div class="slds-form-element__control"> <ui:inputNumber aura:id="formquantity" label="Quantity" class="slds-input" labelClass="slds-form-element__label" value="{!v.newItem.Quantity__c}" required="true" placeholder="0"/> </div> </div> <div class="slds-form-element"> <ui:inputCheckbox aura:id="formpacked" label="Packed?" class="slds-checkbox" labelClass="slds-form-element__label" value="{!v.newItem.Packed__c}"/> </div> <div class="slds-form-element"> <ui:button label="Create Form" class="slds-button slds-button--brand" press="{!c.clickCreateFormData}"/> </div> </form> </fieldset> </div> </div> <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="items"> <c:campingListItem item="{!items}"/> </aura:iteration> </div> </section> </div> </div> </aura:component>CampingListController.js:
({ clickCreateFormData: function(component, event, helper) { var validitem = true; var nameField = component.find("formname"); var expname = nameField.get("v.value"); if ($A.util.isEmpty(expname)){ validitem = false; nameField.set("v.errors", [{message:"Expense name can't be blank."}]); } else { nameField.set("v.errors",null); } var priceField = component.find("formprice"); var expprice = nameField.get("v.value"); if ($A.util.isEmpty(expprice)){ validitem = false; priceField.set("v.errors", [{message:"Expense price can't be blank."}]); } else{ priceField.set("v.errors",null); } var quantityField = component.find("formquantity"); var expquantity = nameField.get("v.value"); if ($A.util.isEmpty(expquantity)){ validitem = false; quantityField.set("v.errors", [{message:"Expense quantity can't be blank."}]); } else{ quantityField.set("v.errors",null); } /* if(validExpense){ var newItem = component.get("v.newItem"); console.log("Create item: " + JSON.stringify(newItem)); helper.createExpense(component, newItem); } */ if(validitem){ var newItem = component.get("v.newItem"); console.log("Create item: " + JSON.stringify(newItem)); var theItem = component.get("v.items"); var newItem = JSON.parse(JSON.stringify(newItem)); theItem.push(newItem); component.set("v.newItem",newItem); } component.set("v.newItem",{'sobjectType': 'Camping_Item__c', 'Name': '', 'Price__c': 0, 'Quantity__c': 0, 'Packed__c': false }); } })CampingListItem.cmp:
<aura:component implements="force:appHostable"> <aura:attribute name="item" type="Camping_Item__c"/> <p>The Item is: <ui:outputText value="{!v.item}" /> </p> <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> <!-- <p> <ui:button label="Packed!" press="{!c.packItem}"/> </p> --> </aura:component>
Could anyone help pass and run the challenge.
Thanks.
Hi @Jeff Douglas,
Could you please help in solving the above query?
Thanks,
Yashita.
Jeff Douglas
Trailhead Developer Advocate
With the help of @Shobhit following the thread ( https://developer.salesforce.com/forums/ForumsMain?id=906F0000000kDD0IAM ). I am able to complete the challenge and run it.
However, am not sure if my question is valid - As per problem statement the last bullet point it says 'If the form is valid, the JavaScript controller pushes the newItem onto the array of existing items, triggers the notification that the items value provider has changed, and resets the newItem value provider with a blank sObjectType of Camping_Item__c.'
Specifically, triggers the notification that the items value provider has changed,
The code is not fulfilling the requirement so how to go about it. Could anyone please help me understand.
Thanks.
Here you are not been able to understand the language of the question.
Basically,triggering means that values goes from one place (exit),at the same time enters a new place.
So by triggers the notification that the items value provider has changed, they mean to say that :Whenever we create a 'newItem',it triggers(exits from newItem & simultaneously enters into items) its values into the 'items' array, and resets itself to a blank sObject Type.
I hope you understand what I mean to say.
Shobhit Saxena
Thanks for the explanation @Shobhit.
Jeff Douglas
Trailhead Developer Advocate
I have tried the challenge recently. I faced the below error -
Challenge Not yet complete... here's what's wrong:
ThecampingList component doesn't appear to have a Quantity input field in the form using a Lightning Base component.
Below is the piece of code -
campingList.cmp
controller
Please help me out to complete this challenge.
One more question about header code for this task
Similar to the unit, style the Camping List H1 inside the slds-page-header. Add the action:goal SLDS icon using lightning:icon.
I try some code from doc similar to
but can't understand how I can use image and header ?
Thank for answer(s)
On ussing lightning base components, it says
"The campingList component doesn't appear to have a Quantity input field in the form using a Lightning Base component."
below is the code with lightning base component for form. and it throws above error. Not able to identify what is the error.
<form aura:id="campingItemInputForm">
<Table>
<tr>
<lightning:input aura:id="name" label="Name" placeholder="Name" value="{!v.newItem.Name}"/>
</tr>
<tr>
<lightning:input aura:id="quantity" name="quantity" value="{!v.newItem.Quantity__c}" label="Quantity" type="number" required="true"/>
</tr>
<tr>
<lightning:input aura:id="price" label="Price" placeholder="price" type="number" value="{!v.newItem.Price__c}" required="true" formatter="currency" step="0.01"/>
</tr>
<tr>
<lightning:input type="checkbox" label="Packed ?" name="packed" checked="{!v.newItem.Packed__c}" />
</tr>
</Table>
<lightning:button aura:id="createItem" type="createItem" label="createItem" onclick="{! c.clickCreateItem }" />
</form>
The campingList component doesn't appear to have a Quantity input field in the form using a Lightning Base component."
I did update teh camplingListForm from ui to lighting components. What is even more puzzling to me is that I had first received this error on the name field. I changed all the fields to lightning components and I no longer get the error on the name, I get it on the Quantity. I have spent a week on this last part of the trail. If anyone could help me it would be greatly appreciated. What am I missing? thanks!!!!
I am experiencing the exact same error, so I am assuming there might be something wrong with the challenge?
I am also facing the same issue. If anyone is able to complete it , please provide the steps and code.
Thanks,
Vishnu
The application works as described but I can not pass the challenge.
Component:
<aura:component >
<aura:attribute name="newItem" type="Camping_Item__c" default="{ 'sobjectType': 'Camping_Item__c',
'Name': '',
'Quantity__c': '0',
'Price__c': 0,
'Packed__c': false}"/>
<aura:attribute name="items" type="Camping_Item__c[]"/>
<div class="slds-col slds-col--padded slds-p-top--large">
<div aria-labelledby="newItemform">
<fieldset class="slds-box slds-theme--default slds-container--small">
<legend id="newexpenseform" class="slds-text-heading--small slds-p-vertical--medium">
Add Camping Item
</legend>
<form class="slds-form--stacked">
<div class="slds-form-element slds-is-required">
<div class="slds-form-element__control">
<lightning:input name="expname" label="Camping Item Name"
class="slds-input slds-form-element__label"
value="{!v.newItem.Name}" aura:id="expname"
required="true"/>
</div>
</div>
<div class="slds-form-element slds-is-required">
<div class="slds-form-element__control">
<lightning:input type="number" label="Quantity" maxlength="10" min="1"
name="quantity" class="slds-input slds-form-element__label"
value="{!v.newItem.Quantity__c}" aura:id="quantity"
required="true"/>
</div>
</div>
<div class="slds-form-element">
<div class="slds-form-element__control">
<lightning:input type="number" name="price" label="Price" formatter="currency" step="0.01"
class="slds-input slds-form-element__label"
value="{!v.newItem.Price__c}" aura:id="price"
/>
</div>
</div>
<div class="slds-form-element">
<lightning:input type="checkbox" name="packed" label="Packed"
class="slds-checkbox slds-form-element__label"
aura:id="packed"
value="{!v.newItem.Packed__c}"
onchange="{!c.onChange}"/>
</div>
<div class="slds-form-element">
<lightning:button label="Create Expense"
class="slds-button slds-button--brand"
onclick="{!c.clickCreateItem}"/>
</div>
</form>
</fieldset>
</div>
</div>
<section class ="slds-card__body">
<div id="list" class = "row">
<aura:iteration items="{!v.items}" var="item">
<c:campingListItem item="{!item}"/>
</aura:iteration>
</div>
</section>
</aura:component>
Controller
({
clickCreateItem: function(component, event, helper) {
// Simplistic error checking
var validCamp = true;
// get Value from expname input
var textField = component.find("expname");
console.log("--textField--"+textField);
var textValue = textField.get("v.value");
console.log('textValue = '+textValue);
// get Value from quantity input
var quantityField = component.find("quantity");
console.log("--quantityField--"+quantityField);
var quantityValue = quantityField.get("v.value");
console.log('quantityValue = '+quantityValue);
// get Value from price input
var priceField = component.find("price");
console.log("--priceField--"+priceField);
var priceValue = priceField.get("v.value");
console.log('priceValue = '+priceValue);
// get Value from checkMark
var checkmarkField = component.find("packed");
console.log("--checkmarkField--"+checkmarkField);
var checkmarkValue = component.get("v.newItem.Packed__c");
console.log('checkmarkValue = '+checkmarkValue);
// //TEST INPUT
if ($A.util.isEmpty(textValue)){
validCamp = false;
textField.set("v.errors", [{message:"Camping Item name can't be blank."}]);
}
else {
textField.set("v.errors", null);
}
if (validCamp == true && quantityValue < 1){
validCamp = false;
quantityField.set("v.errors", [{message:"Camping Item's quantity should be greater or equal 1."}]);
}
else {
quantityField.set("v.errors", null);
}
priceField.set("v.errors", null);
checkmarkField.set("v.errors", null);
//
// //LOGIC
//
if(validCamp){
//
var itemObj = component.get("v.newItem");
itemObj.Packed__c = checkmarkValue;
console.log("---itemObj---"+JSON.stringify(itemObj));
console.log("Create camping item : " + JSON.stringify(itemObj));
var theItems = component.get("v.items");
// Copy the expense to a new object
//var newItem = JSON.parse(JSON.stringify(itemObj));
var newItem = itemObj;
console.log("Expenses before 'create': " + JSON.stringify(theItems));
theItems.push(newItem);
component.set("v.items", theItems);
console.log("Expenses after 'create': " + JSON.stringify(theItems));
var newItemObj = { 'sobjectType': 'Camping_Item__c',
'Name': '',
'Quantity__c': 0,
'Price__c': 0,
'Packed__c': false};
//resetting the Values in the form
component.set("v.newItem",newItemObj);
alert('the items value provider has changed');
}
},
onChange : function(component, event, helper) {
var packedBool = component.get("v.newItem.Packed__c");
console.log('packedBool1 =', packedBool);
if(packedBool === false){
packedBool = true;
} else {
packedBool = false;
}
console.log('packedBool2 =', packedBool);
component.set('v.newItem.Packed__c',packedBool);
}
})
1. Challenge has been changed. Quantity now needs to have a minimum value of 1. So you need to add min="1" as an attribute to the Quantity input, like this:
2. This is wrong:
This is correct:
I modified the code by Ruben Halman to suit the necessities of the challenge.
The code below should be good enough to clear the test.
Please mark this as the best answer if it helps you.
Thanks.
campinglist.cmp
campingListController.js
CampingList.cmp CampingListController.js
You can get complete answer here.
http://faizanaz90.blogspot.com/2017/11/lightning-components-basics-input-data.html
I have tried a given example in "Lightning Components Basics - Input Data Using Forms", but it's not accepting input data.
Please help me out in this.
Thanks,
Srinivas K
I am trying to complete this challenge, but getting below error-
This page has an error. You might just need to refresh it.
Action failed: lightning:formattedNumber$controller$init [Value Currency out of range for numberformat options property style]
Failing descriptor: {lightning:formattedNumber$controller$init}
I referred the doc- https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_formattedNumber.htm
Everything seems to be fine. Below is my code.
campinglist.cmp:-
campingListController.js:
CampingListitem.cmp
CampingListItemController.js
Thanks,
Manish