to-do list in lightning component

Develop a Simple To-Do List App With Salesforce Lightning Component

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.

to do app demo salesforce
Output
Prerequisite :
  1. 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 :

to-do app demo salesforce

Related Resources :
Other popular Post :

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: 

Kiran.B

3 Post Contribute

kiran b sfdcMonkey

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 :

  1. How To Implement Infinity Or Lazy Loading In Salesforce Lightning DataTable
  2. How To Implement Column Sorting In Salesforce Lightning DataTable
  3. Develop a Simple To-Do List App With Salesforce Lightning Component

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.

     

  • 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.

    • 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.

Leave a Reply