Kanban Drag And Drop Lightning Component At A Glance
Drag and Drop lightning component

Kanban Drag And Drop Lightning Component At A Glance

Sharing is caring!

If you are making the use of the Salesforce Lightning interface, you must have come across the Kanban view while viewing the records list. Interestingly, it was one of the most demoed features as the interface was evolving. It allows users to drag-and-drop records from one column to another, active changing status.

USAGE 

 <c:KanbanBoard 

 objLabel=”Audit”  

 objectName=”Audits__c” 

 objFields=”[‘Name’, ‘Planned_Start_Date__c’,’Audit_Locations__c’, ‘Planned_Finish_Date__c’,  ‘Actual_Start_Date__c’,’Actual_Finish_Date__c’,’Audit_Type__c,Status__c’]”

 kanbanColumnField=”Audit_Type__c”

 KanbanRowField=”Status__c”/>

Step 1 : Create a lightning component KanbanBoard.cmp which will show the records on the basis of the column and row fields selected.

    <aura:attribute name=”objectName” type=”String”/>

    <aura:attribute name=”objFields” type=”String[]”/>

    <aura:attribute name=”RecordIdObj” type=”String”/>

    <aura:attribute name=”kanbanColumnField” type=”String”/>

    <aura:attribute name=”KanbanRowField” type=”String”/>

    <aura:attribute name=”objLabel” type=”String”/>

    <aura:attribute name=”isOpenUrl” type=”boolean” default=”false”/>

    <aura:attribute name=”FilteredRecordsList” type=”List” />

    <aura:attribute name=”DynamicFilteredList” type=”List” />

    <aura:attribute name=”sectionList” type=”List” />

    <!–  Attributes for Kanban View    –>

    <aura:attribute name=”showNewProduct” type=”boolean” default=”true”/>

    <aura:attribute name=”kanbanData” type=”kanbanController.kanbanWrap”/>

    <aura:attribute name=”isShowSpinner” type=”boolean” default=”false”/>

    <aura:handler name=”init” action=”{!c.doInit}” value=”{!this}”/>

    <aura:registerEvent name=”RecordIdForNavigation”type=”c:KanbanNavigateRecord”/>

 <!–Kanban For Audit –>

    <aura:if isTrue=”{! v.objectName == ‘Audits__c’}”>

        <div class=”slds-grid slds-grid_vertical” style=”width:100%;overflow-y: hidden;overflow-x: auto;”>

            <div class=”slds-grid slds-clearfix slds-col slds-m-top_x-small slds-m-bottom_x-small slds-m-left_large slds-m-right_large” style=””>

                <aura:iteration var=”pickValue” items=”{!v.kanbanData.pickVals}”>

                    <div class=”PickHeader slds-float_left slds-p-bottom_xx-small slds-p-top_xx-small slds-border_top slds-border_right slds-border_bottom slds-border_left slds-m-left_small slds-m-right_small” style=”min-width: 36.5vh;max-width: 37vh;” >

                        <h1 class=”” style=”text-align: center;” title=”{!pickValue}”>{!pickValue}</h1>

                    </div>

                </aura:iteration>

            </div><br/>

            <div  class=”” style=” overflow-y: auto;overflow-x: hidden;width: fit-content;height:30rem;”>

                <aura:iteration items=”{!v.DynamicFilteredList}” var=”RecordListMapObj” indexVar=”key”>

                    <aura:if isTrue=”{!RecordListMapObj.Size > 0}”>

                        <div class=”slds-grid”>

                            <div class=”slds-col slds-grow-none slds-m-left_large”>

                                <aura:iteration items=”{!v.sectionList}” var=”sectionListObj” indexVar=”key”>

                                    <aura:if isTrue=”{!(sectionListObj.divName == RecordListMapObj.divName)}”>

                                        <button class=”slds-button btn”  name=”{!RecordListMapObj.divName}” onclick=”{!c.showNewProduct}”>

                                            <aura:if isTrue=”{!sectionListObj.flag}”>

                                                <span><lightning:icon class=”icnCSS” iconName=”utility:chevrondown” alternativeText=”” title=”” /></span>

                                                <aura:set attribute=”else”>

                                                    <span><lightning:icon class=”icnCSS” iconName=”utility:chevronright” alternativeText=”” title=”” /></span>  

                                                </aura:set>

                                            </aura:if>

                                        </button>

                                    </aura:if>

                                </aura:iteration>

                            </div>

                            <div class=”slds-col slds-grow-none” style=”margin-top: 1vh;”> 

                                <h1>{!RecordListMapObj.Key}</h1>

                            </div>

                        </div>

                        <div aura:id=”sectionOne” class = “slds-clearfix slds-grid slds-col slds-m-left_small” data-id=”{!RecordListMapObj.divName}” style=”padding:0.5rem;”>

                            <aura:iteration var=”pickValue” items=”{!v.kanbanData.pickVals}”>

                                <div class=”stageContainer slds-float_left” style=”min-width:40vh”>

                                    <ul aura:id=”myDIV1″ ondrop=”{!c.drop}” ondragover=”{!c.allowDrop}” data-id=”{!RecordListMapObj.divName}” class=”slds-m-left_large slds-has-dividers_around-space dropZone” data-Pick-Val=”{!pickValue}” style=”max-height:39vh;overflow-y:auto;”>

                                        <aura:iteration items=”{!RecordListMapObj.Value}” var=”RecordListObj” indexVar=”key”>

                                            <aura:if isTrue=”{!pickValue == RecordListObj.Key}”>

                                                <aura:iteration items=”{!RecordListObj.Value}” var=”ColRecordListObj” indexVar=”key”>

                                                    <li class=”RecordDivCss slds-item slds-m-around_small” draggable=”true” ondragstart=”{!c.drag}” id=”{!ColRecordListObj.Id}”>

                                                        <article class=”slds-tile slds-tile_board”>

                                                            <h3 class=”slds-truncate” title=”{!ColRecordListObj.Name}”>

                                                                <a href=”javascript:void(0);” onclick=”{!c.doView}” >

                                                                    <span class=”slds-truncate linkCSS” id=”{!ColRecordListObj.Id}”>{!ColRecordListObj.Name}</span>

                                                                </a>

                                                            </h3>

                                                            <div class=”slds-tile__detail slds-text-body_small”>

                                                                <p class=”slds-truncate” style=”font-size: 13px;font-weight: 500;font-family: sans-serif;”><b>Planned Start Date: </b>{!ColRecordListObj.Planned_Start_Date__c}</p>

                                                                <p class=”slds-text-heading_medium” style=”font-size: 13px;font-weight: 500;font-family: sans-serif;”><b>Planned Finished Date: </b>{!ColRecordListObj.Planned_Finish_Date__c}</p>

                                                            </div> 

                                                        </article>

                                                    </li>

                                                </aura:iteration>

                                            </aura:if>

                                        </aura:iteration>

                                    </ul>

                                </div>

                            </aura:iteration>

                        </div>

                    </aura:if>

                </aura:iteration>

            </div>

        </div>

    </aura:if>

 <aura:if isTrue=”{!v.isOpenUrl}”>

        <!–###### MODAL BOX Start######–> 

        <section role=”dialog” tabindex=”-1″ aria-labelledby=”modal-heading-01″ aria-modal=”true” aria-describedby=”modal-content-id-1″ class=”slds-modal slds-fade-in-open” style=”box-shadow: 0px 1px 7px 2px lightgrey;”>

            <div class=”slds-modal__container”>

                <!– ###### MODAL BOX HEADER Start ######–>

                <header class=”slds-modal__header”>

                    <lightning:buttonIcon iconName=”utility:close”

                                          onclick=”{! c.closeModelUrl }”

                                          alternativeText=”close”

                                          variant=”bare-inverse”

                                          class=”slds-modal__close”/>

                    <h2 id=”modal-heading-01″ class=”slds-text-heading_medium slds-hyphenate”>{!v.objLabel}</h2>

                </header>

                <!–###### MODAL BOX BODY Part Start######–>

                <div class=”slds-modal__content slds-p-around_medium” id=”modal-content-id-1″>

                    <force:recordView recordId=”{!v.RecordIdObj}” />

                </div>

                <!–###### MODAL BOX FOOTER Part Start ######–>

                <footer class=”slds-modal__footer”>

                    <lightning:button variant=”brand” 

                                      label=”Close”

                                      onclick=”{! c.closeBox }”/>

                </footer>

            </div>

        </section>

        <div class=”slds-backdrop slds-backdrop_open”></div>

        <!–###### MODAL BOX Part END Here ######–>

    </aura:if>

