function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Yashita Goyal 17Yashita Goyal 17 

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.
  • 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.
Yashita Goyal 12Yashita Goyal 12

Hi @Jeff Douglas,

Could you please help in solving the above query?

Thanks,
Yashita.
 
Timothy WinterTimothy Winter
What is the error you are receiving?
Jeff DouglasJeff Douglas
What is the error you are receiving?

Jeff Douglas
Trailhead Developer Advocate
Yashita Goyal 17Yashita Goyal 17
Hi,

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.
Shobhit SaxenaShobhit Saxena
Hello @Yashita,
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
Yashita Goyal 17Yashita Goyal 17
oh ok...got it. I thought we had to do something with aura:valueChange and was trying to do something for triggering part. :P

Thanks for the explanation @Shobhit.
Jeff DouglasJeff Douglas
We just updated this module with some new code. Please try the challenge check again. Sorry for the inconvenience. 

​Jeff Douglas
Trailhead Developer Advocate
Ashish Goyal 63Ashish Goyal 63
Hello @Jeff Douglas,

I have tried the challenge recently. I faced the below error -

Challenge Not yet complete... here's what's wrong: 
The
campingList 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
 
<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" 
                                name="quantity" class="slds-input slds-form-element__label"
                                value="{!v.newItem.Quantity__c}" aura:id="amount"
                                required="true"/>
                        </div>
                    </div>
    
                    <div class="slds-form-element">
                        <div class="slds-form-element__control">
                            <lightning:input type="number" name="price" label="Price"
                              class="slds-input slds-form-element__label"
                              value="{!v.newItem.Price__c}"
                              placeholder="ABC Co."/>
                        </div>
                    </div>
    
                    <div class="slds-form-element">
                        <lightning:input type="checkbox" name="packed" label="Packed"
                          class="slds-checkbox slds-form-element__label"
                          value="{!v.newItem.Packed__c}"/>
                    </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;
        var nameField = component.find("expname");
        console.log("--nameField--"+nameField);
        var expname = nameField.get("v.value");
        var campQuantityField = component.find("quantity")
        var campQuantity = campQuantityField.get("v.value");

        if ($A.util.isEmpty(expname)){
            validCamp = false;
            nameField.set("v.errors", [{message:"Camping Item name can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
        
        if (validCamp == true && campQuantity < 1){
            validCamp = false;
            campQuantityField.set("v.errors", [{message:"Camping Item's quantity should be greater or equal 1."}]);
        }
        else {
            campQuantityField.set("v.errors", null);
        }

        if(validCamp){
            var itemObj = component.get("v.newItem");
            console.log("---itemObj---"+itemObj);
            console.log("Create camping item : " + JSON.stringify(itemObj));
            var theItems = component.get("v.items");
 
        // Copy the expense to a new object
        // THIS IS A DISGUSTING, TEMPORARY HACK
        
            var newItem = JSON.parse(JSON.stringify(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 };
                        //resetting the Values in the form
            component.set("v.newItem",newItemObj);
            alert('the items value provider has changed');
        }
    }
    }
})

Please help me out to complete this challenge.
Andrejs VeliksAndrejs Veliks
Hi! 
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 
<div class="slds-page-header">
      <div class="slds-media">
   	 	<div class="slds-media__figure">
      		<span class="slds-icon_container slds-icon-standard-opportunity" >
        		<svg class="slds-icon" aria-hidden="true">
          			<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#opportunity"></use>
        		</svg>
      		</span>
    	</div>
    	<div class="slds-media__body">
      		<h1 class="slds-page-header__title">Camping List</h1>
      		
    	</div>
  	  </div>
	</div>

but can't understand how I can use image and header ?

Thank for answer(s) 
Pradeep Kiran VeeravalliPradeep Kiran Veeravalli
 No more UI components are getting accepted. clearly saying use lightning base components.
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>
fredkafredka
I am experiencing the same issue. I am getting the error, "Challenge Not yet complete... here's what's wrong: 
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!!!!
<aura:component >
    <aura:registerEvent name="addItem" type="c:addItemEvent"/>
    
    <aura:attribute name="newItem" type="Camping_Item__c"
                    default="{ 'sobjectType': 'Camping_Item__c',
                             'Name': '',
                             'Quantity__c': 0,
                             'Price__c': 0,
                             'Packed__c': false }"/>

	<form class="slds-form--stacked">
        
     <tr>
        <lightning:input name="Name" value="{!v.newItem.Name}" required="True"/>
     </tr> 

     <tr>
        <lightning:input aura:id="Quantity" name="Quantity" value="{!v.newItem.Quantity__c}" label="Quantity" type="number" required="true"/>
     </tr>
      
     <tr>
        <lightning:input  type="number" name="Price" value="{!v.newItem.Price__c}" formatter="currency" required="True"/>
     </tr>

     <tr>
         <lightning:input  type="checkbox" name="Packed" value="{!v.newItem.Packed__c}" />
     </tr>

      <div class="slds-form-element">
          <ui:button label="Create Camping Item"
              class="slds-button slds-button--brand"
              press="{!c.clickCreateItem}"/>
      </div>
      
    </form>
