Develop a Simple To-Do List App With Salesforce Lightning Component
Hey guys, today in this post we are going to create a very simple custom To-Do List app with salesforce lightning component and custom object.
Prerequisite :
- Create salesforce custom object with following custom fields :
Resource | Name [API] | Type | Description |
Custom Object | ToDo__c | – | To store To-Do Items data in Salesforce database |
Custom Fields | Description__c | Long Text Area | To-Do task description |
Due_Date__c | Date | To store due date of task | |
Reminder_Date__c | Date | To store reminder date of task | |
Name | Auto number | Standard field |
Step 1 : Apex Controller :
/* * Source : sfdcMonkey.com * Date : 4/30/2019 * API : 45.00 */ public with sharing class ToDoController { //Method to return list of toDo records during component initialization @AuraEnabled public static List<ToDo__c> loadData(){ return [SELECT ID,Reminder_Date__c,Due_Date__c,Description__c FROM ToDo__c ORDER BY Due_Date__c ASC NULLS LAST]; } //Method to save the record in database and return error message @AuraEnabled public static String saveTodoRecord(ToDo__c toDoRecord){ String message; Database.saveResult sr = Database.insert(toDoRecord,false); if(!sr.isSuccess()){ for(Database.error err : sr.getErrors()){ message += err.getMessage(); } } return message; } }
Step 2 : Lightning Component :
<!--/* * Source : sfdcMonkey.com * Date : 4/30/2019 * API : 45.00 */ --> <aura:component controller="ToDoController" implements="flexiPage:availableForAllPageTypes"> <!--Componnet init handler --> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <!--AURA ATTRIBUTES START--> <aura:attribute name="todocolumns" type="List"/> <aura:attribute name="todoData" type="Object"/> <aura:attribute name="today" type="Date" description="To set todays date as mimimum value for Due date and reminder date"/> <aura:attribute name="objToDo" type="ToDo__c" default="{'sobjectType' : 'ToDo__c'}"/> <!--AURA ATTRIBUTES END--> <!--TO DO Form START--> <lightning:card title="Add New Task"> <aura:set attribute="actions"> <lightning:buttonicon iconName="utility:chevrondown" alternativeText="down icon" onclick="{!c.toggleForm}"/> </aura:set> <div aura:id="formDiv" class="slds-size_1-of-1 slds-p-around_medium"> <lightning:textarea aura:id="todoForm" type="String" label="Task Description" value="{!v.objToDo.Description__c}" required="true" messageWhenValueMissing="Enter description" /> <lightning:input aura:id="todoForm" type="Date" label="Due date" value="{!v.objToDo.Due_Date__c}" required="true" messageWhenValueMissing="Enter due date" min="{!v.today}" onchange="{!c.setMaxValueOfReminderDate}"/> <lightning:input aura:id="reminderDate" type="Date" disabled="true" label="Reminder date" value="{!v.objToDo.Reminder_Date__c}" min="{!v.today}"/> <lightning:button class="slds-m-top_small" label="Create Task" variant="brand" onclick="{!c.saveTodo}"/> </div> </lightning:card> <!--TO DO Form END--> <div class="slds-m-vertical_large"> <!--Lightning data table definition to display all To-Do Tasks--> <lightning:datatable aura:id="tableId" keyField="Id" columns="{!v.todocolumns}" data="{!v.todoData}" hideCheckboxColumn="true"/> </div> </aura:component>
JavaScript Controller :
({ //Method to set columns and data for datatable doInit : function(component,event,helper){ // create current date instance var now = new Date(); var date = now.getDate(); var month = now.getMonth() + 1; var fullYear = now.getFullYear(); var today = fullYear + '-' + month + '-' + date; component.set("v.today", today); // set lightning datatable columns component.set("v.todocolumns",[ { label:'Description', fieldName : 'linkToRecord', type:'url', typeAttributes:{label:{fieldName:'Description__c'},target:'_blank'}//to display link to record page }, { label :'Due Date', fieldName:'Due_Date__c', type:'date', typeAttributes:{day:'2-digit',month:'long',year:'2-digit'} }, { label:'Reminder Date', fieldName:'Reminder_Date__c', type:'date', typeAttributes:{day:'2-digit',month:'long',year:'2-digit'} } ]); // call helper function to get records data helper.getData(component,event,helper); }, toggleForm : function(component,event,helper){ // change toggle button icon var evtSource = event.getSource(); if(evtSource.get("v.iconName") === 'utility:chevrondown'){ evtSource.set("v.iconName" , 'utility:chevronright' ); }else{ evtSource.set("v.iconName" , 'utility:chevrondown' ); } //To show/hide form elements $A.util.toggleClass(component.find("formDiv"),'slds-hide'); }, saveTodo : function(component,event,helper){ //If form data is valid , save record in database if(helper.validateData(component,event,helper)){ //Appending the new todo entry in datatable var objToDo = component.get("v.objToDo"); //call saveTodoRecord server side method to save todo record var action = component.get("c.saveTodoRecord"); action.setParams({ toDoRecord : objToDo }); action.setCallback(this,function(response){ var state = response.getState(); if(state == "SUCCESS"){ var toastRef = $A.get("e.force:showToast"); if(response.getReturnValue() == null){ toastRef.setParams({ "type" : "Success", "title" : "Success", "message" : "New Task is Created.", "mode" : "dismissible" }); } else{ toastRef.setParams({ "type" : "Error", "title" : "Error", "message" : response.getReturnValue(), "mode" : "sticky" }); } toastRef.fire(); $A.get("e.force:refreshView").fire(); } else{ //To handle server error console.log('Error during saving '+state); } }); $A.enqueueAction(action); } }, setMaxValueOfReminderDate : function(component, event, helper){ var dueDate = event.getSource().get("v.value"); component.find("reminderDate").set("v.value",''); //Once due date is entered , reminder date is enabled if(dueDate != null && dueDate != ''){ component.find("reminderDate").set("v.disabled",false); //set max date limit for reminder date component.find("reminderDate").set("v.max",dueDate); } else{ component.find("reminderDate").set("v.disabled",true); } } })
JavaScript Helper :
({ getData : function(component,event,helper){ //call loadData server side method to get the toDo records var action = component.get("c.loadData"); action.setCallback(this,function(response){ var state = response.getState(); if(state == "SUCCESS"){ var dotoList = response.getReturnValue(); for(var i=0; i < dotoList.length;i++){ //To display description of todo item as link dotoList[i].linkToRecord = '/'+dotoList[i].Id; } component.set("v.todoData",dotoList); } else{ //To handle server error console.log('Error occured while init of data '+state); } }); $A.enqueueAction(action); }, validateData : function(component, event, helper){ var isValid = component.find("todoForm").reduce(function(validSoFar,inputComp){ //To display error message when user saves the form with invalid data inputComp.showHelpMessageIfInvalid(); return validSoFar && inputComp.get("v.validity").valid; },true); return isValid; } })
- Check code comments.
Output :
Related Resources :
Other popular Post :
- Mark Locations On Google Map With Salesforce Lightning Component
- How To Fetch Multi Picklist Values From sObject To lightning:dualListbox Component
- How to Create Lightning Web Component And Deploy To The Salesforce Org
- Custom Multi-Select Picklist In Lightning Component With Select2 jQuery Plugin
- Powerful Lightning Datatable base component – Example Using Fieldset
- Add Delete Row Dynamic In Lightning Component : Sample Code
- Data Table With Pagination Buttons in Lightning Component
Like our facebook page for new post updates. & Don’t forget to bookmark this site for your future reference.
if you have any suggestions or issue with it, you can post in comment box.
Happy Learning
About The contributor:
I have 3.5 years of experience and working in lightning for the past 1 year. I am working as a developer in Deloitte.
Skills : Apex ,lightning , visualforce,sales cloud,JavaScript,Einstein analytics
Post By Kiran :
11 comments
This page has an error. You might just need to refresh it. Aura.loadComponent(): Failed to initialize application. COMPONENT markup://c:ToDOList is missing required attribute ‘alternativeText’
i am getting error like this can you help me on this.
are you using same code ? or if you made any changes then please share you code/problem on developer forums in more details and share question URL here, so i can look into your issue. Thanks
https://developer.salesforce.com/forums
Hi Pavani,
Please replace,
in place of,
Your problem will be resolved.
Happy Learning 🙂
This page has an error. You might just need to refresh it. Aura.loadComponent(): Failed to initialize application. COMPONENT markup://c:ToDOList is missing required attribute ‘alternativeText’
i am getting error like this can you help me on this.
Hi Pavani,
Please replace,
<lightning:buttonicon iconName=”utility:chevrondown” onclick=”{!c.toggleForm}” alternativeText=”Toggle” />
in place of,
<lightning:buttonicon iconName=”utility:chevrondown” onclick=”{!c.toggleForm}” />
Your problem will be resolved.
Happy Learning 🙂
This page has an error. You might just need to refresh it. Error in $A.getCallback() [Cannot read property ‘setParams’ of undefined] Callback failed: apex://ToDoController/ACTION$saveTodoRecord Failing descriptor: {c:ToDoListComp}
used the same code but i got this error …can you please check on this
do not test it with stand alone lightning application because force ‘showToast’ and ‘refreshView’ events are handled by the app container. It’s supported in Lightning Experience, Salesforce app, and Lightning communities.
Thanks for the information, I will implement this code.
Why not Task object?
in this post we are just try to demonstrate that how we can develop own custom to do-list functionality in salesforce using custom lightning component. this will more flexible and control will be in hands.