</aura:component>

Step2: Create a client-side controller KanbanBoardController.js which handles the functionality of the Kanban Board and to control the drag and drop functionality of the records.

({

    doInit: function(component, event, helper) {

        component.set(‘v.isShowSpinner’,true);

        helper.doInit_helper(component, event, helper);

    },

    doView: function(c, e, h) {

        try{

           let recordId = event.target.id;

           c.set(‘v.RecordIdObj’,recordId);

           c.set(‘v.isOpenUrl’,true);

        }catch(ex){

            console.log(ex);

        }

    },

    allowDrop: function(component, event, helper) {

        event.preventDefault();

    },

    drag: function (component, event, helper) {

        event.dataTransfer.setData(“text”, event.target.id);

    },

    drop: function (component, event, helper) {

        try{

            event.preventDefault();

            var data = event.dataTransfer.getData(“text”);

            var tar = event.target;

            while(tar.tagName != ‘ul’ && tar.tagName != ‘UL’)

                tar = tar.parentElement;

            tar.appendChild(document.getElementById(data));

            // code for adjusting height of the kanban board dynamically

            let statusName = tar.getAttribute(‘data-Pick-Val’);

            let AllRecords = component.get(‘v.kanbanData.records’);

            let columnFieldValue = component.get(‘v.kanbanPicklistField’);

            let KanbanRowField = component.get(‘v.KanbanRowField’);

            for(let recObj in AllRecords){

                if(AllRecords[recObj].Id == data){

                    var map1 = new Map(Object.entries(AllRecords[recObj]));

                    var currentStatus = map1.get(columnFieldValue);

                    var recordType = map1.get(KanbanRowField);

                }

            }

            //get the list of records related to selected recordType

            var FilteredRecordsList = component.get(‘v.FilteredRecordsList’);

            var requiredListOfRecords = [];

            for(let listObject in FilteredRecordsList){

                if(FilteredRecordsList[listObject].Key == recordType){

                    requiredListOfRecords.push(FilteredRecordsList[listObject].Value);

                }

            }

            document.getElementById(data).style.backgroundColor = “#ffb75d”;

            helper.updatePickVal(component,data,component.get(“v.kanbanPicklistField”),statusName,helper);

            //code to update list and change the status of the record in the list

            var kanbanData = component.get(“v.kanbanData”);

            var AllRowListMap = new Map();

            let rowPickList = kanbanData.rowPickvalList;

            if(rowPickList.length > 0){

                for(let k=0;k<rowPickList.length;k++){

                    let newList = [];

                    AllRowListMap.set(rowPickList[k],newList);

                }

            } 

            //iterate records to fill map according to its Type

            var rowField = component.get(‘v.KanbanRowField’);

            for(let i=0;i<kanbanData.records.length;i++){

                let recordType = kanbanData.records[i];

                let map = new Map(Object.entries(recordType));

                if(map.has(rowField)){

                    if(recordType.Id == data){

                        map.delete(columnFieldValue);

                        map.set(columnFieldValue,statusName);

                        let obj = Object.fromEntries(map);

                        AllRowListMap.get(map.get(rowField)).push(obj);

                    }else{

                        AllRowListMap.get(map.get(rowField)).push(recordType);

                    }

                }

            }

            let FilteredRecordList = [];

            for(let mapObj in Array.from(AllRowListMap.entries())){

                let listMapObj = {};

                listMapObj.Key = Array.from(AllRowListMap.keys())[mapObj];

                listMapObj.Value = Array.from(AllRowListMap.get(listMapObj.Key));

                FilteredRecordList.push(listMapObj);

            }

            component.set(‘v.FilteredRecordsList’,FilteredRecordList);

            //set dynamic filtered list to update the record 

            let DynamicFilteredList = [];

            var ColumnWiseMap = new Map();

            var divCount = 1;

            for(let FilteredRecordListObj in FilteredRecordList){

                let divName = “myDIV”;

                divName += divCount;

                let outerWrapperObj = {};

                outerWrapperObj.Key = FilteredRecordList[FilteredRecordListObj].Key;

                outerWrapperObj.Size = FilteredRecordList[FilteredRecordListObj].Value.length;

                if(FilteredRecordList[FilteredRecordListObj].Value.length > 0){

                    let columnpickVals = kanbanData.pickVals;

                    if(columnpickVals.length > 0){                                

                        for(let m=0;m<columnpickVals.length;m++){

                            let newListObj = [];

                            ColumnWiseMap.set(columnpickVals[m],newListObj);

                        }

                    } 

                    var kanbanPicklistField = component.get(‘v.kanbanPicklistField’);

                    let listOfRecords = FilteredRecordList[FilteredRecordListObj].Value;

                    for(let recordsObj in listOfRecords){

                        let recordTypeObj = listOfRecords[recordsObj];

                        let mapNewObj = new Map(Object.entries(recordTypeObj));

                        if(mapNewObj.has(kanbanPicklistField)){

                            ColumnWiseMap.get(mapNewObj.get(kanbanPicklistField)).push(recordTypeObj);

                        }

                    }

                    let innerRecordList = [];

                    for(let mapObjnew in Array.from(ColumnWiseMap.entries())){

                        let listMapObjNew = {};

                        listMapObjNew.Key = Array.from(ColumnWiseMap.keys())[mapObjnew];

                        listMapObjNew.Value = Array.from(ColumnWiseMap.get(listMapObjNew.Key));

                        innerRecordList.push(listMapObjNew);

                    }

                    outerWrapperObj.flag = true;

                    outerWrapperObj.divName = divName;

                    outerWrapperObj.Value = innerRecordList;

                    DynamicFilteredList.push(outerWrapperObj);

                    divCount ++;

                }else{

                    outerWrapperObj.flag = true;

                    outerWrapperObj.divName = divName;         

                    outerWrapperObj.Value = [];

                    DynamicFilteredList.push(outerWrapperObj);

                    divCount ++;

                }

            }

            component.set(‘v.DynamicFilteredList’,DynamicFilteredList);

            // set kanban data list again

            let KanbanDataObj = {};

            KanbanDataObj.pickVals = kanbanData.pickVals;

            KanbanDataObj.records = [];

            KanbanDataObj.rowPickvalList = kanbanData.rowPickvalList;

            for(let kanRec in kanbanData.records){

                if(kanbanData.records[kanRec].Id == data){

                    let mapObjNew = new Map(Object.entries(kanbanData.records[kanRec]));

                    mapObjNew.delete(columnFieldValue);

                    mapObjNew.set(columnFieldValue,statusName);

                    let objectNew = Object.fromEntries(mapObjNew);

                    console.log(‘Object to push’+JSON.stringify(objectNew));

                    KanbanDataObj.records.push(objectNew);

                }

                else{

                    KanbanDataObj.records.push(kanbanData.records[kanRec]);

                }

            }

            component.set(“v.kanbanData”, KanbanDataObj);

            window.setTimeout(

                $A.getCallback(function (){

                    helper.setHeight(component, event ,helper);

                }), 1000

            );

        }catch(ex){

            console.log(ex);

        }

    },

    showNewProduct : function(c,e,h){

        try{

            let isClicked = c.get(‘v.showNewProduct’);

            let sectionOne = c.find(‘sectionOne’);

            let divName = e.currentTarget.getAttribute(“name”);

            let sectionList = c.get(‘v.sectionList’);

            let sectionListNew = [];

            if(isClicked){

                for(let i=0;i<sectionOne.length;i++){

                    let cmpObjThree = sectionOne[i].getElement().getAttribute(‘data-id’);

                    if(cmpObjThree === divName){

                        $A.util.toggleClass(sectionOne[i],’slds-hide’);

                    }

                }

                c.set(‘v.showNewProduct’,false);

            }else{

                for(let i=0;i<sectionOne.length;i++){

                    let cmpObjOne = sectionOne[i].getElement().getAttribute(‘data-id’);

                    if(cmpObjOne === divName){

                        $A.util.toggleClass(sectionOne[i],’slds-hide’);

                    }

                }

                c.set(‘v.showNewProduct’,true);

            }

            for(let z=0;z<sectionList.length;z++){

                let sectionListObj = {};

                console.log(‘in for loop’);

                if(sectionList[z].divName == divName){

                    if(sectionList[z].flag){

                        sectionListObj.flag = false;

                    }else{

                        sectionListObj.flag = true;

                    }

                    sectionListObj.divName = sectionList[z].divName;

                }else{

                    sectionListObj.flag =  sectionList[z].flag;

                    sectionListObj.divName = sectionList[z].divName;

                }

                sectionListNew.push(sectionListObj);

            }

            console.log(‘sectionListNew:::::’+JSON.stringify(sectionListNew));

            c.set(‘v.sectionList’,sectionListNew);

        }

        catch(ex){

            console.log(ex);

        }

    },

closeBox : function(c,e,h){

        c.set(‘v.isOpenUrl’,false);

    },

    closeModelUrl : function(c,e,h){

        c.set(‘v.isOpenUrl’,false);

    }

})