</aura:component>

 
Ruben HalmanRuben Halman
+1,

I am experiencing the exact same error, so I am assuming there might be something wrong with the challenge?
Vishnu Prasad 18Vishnu Prasad 18
Hi

I am also facing the same issue. If anyone is able to complete it , please provide the steps and code.

Thanks,
  Vishnu
Ruben HalmanRuben Halman

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);
        }
})

Brendan Keogh 3Brendan Keogh 3
I am seeing the same thing here. I have pasted the component form in the parent and still nothing. I have verified it all works as expected.
Ivan VrtacnikIvan Vrtacnik
I have finally managed to pass this challenge. There are two errors everyone here is making, one of which was holding me up:

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:
 
<lightning:input value="{!v.newItem.Quantity__c}" type="number" min="1" aura:id="itemForm"></lightning:input>

2. This is wrong:
 
<lightning:input value="{!v.newItem.Packed__c}" type="checkbox" aura:id="itemForm" />

This is correct:
 
<lightning:input checked="{!v.newItem.Packed__c}" type="checkbox" aura:id="itemForm" />

​​
Mars Rover 744Mars Rover 744
Make sure the controller class checks the form thoroughly as shown in practice exercises above the challenge.
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
<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 checked="{!v.newItem.Packed__c}" type="checkbox" aura:id="itemForm" />
                                        
                    </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>

campingListController.js
 
({
    clickCreateItem: function(component, event, helper) {        
        // Simplistic error checking
        var validCamp = true;
        var nameField = component.find("expname");
        console.log("--nameField--"+nameField);
        var expname = nameField.get("v.value");
        var campQuantityField = component.find("quantity")
        var campQuantity = campQuantityField.get("v.value");

         var validcamp = component.find('newexpenseform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        
        if ($A.util.isEmpty(expname)){
            validCamp = false;
            nameField.set("v.errors", [{message:"Camping Item name can't be blank."}]);
        expname.showHelpMessageIfInvalid();
            return "v.errors";
        }
                if (validCamp == true && campQuantity < 1){
            validCamp = false;
            campQuantityField.set("v.errors", [{message:"Camping Item's quantity should be greater or equal 1."}]);
                    return "v.errors";
                }
        if(validCamp){
            var itemObj = component.get("v.newItem");
            console.log("---itemObj---"+itemObj);
            console.log("Create camping item : " + JSON.stringify(itemObj));
            var theItems = component.get("v.items");
 
        // Copy the expense to a new object
        // THIS IS A DISGUSTING, TEMPORARY HACK
        
            var newItem = JSON.parse(JSON.stringify(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 };
                        //resetting the Values in the form
            component.set("v.newItem",newItemObj);
            alert('the items value provider has changed');
        }
    }
    }
})


 
Kalyani KhuspeKalyani Khuspe
I completed Challenge as well as it displays items created

CampingList.cmp
<aura:component >
    
    <aura:attribute name="newItem" type="Camping_Item__c" 
                    default="{'sobjectType':'Camping_Item__c',
                             'Name':'',
                             'Price__c':0,
                             'Quantity__c':0,
                             'Packed__c':false   
                             }"/>
    
    <aura:attribute name="items" type="Camping_Item__c[]"/>
    <ol>
        <li>Bug Spray</li>
        <li>Bear Repellant</li>
        <li>Goat Food</li>
    </ol>
    <!-- NEW EXPENSE FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">
            
            <!-- CREATE NEW ITEM -->
            <div aria-labelledby="newcampingform">
                <!-- BOXED AREA -->
                <fieldset class="slds-box slds-theme--default slds-container--small">
                    <legend id="newcampingform" class="slds-text-heading--small slds-p-vertical--medium">
                        Camping List
                    </legend>
                    
                    <!-- CREATE NEW CAMPING FORM -->
                    
                    <form class="slds-form--stacked">  
                        <lightning:input aura:id="campform" label="Name"
                                         name="campingitem"
                                         value="{!v.newItem.Name}"
                                         required="true"
                                         messageWhenValueMissing="Did you forget me?"
                                         />
                        
                        <lightning:input type="number" aura:id="campform" label="Price"
                                         name="campPrice"
                                         formatter="currency"
                                         value="{!v.newItem.Price__c}"
                                         messageWhenValueMissing="It's not Free enter Price, Please!"/>
                        
                        <lightning:input type="number" aura:id="campform" label="Quantity"
                                         name="campQuantity"
                                         min="1"
                                         value="{!v.newItem.Quantity__c}"
                                         messageWhenRangeUnderflow="Enter at least 1 quantity."/>
                        
                        <lightning:input type="checkbox" aura:id="campform" label="Packed?" 
                                         name="camppacked"
                                         checked="{!v.newItem.Packed__c}"/>
                        
                        <lightning:button label="Create Camping Item"
                                          class="slds-m-top--medium"
                                          variant="brand"
                                          onclick="{!c.clickCreateItem}"/>
                        
                    </form>
                    
                    
                    <!-- / NEW EXPENSE FORM -->
                    
                    <!-- / CREATE NEW CAMPING ITEM -->
                    <aura:iteration items="{!v.items}" var="camp">
                        <c:campingListItem item="{!camp}"/>
                    </aura:iteration>
                </fieldset>
                <!-- / BOXED AREA -->
            </div>
        </lightning:layoutItem>
    </lightning:layout>