Step3: Create a client-side helper KanbanBoardHelper.js which will pass the column and row field parameters to get the records and control the height of each row and column of the Kanban Board. It will also update the record after drag and drop any record.

({

    doInit_helper : function(component, event, helper) {

        try{

            var action = component.get(“c.getKanbanWrap”);

            action.setParams({

                “objName”:component.get(“v.objectName”),

                “objFields”:component.get(“v.objFields”),

                “kanbanField”:component.get(“v.kanbanPicklistField”),

                “KanbanRowField”:component.get(“v.KanbanRowField”)

            });

            action.setCallback(this, function(response){

                var state = response.getState();

                if (state === “SUCCESS”) {

                    var AllRowListMap = new Map();

                    component.set(“v.kanbanData”, response.getReturnValue());

                    let rowPickList = response.getReturnValue().rowPickvalList;

                    if(rowPickList.length > 0){

                        for(let k=0;k<rowPickList.length;k++){

                            let newList = [];

                            AllRowListMap.set(rowPickList[k],newList);

                        }

                    } 

                    //iterate records to fill map according to its Type

                    var rowField = component.get(‘v.KanbanRowField’);

                    for(let i=0;i<response.getReturnValue().records.length;i++){

                        let recordType = response.getReturnValue().records[i];

                        let map = new Map(Object.entries(recordType));

                        if(map.has(rowField)){

                            AllRowListMap.get(map.get(rowField)).push(recordType);

                        }

                    }

                    let FilteredRecordList = [];

                    for(let mapObj in Array.from(AllRowListMap.entries())){

                        let listMapObj = {};

                        listMapObj.Key = Array.from(AllRowListMap.keys())[mapObj];

                        listMapObj.Value = Array.from(AllRowListMap.get(listMapObj.Key));

                        FilteredRecordList.push(listMapObj);

                    }

                    // make dynamic kanban list on the basis of dynamic rows and columns

                    let DynamicFilteredList = [];

                    let sectionList = [];

                    var ColumnWiseMap = new Map();

                    var divCount = 1;

                    for(let FilteredRecordListObj in FilteredRecordList){

                        let divName = “myDIV”;

                        divName += divCount;

                        let outerWrapperObj = {};

                        let sectionObj = {};

                        outerWrapperObj.Key = FilteredRecordList[FilteredRecordListObj].Key;

                        outerWrapperObj.Size = FilteredRecordList[FilteredRecordListObj].Value.length;

                        if(FilteredRecordList[FilteredRecordListObj].Value.length > 0){

                            let columnpickVals = response.getReturnValue().pickVals;

                            if(columnpickVals.length > 0){     

                                for(let m=0;m<columnpickVals.length;m++){

                                    let newListObj = [];

                                    ColumnWiseMap.set(columnpickVals[m],newListObj);

                                }

                            }

                            var kanbanPicklistField = component.get(‘v.kanbanPicklistField’);

                            let listOfRecords = FilteredRecordList[FilteredRecordListObj].Value;

                            for(let recordsObj in listOfRecords){

                                let recordTypeObj = listOfRecords[recordsObj];

                                let mapNewObj = new Map(Object.entries(recordTypeObj));

                                if(mapNewObj.has(kanbanPicklistField)){

                                    ColumnWiseMap.get(mapNewObj.get(kanbanPicklistField)).push(recordTypeObj);

                                }

                            }

                            let innerRecordList = [];

                            for(let mapObjnew in Array.from(ColumnWiseMap.entries())){

                                let listMapObjNew = {};

                                listMapObjNew.Key = Array.from(ColumnWiseMap.keys())[mapObjnew];

                                listMapObjNew.Value = Array.from(ColumnWiseMap.get(listMapObjNew.Key));

                                innerRecordList.push(listMapObjNew);

                            }

                            outerWrapperObj.flag = true;

                            outerWrapperObj.divName = divName;

                            outerWrapperObj.Value = innerRecordList;

                            DynamicFilteredList.push(outerWrapperObj);

                            sectionObj.flag = true;

                            sectionObj.divName = divName;

                            sectionList.push(sectionObj);

                            divCount ++;

                        }else{

                            outerWrapperObj.flag = true;

                            outerWrapperObj.divName = divName;

                            outerWrapperObj.Value = [];

                            DynamicFilteredList.push(outerWrapperObj);

                            sectionObj.flag = true;

                            sectionObj.divName = divName;

                            sectionList.push(sectionObj);

                            divCount ++;

                        }

                    }

                    component.set(‘v.FilteredRecordsList’,FilteredRecordList);

                    component.set(‘v.DynamicFilteredList’,DynamicFilteredList);

                    component.set(‘v.sectionList’,sectionList);

                    component.set(‘v.isShowSpinner’,false);

                    console.log(‘sectionList:::>>’+JSON.stringify(sectionList));

                    window.setTimeout(

                        $A.getCallback(function (){

                            helper.setHeight(component, event ,helper);

                        }), 1000

                    );

                }

            });

            $A.enqueueAction(action);

        }catch(ex){

            console.log(ex);

        }

    },

    updatePickVal : function(component, recId, pField, pVal,helper) {

        //Id recId, String kanbanField, String kanbanNewValue

        var action = component.get(“c.getUpdateStage”);

        action.setParams({

            “recId”:recId,

            “kanbanField”:pField,

            “kanbanNewValue”:pVal

        });

        action.setCallback(this, function(response){

            var state = response.getState();

            if (state === “SUCCESS”) {

                document.getElementById(recId).style.backgroundColor = “#04844b”;

                setTimeout(function(){ document.getElementById(recId).style.backgroundColor = “”; }, 300);

            }

        });

        $A.enqueueAction(action);

    },

    setHeight : function(c, e ,h){

        try{

            //set height of each row on the basis of maximum number of records

            var divNumber = 0;

            var columnFieldValue = c.get(‘v.kanbanPicklistField’);

            let FilteredRecordsList = c.get(‘v.FilteredRecordsList’);

            for(let filteredListObj in FilteredRecordsList){

                var divName = ‘myDIV’;

                divNumber += 1;

                divName += divNumber;

                if(FilteredRecordsList[filteredListObj].Value.length > 0){

                    var maxRecordsMap = new Map();

                    var finalList = FilteredRecordsList[filteredListObj].Value;

                    for(let iterateObj in finalList){

                        var map2 = new Map(Object.entries(finalList[iterateObj]));

                        if(!maxRecordsMap.has(map2.get(columnFieldValue))){

                            maxRecordsMap.set(map2.get(columnFieldValue),1);

                        }else{

                            let count = maxRecordsMap.get(map2.get(columnFieldValue));

                            count = count+1;

                            maxRecordsMap.delete(map2.get(columnFieldValue));

                            maxRecordsMap.set(map2.get(columnFieldValue),count);

                        }

                    }

                    // iterate map to find maximum number of records

                    var maxRecords = 0;

                    for(let mapObj in Array.from(maxRecordsMap.entries())){

                        let keyObj = Array.from(maxRecordsMap.keys())[mapObj];

                        if(maxRecordsMap.get(keyObj) > maxRecords){

                            maxRecords = maxRecordsMap.get(keyObj);

                        }

                    }

                    if(maxRecords == 2){

                        var classObj = c.find(“myDIV1”);

                        for(var i=0;i<classObj.length;i++){

                            var cmpObjOne = classObj[i].getElement().getAttribute(‘data-id’);

                            if(cmpObjOne === divName){

                                $A.util.addClass(classObj[i], ‘newCSS’);

                            }

                        }

                    }

                    else if(maxRecords == 1){

                        var Elements = c.find(“myDIV1”);

                        for(var j=0;j<Elements.length;j++){

                            var cmpObjTwo = Elements[j].getElement().getAttribute(‘data-id’);

                            if(cmpObjTwo === divName){

                                $A.util.addClass(Elements[j], ‘dropZone4’);

                            }

                        } 

                    }

                        else{

                            var classObj3 = c.find(“myDIV1”);

                            for(var k=0;k<classObj3.length;k++){

                                var cmpObjThree = classObj3[k].getElement().getAttribute(‘data-id’);

                                if(cmpObjThree === divName){

                                    $A.util.addClass(classObj3[k], ‘newCSS1’);

                                }

                            }  

                        }

                }

            }

        }catch(ex){

            console.log(ex);

        }

    }

})

Step4: Set the CSS of the KanbanBoard.css in a separate CSS resource available in the lightning bundle.

.THIS {

}

.THIS .slds-item {

    border: 1px solid #d8dde6;

    border-radius: 0.25rem;

    background-clip: padding-box;

    padding: 0.45rem;

    margin: 0.25rem;

}

.THIS .stageContainer{

    width:13vh;

}

.THIS .slds-page-header__title {

    padding: 0rem 0.5rem;

}

.THIS .dropZone{

    min-height: 14vh;

    background-color: burlywood;

}

.THIS .RecordDivCss{

    box-shadow: #003358 0px 0px 10px -1px;

    background-color: sandybrown;

    color: saddlebrown;

}

.THIS .KanbanDiv{

    background-color:black;

}

.THIS .PickHeader{

    background-color: #003358;

    color:white;

    box-shadow: #003358 0px 0px 6px -1px;

    min-width: 36.5vh;

    max-width: 37vh;

}

.THIS .btn:focus {

    outline: none;

    box-shadow: none;

}

.THIS .icnCSS svg{

    fill: #003358;

    width:16px;

}

.THIS .newCSS{

    min-height: 31vh;

}

.THIS .newCSS1{

    min-height: 39vh;

}

.THIS .scrollableClass{

    height:30rem;

    width:100%;

}