</aura:component>
CampingListController.js
({
    clickCreateItem : function(component, event, helper) {
        var validCampItem = component.find('campform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validCampItem){
            // Create the new expense
            var newCampItem = component.get("v.newItem");
            console.log("Create Camp Item: " + JSON.stringify(newCampItem));
            var Item = component.get("v.items");
            // Copy the camping to a new object
            // THIS IS A DISGUSTING, TEMPORARY HACK
            var theItem = JSON.parse(JSON.stringify(Item));
            
            theItem.push(newCampItem);
            component.set("v.items", newCampItem);
            component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                                       'Name': '',
                                       'Quantity__c': 0,
                                       'Price__c': 0,
                                       'Packed__c': false });
            
            
        }
    }
})


 
Faiza Naz 10Faiza Naz 10
Hi,
You can get complete answer here.
http://faizanaz90.blogspot.com/2017/11/lightning-components-basics-input-data.html
Srini KanuriSrini Kanuri
Hi,

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
Manish Anand 22Manish Anand 22
Hi All,

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:-
 
<aura:component >
    <aura:attribute name="items" type="Camping_Item__c[]" />
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'sObjectType' :'Camping_Item__c',
                                                                   'Quantity__c' : 0 ,
                                                                    'Price__c' : 0,
                                                                    'Packed__c' : false 
                                                                    }" />
   
    <form class="slds-form--stacked">   
    
     <lightning:input aura:id="campingform" label="Name"
                      name="campingname"
                      value="{!v.newItem.Name}"
                      required="true"
                      />
      <lightning:input aura:id="campingform" label="Quantity"
                       name="campingquantity"
                       min="1"
                       step="1"
                       value="{!v.newItem.Quantity__c}"
                       messageWhenRangeUnderflow="Enter atleast 1 quantity."
                       />
      <lightning:input aura:id="campingform" label="Price"
                       name="campingprice"
                       formatter="currency"
                       value="{!v.newItem.Price__c}"
                       messageWhenValueMissing="Did you forget me?"
                       />
         <lightning:input type="checkbox" aura:id="campingform" label="Packed?" 
                                         name="campingpacked"
                                         checked="{!v.newItem.Packed__c}"/>
        
      <lightning:button label="Create Camping" 
                        class="slds-m-top--medium"
                        variant="brand"
                        onclick="{!c.clickCreateItem}"/>
    </form>
     <lightning:card title="Campings">
        <p class="slds-p-horizontal--small">
            <aura:iteration items="{!v.items}" var="itm">
                <c:campingListItem item="{!itm}"/>
            </aura:iteration>
        </p>
    </lightning:card>	
</aura:component>

campingListController.js:
({
	clickCreateItem : function(component, event, helper) {
        var validCamping = component.find('campingform').reduce(function (validSoFar,inputCmp){
        inputCmp.showHelpMessageIfInvalid();
        return validSoFar && inputCmp.get('v.validity').valid;
    }, true );
	if(validCamping)
    {
       var newCamping1 = component.get("v.newItem");
       console.log("Create Camping :" + JSON.stringify(newCamping1));
      // createCamping(component,newcamping);
       var theCampings = component.get("v.items");
       var newCamping = JSON.parse(JSON.stringify(newCamping1));
       console.log("Expenses before 'create': " + JSON.stringify(theCampings));
       theCampings.push(newCamping);
       component.set("v.items", theCampings);
       console.log("Expenses after 'create': " + JSON.stringify(theCampings));
       component.set("v.newItem",{ 'sobjectType': 'Camping_Item__c',
                    'Name': '',
                    'Quantity__c': 0.0,
                    'Price__c': 0,
                    'Packed__c': false });
    }
	}
   
  
})

CampingListitem.cmp
<aura:component >
	<aura:attribute name="item" type="Camping_Item__c" default="{'sobjectType':'Camping_Item__c',
                                                                'Packed__c':false}" required="True" />
    <P>
        Name : {!v.item.name}    </P>
    <P> 
        Price :
        <lightning:formattednumber value="{!v.item.Price__c}" style="Currency" />
    </P>
    <P>
        Quantity : 
        <lightning:formattednumber value="{!v.item.Quantity__c}" style="Decimal" />
    </P>
    <P>
        <lightning:input type="toggle" 
                         label="Packed?"
                         name="packed"
                         checked="{!v.item.Packed__c}" />
    </P>
    <p>
        <lightning:button label="Packed!" onclick="{!c.packItem}" />
    </p>
</aura:component>

CampingListItemController.js
({
	packItem : function(component, event, helper) {
		// component.set("v.item.packed", true);
		 var a = component.get("v.item",true);
        a.Packed__c = true;
        component.set("v.item",a);
        var btn = event.getSource();
        btn.set("v.disabled",true)
	}
})

​​Thanks,
Manish