.THIS .linkCSS{

    color: darkgreen;

}

Step 5: Create an apex server-side class kanbanController.apxc which will fetch all the records from the database on the basis of parameters received from client-side helper. It will also update the record stored in the database as per user’s requirement.

public class kanbanController {

    @AuraEnabled

    public static kanbanWrap getKanbanWrap(String objName, String[] objFields, String kanbanField, String KanbanRowField) {

        try{

            List<String> lstPickvals = new List<String>();

            List<String> rowPickVal = new List<String>();            

            for (Schema.PicklistEntry a : Schema.getGlobalDescribe().get(objName).getDescribe().fields.getMap().get(kanbanField).getDescribe().getPickListValues())

                lstPickvals.add(a.getValue());

            for (Schema.PicklistEntry rowObj : Schema.getGlobalDescribe().get(objName).getDescribe().fields.getMap().get(KanbanRowField).getDescribe().getPickListValues())

                rowPickVal.add(rowObj.getValue());

            System.debug(lstPickvals);

            String query = ‘SELECT Id, ‘;

            for(String sObjeNew:objFields){

                query += sObjeNew+’ ,’;

            }

            query = query.removeEnd(‘,’);

            query += ‘ FROM ‘ + objName;

            query += ‘ WHERE ‘+ kanbanField + ‘!=Null’;

            query += ‘ and ‘+ KanbanRowField + ‘!=Null LIMIT 50000 ‘;

            System.debug(‘required query:: ‘ + query);

            return new kanbanWrap(Database.query(query), lstPickvals,rowPickVal );

        }catch(Exception e){

            System.debug(‘Exception in code:::’+e.getCause()+’Exception in line number:::’+e.getLineNumber()); 

        }

        return null;

    }

    @AuraEnabled

    public static String getUpdateStage(Id recId, String kanbanField, String kanbanNewValue) {

        try{

            SObject sobjectName = recId.getSObjectType().newSObject(recId);

            sobjectName.put(kanbanField,kanbanNewValue);

            update sobjectName;

            return ‘Success’;

        }catch(Exception e){

            System.debug(‘Exception in code:::’+e.getCause()+’Exception in line number:::’+e.getLineNumber()); 

        }

        return null;

    }

    public class kanbanWrap{

        @AuraEnabled

        public List<sObject> records {get;set;}

        @AuraEnabled

        public List<String> pickVals {get;set;}

        @AuraEnabled

        public List<String> rowPickvalList {get;set;}

        public kanbanWrap(List<sObject> recs, List<String> pVals, List<String> rowList){

            this.records = recs;

            this.pickVals = pVals;

            this.rowPickvalList = rowList; 

        }

    }

}

If you need any guidance with Salesforce and Google Cloud Integration or any form of Salesforce Integration, contact Cloud Analogy, one of the world’s leading Salesforce development companies and Salesforce Implementation Partners.

Suraj

Suraj Tripathi

Salesforce Consultant | Solutions Engineering Head
"Suraj Tripathi, a certified Salesforce Principal Consultant of repute, is a wonderful mentor and leader. A certified Salesforce Architect and a 7x Salesforce Certified Platform Application Developer by passion and profession, Suraj has rich experience in languages such as Aura, HTML, Angular, Bootstrap, APEX, and JavaScript. With more than five years of expertise in Salesforce Development, Suraj has worked on more than 50+ projects out of which 20+ projects were related to Salesforce Integration, Writing Triggers, Batch classes, VisualForce pages, and Aura Components.

Hire the best Salesforce Development Company. Choose certified Salesforce Developers from Cloud Analogy now.

Close Menu