Monday, 16 April 2018

Getting Reference FieldsI(Lookup or Master detail) through dynamic apex

Hi ,

We  had a scenario

If  we get a parameter "id" in the  url  then we should  be  able to find out    object reference is present in  the object which we are  trying  to insert then we have to make it  child record for  the object  related  to id.

For eg :

On my vf page i am trying  to insert  a contact and  i got  a parameter id related to Account

through the below code  i can find out  the  field which is  reference  to  Account  and  then fill that with parameter id to get contact inserted  under account.
The following code useful getting  reference fields  under  an object not  whole  example.



Eg: Code for  getting  reference

Map<String,Schema.SObjectField>  sobjecFieldMap = schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap();
for(String fieldName:sobjecFieldMap.keyset()){ 
    if(sobjecFieldMap.get(fieldName).getDescribe().getType()== Schema.DisplayType.REFERENCE){
       System.debug(sobjecFieldMap.get(fieldName).getDescribe().getReferenceTo());
    }
   
}


Output:
---------
Contact
Account
User




Sunday, 8 April 2018

Custom Lookup Creation and Example in Lightning

Hi ,

Lets how to prepare custom lookup component


Here in this example i am using "svg" component for icons but you can use lightning:icon tag instead


1)Create LC_svg component:

<aura:component >
    <aura:attribute name="class" type="String" description="CSS classname for the SVG element" />
    <aura:attribute name="xlinkHref" type="String" description="SLDS icon path. Ex: /assets/icons/utility-sprite/svg/symbols.svg#account" />
    <aura:attribute name="aria-hidden" type="String" default="true" description="aria-hidden true or false. defaults to true" />
</aura:component>

Renderer:
({
render: function(component, helper) {
//grab attributes from the component markup
var classname = component.get("v.class");
var xlinkhref = component.get("v.xlinkHref");
var ariaHidden = component.get("v.aria-hidden");

//return an svg element w/ the attributes
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('class', classname);
svg.setAttribute('aria-hidden', ariaHidden);
svg.innerHTML = '<use xlink:href="'+xlinkhref+'"></use>';
return svg;
}
})


2)Create SelectedObject event and  Custom Lookup Result component for getting the list of accounts based  search keyword


SelectedObject.evt:

<aura:event type="COMPONENT" description="by this event we are passing the selected Record in the Obeerving Component">
    <aura:attribute name="RecordByEvent" type="sObject"/>
</aura:event>

CustomLookupResult.cmp

<aura:component >
    <aura:attribute name="Obj" type="sObject" />
  <!--Register the component level event-->
    <aura:registerEvent name="oSelectedObjectEvent" type="c:SelectedObject"/>
    
    <li role="presentation">
        <span class="slds-lookup__item-action slds-media slds-media--center" id="lookup-option-350" role="option">
         <div class="slds-media__body">
          <div class="slds-input-has-icon slds-input-has-icon--right">
            <c:LC_svg class="slds-input__icon" xlinkHref="{!$Resource.SLDS092 + '/assets/icons/standard-sprite/svg/symbols.svg#account'}" />                   
          
<div class="slds-lookup__result-text"><a onclick="{!c.selectRecord}">{!v.Obj.Name}</a></div>
          </div>
        </div>    
        </span>
    </li>
</aura:component>

CustomLookupResultController.js:
----------------------------------------------------
({
selectRecord : function(component, event, helper){      
    // get the selected Account from list  
      var getSelectRecord = component.get("v.Obj");
    // call the event   
      var compEvent = component.getEvent("oSelectedObjectEvent");
    // set the Selected Object to the event attribute.  
     compEvent.setParams({"RecordByEvent" : getSelectRecord });  
    // fire the event  
     compEvent.fire();
    },
})


3)Create PickListEvt.evt and CustomLookup.cmp component:

PickListEvt.evt:
---------------------
<aura:event type="Component" description="Event fire when some one selects a value in picklist" >
    <aura:attribute name="SelectedValue" type="string" description="The result of the Selection"/>
</aura:event>

CustomLookup.cmp
---------------------------
/*
 This is the Controller Class for the Custom Lookup component.
 */
public class LookUpController {
  @AuraEnabled
 public static List <sObject> fetchRecords(String searchKeyWord, String ObjName, string count) {
  String searchKey = searchKeyWord + '%';
  List < Sobject > lstOfObj =  Database.query('SELECT id, Name '+' FROM '+ObjName+' WHERE Name LIKE \''+searchKey+'\' limit ' + count);
 
  return lstOfObj ;
 }
}


<aura:component controller="LookUpController" >    
   <aura:registerEvent name="RecordSelected" type="c:PickListEvt" description="This will Fire when the records has reached in it"/>
   <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/>
   <aura:attribute name="listOfSearchRecords" type="sObject[]" description="Use,for store the list of search records which returns from apex class"/>
   <aura:attribute name="SearchKeyWord" type="string"/>
   <aura:attribute name="FieldLabel" type="String"/>
   <aura:attribute name="ObjName" type="string" default="Account"/>
   <aura:attribute name="RecordCount" type="string" default="10"/>
   <aura:attribute name="Message" type="String" default="Search Result.."/>
    
   <!--declare events handlers-->  
   <aura:handler name="oSelectedObjectEvent" event="c:SelectedObject" action="{!c.handleComponentEvent}"/>
   <aura:handler event="aura:waiting" action="{!c.showSpinner}"/>
   <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/>
   <div class="slds-m-around">
      <div aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single">
          <aura:if isTrue="{!!empty(v.FieldLabel)}">
         <label class="slds-form-element__label" for="lookup-348"> {!v.FieldLabel}</label>
          </aura:if>
         <!--This part is for display search bar for lookup-->  
         <div class="slds-form-element__control">
            <div class="slds-input-has-icon slds-input-has-icon--right">
               <c:LC_svg class="slds-input__icon slds-show" xlinkHref="{!$Resource.SLDS092 + '/assets/icons/utility-sprite/svg/symbols.svg#search'}" />
               <!-- This markup is for when an record is selected -->
               <div aura:id="lookup-pill" class="slds-pill-container slds-hide">
                  <span class="slds-pill">
                     <span class="slds-pill__label">
                       {!v.selectedRecord.Name} 
                     </span>
                     <span class="slds-button slds-button--icon slds-pill__remove deleteIcon" onclick="{!c.clear}">
                        <c:LC_svg class="slds-button__icon" xlinkHref="{!$Resource.SLDS092 + '/assets/icons/utility-sprite/svg/symbols.svg#close'}" />
                        <span class="slds-assistive-text">Remove</span>
                     </span>
                  </span>
               </div>
              <div aura:id="lookupField" class="slds-show">
               <ui:inputText updateOn="keyup" keyup="{!c.keyPressController}" aura:id="LookupGeneral"
                             class="slds-lookup__search-input slds-input " 
                             value="{!v.SearchKeyWord}" placeholder="search.." />
              </div>   
            </div>
         </div>
         <!--This part is for Display typehead lookup result List-->  
         <div class="slds-lookup__menu slds" id="lookup-348">
            <div class="slds-lookup__item--label slds-text-body--small">{!v.Message}</div>
            <center> <ui:spinner aura:id="spinner"/> </center>
            <ul class="slds-lookup__list" role="listbox">
               <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec">
                  <c:CustomLookupResult Obj="{!singleRec}" />
               </aura:iteration>
            </ul>
         </div>
      </div>
   </div>
</aura:component>


CustomLookupController.js:

({
  
keyPressController : function(component, event, helper) {
      // get the search Input keyword   
var getInputkeyWord = component.get("v.SearchKeyWord");
        var getObjName = component.get("v.ObjName");
        var getRecordCount = component.get("v.RecordCount");
      // check if getInputKeyWord size id more then 0 then open the lookup result List and 
      // call the helper 
      // else close the lookup result List part.   
        if( getInputkeyWord.length > 0 ){
             var forOpen = component.find("searchRes");
               $A.util.addClass(forOpen, 'slds-is-open');
               $A.util.removeClass(forOpen, 'slds-is-close');
            helper.searchHelper(component,event,getInputkeyWord, getObjName, getRecordCount);
        }
        else{  
            component.set("v.listOfSearchRecords", null ); 
             var forclose = component.find("searchRes");
               $A.util.addClass(forclose, 'slds-is-close');
               $A.util.removeClass(forclose, 'slds-is-open');
          }
         
},
  
  // function for clear the Record Selaction 
    clear :function(component,event,heplper){
      
         var pillTarget = component.find("lookup-pill");
         var lookUpTarget = component.find("lookupField"); 
         $A.util.addClass(pillTarget, 'slds-hide');
         $A.util.removeClass(pillTarget, 'slds-show');
        
         $A.util.addClass(lookUpTarget, 'slds-show');
         $A.util.removeClass(lookUpTarget, 'slds-hide');
      
         component.set("v.SearchKeyWord",null);
         component.set("v.listOfSearchRecords", null );
         
    },
    
  // This function call when the end User Select any record from the result list.   
    handleComponentEvent : function(component, event, helper) {
    // get the selected Account record from the COMPONETN event  
       var selectedRecordGetFromEvent = event.getParam("RecordByEvent");
       var RecordSelected = component.getEvent("RecordSelected");     
         RecordSelected.setParams({
            SelectedValue: selectedRecordGetFromEvent.Id
        }).fire();
       component.set("v.selectedRecord" , selectedRecordGetFromEvent); 
       
        var forclose = component.find("lookup-pill");
           $A.util.addClass(forclose, 'slds-show');
           $A.util.removeClass(forclose, 'slds-hide');
        
        var forclose = component.find("searchRes");
           $A.util.addClass(forclose, 'slds-is-close');
           $A.util.removeClass(forclose, 'slds-is-open');
         
        var lookUpTarget = component.find("lookupField");
            $A.util.addClass(lookUpTarget, 'slds-hide');
            $A.util.removeClass(lookUpTarget, 'slds-show'); 
           
      
},
  // automatically call when the component is done waiting for a response to a server request.  
    hideSpinner : function (component, event, helper) {
        var spinner = component.find('spinner');
        var evt = spinner.get("e.toggle");
        evt.setParams({ isVisible : false });
        evt.fire();    
    },
 // automatically call when the component is waiting for a response to a server request.
    showSpinner : function (component, event, helper) {
        var spinner = component.find('spinner');
        var evt = spinner.get("e.toggle");
        evt.setParams({ isVisible : true });
        evt.fire();    
    },
    
})

CustomLookupHelper.js
-----------------------------------
({
searchHelper : function(component,event,getInputkeyWord, getObjName, getRecordCount) {
  // call the apex class method 
     var action = component.get("c.fetchRecords");
      // set param to method  
        action.setParams({
            'searchKeyWord': getInputkeyWord,
            'ObjName' : getObjName,
            'count' : getRecordCount
          });
      // set a callBack    
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var storeResponse = response.getReturnValue();
              // if storeResponse size is equal 0 ,display No Result Found... message on screen.
                if (storeResponse.length == 0) {
                    component.set("v.Message", 'No Result Found...');
                } else {
                    component.set("v.Message", 'Search Result...');
                }
                
                // set searchResult list with return value from server.
                component.set("v.listOfSearchRecords", storeResponse);
            }
 
        });
      // enqueue the Action  
        $A.enqueueAction(action);
    
},
})


Custom Lookup Example: (Usage):

CustomLookupExample.cmp:
---------------------------------------
<aura:component controller="ContactSavecls">
    <aura:attribute name="contactObj" type="Contact" default="{'sobjectType':'Contact',
                                                              'AccountId':'','FirstName':'',
                                                               'LastName':''}"/>
    <div>
    <div class="slds-form-element__control">
        <ui:inputText class="slds-input" label="Last Name" value="{!v.contactObj.LastName}"/>
        <c:CustomLookup ObjName="Account" FieldLabel="Related Account"
            RecordCount="5" 
            RecordSelected="{!c.handleRecordSelection}" />
       </div>    
        <ui:button press="{!c.contactSave}">Save Contact</ui:button>
    </div>
</aura:component>

CustomLookupExample.js:
-------------------------------------
({
handleRecordSelection : function(component, event, helper) {
        alert('hi'+event.getParam("SelectedValue"));
component.set("v.contactObj.AccountId", event.getParam("SelectedValue"));
},
    contactSave:function(component, event, helper){
        var action = component.get("c.saveContact");
        var contRec = component.get("v.contactObj");
        action.setParams({"contObj":contRec});
        action.setCallback(this,function(data){
            var result = data.getReturnValue();
            alert(result);
        });
        $A.enqueueAction(action);
        
    }
})



ApexController:
--------------------
public class ContactSavecls{
    @Auraenabled
    public static String saveContact(Contact contObj){
        insert contObj;
        return contObj.Id;
    }
}



output:
------------




References:
------------------
https://developer.salesforce.com/blogs/developer-relations/2015/06/salesforce-lightning-inputlookup-missing-component.html


http://sfdcmonkey.com/2017/07/17/re-usable-custom-lookup/

http://sfdcmonkey.com/2017/01/07/custom-lookup-lightning-component/

https://teamforcesite.wordpress.com/2017/09/20/how-to-build-custom-lookup-in-lightning/
https://github.com/enreeco/inputlookup

https://www.jitendrazaa.com/blog/salesforce/lookup-component-in-salesforce-lightning/

https://www.lightningdesignsystem.com/components/lookups/


Wednesday, 4 April 2018

lightning:icon (No svg component creation needed now)

Hi,

To show icons in lightning component  we don't  need to create svg component. We can use "lightning:icon"

directly.

It represents a visual element that provides context and enhances usability.

lightning:icon is a visual element that provides context and enhances usability. Icons can be used inside the body of another component or on their own.

Component:IconComponent: ( created  reusable component you can use tag directly also)

<aura:component description="IconComp">
    <aura:attribute name="iconName" type="String" default="action:more"/>
    <aura:attribute name="size" type="String" default="small"/>
    <aura:attribute name="iconSize" type="String" default="small"/>
    <aura:attribute name="alternativeText" type="String" default="Indicates More"/>
    <aura:attribute name="className"    type="String" default=""/>
    <aura:attribute name="title" type="String" default=""/>
    <aura:attribute name="variantName" type="String" default=""/>
    <lightning:icon iconName="{!v.iconName}" size="{!v.iconSize}" alternativeText="{!v.alternativeText}" title="{!v.title}"
                    class="{!v.className}" variant="{!v.variantName}"/>
</aura:component>


IconComponentApp :

<aura:application  extends="force:slds">
    Icons:<br/>
    <c:IconComponent iconName="action:add_photo_video" alternativeText="video" size="small"/> 
    <br/> <br/>
    <c:IconComponent iconName="action:follow" alternativeText="follow" size="small"/> <br/> <br/>
    <c:IconComponent iconName="action:edit_groups" alternativeText="edit_groups" size="small"/> <br/> <br/>
    <c:IconComponent iconName="custom:custom1" alternativeText="custom1" size="large"/> <br/> <br/>
    <c:IconComponent iconName="doctype:attachment" alternativeText="Attachment" size="large"
                      variantName ="warning"/> <br/> <br/>
    <c:IconComponent iconName="standard:account" alternativeText="Account" size="large"/> <br/> <br/>
     <c:IconComponent iconName="utility:activity" alternativeText="Activity" size="large"/> <br/> <br/>
</aura:application>



References:
------------

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_icon.htm

https://lightningdesignsystem.com/icons/



Sunday, 25 March 2018

lightning:radioGroup values preparation from Apex Class

Hi ,

Here in the following i am preparing the values from Apex class for lightning:radioGroup.

Lightniong:radiogroup:
-----------------------------

Apex Controller:
-------------------
public class LightningRadioGroup {
   @Auraenabled
    public static Map<string,String> retrieveValues(){
        Map<String,String> dummyValuesMap = new Map<String,String>();
        dummyValuesMap.put('balaji','balaji');
        dummyValuesMap.put('Sree Valli','Sree Valli');
        return dummyValuesMap;
    }
     @Auraenabled
    public static String retrieValuesinJSON(){
        JSONGenerator gen = JSON.createGenerator(true);
        gen.writeStartArray();
        gen.writeStartObject();
            gen.writeStringField('class','optionClass');
            gen.writeStringField('label','Balaji');
            gen.writeStringField('value','Balaji');
        gen.writeEndObject();
         gen.writeStartObject();
            gen.writeStringField('class','optionClass');
            gen.writeStringField('label','Alivelimanga');
            gen.writeStringField('value','Alivelimanga');
        gen.writeEndObject();
        gen.writeEndArray();
        String jsonString= gen.getAsString();
        System.debug('jsonString:'+jsonString);
        return jsonString;
    }
}
---------------
RadioGroup.cmp: (preparation of values using Map)

<aura:component controller="LightningRadioGroup">
    <aura:handler name="init" value="{!this}" action="{!c.usingMap}"/>
    <aura:attribute name="optionsList" type="List" /> 
    <aura:attribute name="value" type="String" default="option1"/>
    <div class="slds-form slds-form_stacked">
        <h1>Lightning Radio Group Example</h1>
    <lightning:radioGroup aura:id="mygroup"
                name="radioButtonGroup"
                label="Radio Button Group Usin Map"
                options="{!v.optionsList}"
                value="{!v.value}"       
                required="true" />
   
    </div>
</aura:component>

RadioGroupController.js:
----------------------------
({
usingMap : function(component, event, helper) {       
var action = component.get("c.retrieveValues");
        action.setCallback(this,function(response){
            var values = [];
            var result = response.getReturnValue();
            for(var key in result){
                values.push({
                    class:'optionClass',
                    label:key,
                    value:result[key]});     
            }
            component.set("v.optionsList",values);
        });
        $A.enqueueAction(action);
}
})



RadioGroupusinJSON.cmp: (Displaying values using JSON string)

<aura:component controller="LightningRadioGroup">
    <aura:handler name="init" value="{!this}" action="{!c.usingJSON}"/>
    <aura:attribute name="optionsJSON" type="String" /> 
    <aura:attribute name="value" type="String" default="option1"/>
    <div class="slds-form slds-form_stacked">
    <lightning:radioGroup aura:id="mygroup"
                name="radioButtonGroup"
                label="Radio Button Group Usin JSON"
                options="{!v.optionsJSON}"
                value="{!v.value}"       
                required="true" />
   
    </div>
</aura:component>

RadioGroupusinJSONController.js:
({
usingJSON : function(component, event, helper) {       
var action = component.get("c.retrieValuesinJSON");
        action.setCallback(this,function(response){         
            var result = response.getReturnValue();
            component.set("v.optionsJSON",JSON.parse(result));         
        });
        $A.enqueueAction(action);
}
})


Output:
---------



References:
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_radioGroup.htm

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_ui_inputRadio.htm

Lightning Picklist Helper and Component Event Example

Hi ,

I am going to explain a reusable component for picklist . We can use it in any component for generating picklist.

It has following parameters to set dynamically.
objectName -- For which object we have to generate piclist
FieldName -- It is Picklist Field API name
FieldLabel -- Label of the Picklist field
MultiSelect -- We can setup picklist as muliselect or single select
SelectedValue -- We can set up default value

We have to create an event to pass selected value from PicklistHelper Component. Here

we are using component event.

PickListEvent.evt:

<aura:event type="Component" description="Event fire when some one selects a value in picklist" >
    <aura:attribute name="SelectedValue" type="string" description="The result of the Selection"/>

</aura:event>


PicklistHelper.cmp:

<aura:component controller="PicklstHelper">
  <aura:registerEvent name="PicklistSelected" type="c:PickListEvt"/>
   <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
   <aura:attribute name="objectName" type="String"/>
    <aura:attribute name="FieldName" type="String" />
    <aura:attribute name="FieldLabel" type="String" default="PickLIst"/>
    <aura:attribute name="MultiSelect" type="Boolean" default="false" />
    <aura:attribute name="SelectedValue" type="String" default="" />
   <div class="slds-form-element">
      <label class="slds-form-element__label" for="select-01">{!v.FieldLabel}</label>
      <div>
         <ui:inputSelect aura:id="PickListId" multiple="{!v.MultiSelect}" class="slds-select"  change="{!c.onPicklistChange}"/>
      </div>
   </div>

</aura:component>

PickListHelperController.JS:
---------------------
({
    doInit: function(component, event, helper) {        
        helper.fetchPickListVal(component, 'PickListId', component.get("v.SelectedValue"));
    },
onPicklistChange : function(component, event, helper) {
// get the value of select option
        var SelectPicklist = component.getEvent("PicklistSelected");
        SelectPicklist.setParams({
            SelectedValue: event.getSource().get("v.value")
        }).fire();      
}
})

PickListHelperHelper.JS:
---------------------
({
fetchPickListVal: function(component, elementId, selectedVal) {
        var action = component.get("c.getselectOptions");
        action.setParams({
            "objectName": component.get("v.objectName"),
            "fieldName": component.get("v.FieldName")
        });
        var opts = [];
        action.setCallback(this, function(response) {
            if (response.getState() == "SUCCESS") {
                var allValues = response.getReturnValue();
                if (allValues != undefined && allValues.length > 0) {
                    opts.push({
                        class: "optionClass",
                        label: "--- None ---",
                        value: ""
                    });
                }
                for (var i = 0; i < allValues.length; i++) {
                    if(selectedVal == allValues[i])
                    {
                        opts.push({
                            class: "optionClass",
                            label: allValues[i],
                            value: allValues[i],
                            selected: "true"
                        });
                        var SelectPicklist = component.getEvent("PicklistSelected");
                        SelectPicklist.setParams({
                            SelectedValue: selectedVal
                        }).fire(); 
                    }
                    else
                    {
                        opts.push({
                            class: "optionClass",
                            label: allValues[i],
                            value: allValues[i],                          
                        });
                }
                }
                component.find(elementId).set("v.options", opts);
            }
        });
        $A.enqueueAction(action);
    }

})

PickListHelper.CSS
---------------------------
.THIS .optionClass {
    padding: .1rem;
}
.THIS .slds-select[size] option {
    padding: .1rem;
}
.THIS .slds-select[multiple] option {
    padding: .1rem;
}


Apex Controller:
----------------------
public class PicklstHelper {
    @AuraEnabled
    public static List < String > getselectOptions(String objectName, string fieldName) {
       List<String> optionsList = new List<String>();
       list <Schema.PicklistEntry>  piclistValueList = schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues();
        for(Schema.PicklistEntry pickEntryObj:piclistValueList){
            optionsList.add(pickEntryObj.getValue());
        }
       
        return optionsList;
    }
}

AccountSave.cmp: (Component where we are going to utilize the above picklist Helper component)

<aura:component controller="AccountSavecls">
    <aura:attribute name="accountObj" type="Account" default="{'sobjectType': 'Account',
                          'Name':'','Type':''}"/>
    <div class="slds">        
        <div class="slds-card">
            <div class="slds-card__header slds-grid">
                <div class="slds-media__body">
                    <span class="slds-text-heading_small">Save Contact and Add it to table with checkbox selection</span>
                </div>
            </div>
            <div class="slds-card__body slds-card__body_inner">
                <ui:inputText class="slds-input" label="Name"  value="{!v.accountObj.Name}"/><br/>            
                <c:PickListHelper objectName="Account" 
                                  FieldName="Type" 
                                  FieldLabel="Account Type"
                                  SelectedValue="Customer - Direct"
                                  PicklistSelected="{!c.changeValue}"/><br/>
                <ui:button class="slds-button" press="{!c.saveAct}">Save Account</ui:button>
            </div>
        </div>   
    </div>
</aura:component>

AccountSaveController.js:
({
saveAct : function(component, event, helper) {       
        var actRec = component.get("v.accountObj");
var action = component.get("c.saveAccout");
        action.setParams({"actObj":actRec});
        action.setCallback(this,function(response){
            var result = response.getReturnValue();            
        });
        $A.enqueueAction(action);
},
    changeValue : function(component,event,helper){        
        component.set("v.accountObj.Type", event.getParam("SelectedValue"));
    }
})

AccountSaveApp.App;



output:
---------



References:
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/events_component.htm
https://trailhead.salesforce.com/modules/lex_dev_lc_basics/units/lex_dev_lc_basics_events
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/events_intro.htm








Thursday, 22 March 2018

Adding New contact to table dynamically and process selected contacts through check boxes in Lightning

Hi ,

Here we are going to learn how to save Record and then added to list which are displaying in the component on load.

In the table you can see check boxes for selecting multiple records and then process selected records.


Wrapper Class: Which holds Contact object and isSelected boolean variables to combine checkbox with contact record.

public class ContactWrapper{
        @Auraenabled
        public Contact contactObj;
        @Auraenabled
        public boolean isSelected;
}

Apex Class (Controller):

public class ContactCls {
  //retrieving contacts and return to the lightning component
    @Auraenabled
    public  static List<ContactWrapper> retrieveContacts(){
        List<ContactWrapper> contactWrapperList = new List<ContactWrapper>();
        for(Contact contactObj:[select id,firstName,LastName from Contact where firstName!=null order by createddate desc limit 6]){
            ContactWrapper contactWrapObj = new ContactWrapper();
            contactWrapObj.contactObj = contactObj;
            contactWrapObj.isSelected = false;
            contactWrapperList.add(contactWrapObj);
        }
        return contactWrapperList;
    }

//for sending contacts when we click on "Process Contacts" button along with checkbox selection
    @Auraenabled
    public static String updateContacts(String contactString){
        String ids = '';
        List<ContactWrapper> contactWrapList = (List<ContactWrapper>)JSON.deserialize(contactString, List<ContactWrapper>.class);
        for(ContactWrapper contacctWrapObj:contactWrapList){
            if(contacctWrapObj.isSelected){
                ids+=contacctWrapObj.contactObj.Id;
            }
        }
        return ids;
    }

//For saving contact record and returning the wrapper record to lightning component
    @Auraenabled
    public static ContactWrapper saveContact(Contact contObj){
        ContactWrapper contWrapperObj = new ContactWrapper();
        insert contObj;
        if(contObj.Id!=null){
            contWrapperObj.contactObj = contObj;
            contWrapperObj.isSelected = false;
        }
       
        return contWrapperObj;
    }

}



Lightning Component: Contact_Componen.cmp
-------------------------
<aura:component controller="ContactCls">
    <aura:attribute name="contObj" type="Contact" default="{'sobjectType':'Contact',
                                                             'FirstName':'',
                                                             'LastName':''}"/>
    <aura:attribute name="contactList" type="ContactWrapper[]"/>   
    <aura:handler name="init" value="{!this}" action="{!c.myAction}"/> 
    <div class="slds-card">
         <div class="slds-card__header slds-grid">
             <div class="slds-media__body">
        <span class="slds-text-heading_small">Save Contact and Add it to table with checkbox selection</span>
              </div>
        </div>
        <div class="slds-card__body slds-card__body_inner">
             <ui:inputText class="slds-input" label="First Name" value="{!v.contObj.FirstName}"/><br/>
             <ui:inputText class="slds-input" label="Last Name" value="{!v.contObj.LastName}"/><br/>
            <ui:button class="slds-button" press="{!c.contactSave}">Save</ui:button>
        </div>
    </div>
    <br/>
    <div class="slds-card">
         <div class="slds-card__body slds-card__body_inner">
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
        <thead>
            <tr class="slds-text-title_caps">
                <th scope="col">
                    <div class="slds-truncate">Select</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="First Name">First Name</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Last Name">Last Name</div>
                </th>               
            </tr>
        </thead> 
        <tbody>
        <aura:iteration items="{!v.contactList}" var="contactWrap" indexVar="index">
                <tr class="slds-text-title_caps">
                        <td>
                           <ui:inputCheckbox value="{!contactWrap.isSelected}"/>
                        </td>                                             
               
                        <td>
                            <ui:outputText value="{!contactWrap.contactObj.FirstName}"/>
                        </td>
                        <td>
                            <ui:outputText value="{!contactWrap.contactObj.LastName}"/>
                        </td>                                             
                </tr>
            </aura:iteration>
       
        </tbody>
    </table>
   
    <br/>
    <ui:button class="slds-button" press="{!c.updateSelectedContacts}">Process Contacts</ui:button>
        </div>
  </div>
</aura:component>

Controller: Conact_ComponentController.js
({
//for displaying contacts
     myAction : function(component, event, helper) {       
var action = component.get("c.retrieveContacts");
        action.setCallback(this,function(data){
            var result = data.getReturnValue();
            component.set("v.contactList",result);
        });
        $A.enqueueAction(action);
},
 //for processing selected contacts
    updateSelectedContacts : function(component,event,helper){
       var contactList = component.get("v.contactList");
       var action = component.get("c.updateContacts");
        action.setParams({"contactString":JSON.stringify(contactList)});
        action.setCallback(this,function(data){
            var result = data.getReturnValue();
            alert(result);
        });
        $A.enqueueAction(action);     
    },
  //for saving a contact and adding the same into list at 0th index by using "splice" method
    contactSave : function(component,event,helper){
        var contactObj = component.get("v.contObj");
        var contactsList = component.get("v.contactList");
        var action = component.get("c.saveContact");
        action.setParams({"contObj":contactObj});
        action.setCallback(this,function(data){
            var result = data.getReturnValue();         
            contactsList.splice(0,0,result);           
            component.set("v.contactList",contactsList);         
        })
        $A.enqueueAction(action);
    }
})


Lightning App: Contact_ComponentApp.app
---------------------
<aura:application implements="force:appHostable" extends="force:slds">
    <c:Conact_Component />
</aura:application>




Output:
----------



References:

https://www.w3schools.com/jsref/jsref_splice.asp (for splice method in javascript)
https://www.lightningdesignsystem.com/components/cards/
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_ui_inputCheckbox.htm
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/apex_records_save.htm




Monday, 19 March 2018

Display SVG Icon in Lightning Component ( Lightning Component Helper)

Hi ,



To display icons from salesforce.com in lightning we have to follow the below steps.



1) Creating the Lightning Component with the name "svgIcon"



 Create a new Lightning component from the menu: File > New > Lightning Component



2)Paste the following the code



Click on the COMPONENT tab, then paste:



<aura:component>
  <aura:attribute name="svgPath"        default="" type="String" description="the path for the icon in the static resource, this will be use in a SVG use tag" />
  <aura:attribute name="name"           default="" type="String" description="Symbol name of icon" />
  <aura:attribute name="class"          default="" type="String" description="the class of this SVG tag, can be use for CSS purpose" />
  <aura:attribute name="containerClass" default="" type="String" description="Container class name for span container of icon" />
  <aura:attribute name="category"       default="" type="String" description="Category of icon- action, standard, utility etc." />
  <aura:attribute name="size"           default="" type="String" description="Size of icon-- small, medium, large" />
  <aura:attribute name="assistiveText"  default="" type="String" description="Description name of icon" />
  <span aura:id="container" class="{!v.containerClass}">
    <span aura:id="assistiveText" class="slds-assistive-text">{!v.assistiveText}</span>
  </span>
</aura:component>



Click on the HELPER tab, then paste:

({
  renderIcon: function(component) {
    var prefix = "slds-";
    var svgns = "http://www.w3.org/2000/svg";
    var xlinkns = "http://www.w3.org/1999/xlink";
    var size = component.get("v.size");
    var name = component.get("v.name");
    var classname = component.get("v.class");
    var containerclass = component.get("v.containerClass");
    var category = component.get("v.category");

    var containerClassName = [
        prefix+"icon_container",
        prefix+"icon-"+category+"-"+name,
        containerclass
        ].join(' ');
    component.set("v.containerClass", containerClassName);

    var svgroot = document.createElementNS(svgns, "svg");
    var iconClassName = prefix+"icon "+prefix+"icon--" + size+" "+classname;
    svgroot.setAttribute("aria-hidden", "true");
    svgroot.setAttribute("class", iconClassName);
    svgroot.setAttribute("name", name);

    // Add an "href" attribute (using the "xlink" namespace)
    var shape = document.createElementNS(svgns, "use");
    shape.setAttributeNS(xlinkns, "href", component.get("v.svgPath"));
    svgroot.appendChild(shape);

    var container = component.find("container").getElement();
    container.insertBefore(svgroot, container.firstChild);
  }
})



Click on the RENDERER tab, then paste:



({
  render: function(component, helper) {
    // By default, after the component finished loading data/handling events,
    // it will call this render function this.superRender() will call the
    // render function in the parent component.
    var ret = this.superRender();

    // Calls the helper function to append the SVG icon
    helper.renderIcon(component);
    return ret;
  }
})







3.Use the New Component



Use your new component whenever you need an Lightning Design System SVG icon. For example, if your Static Resource is named SLDS you might use:



<c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#user" category="standard" size="large" name="user" />


Example Component:
------------------------------

<aura:component >
<div class="slds-icon_container"> 
    <c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#user" category="standard" size="large" name="user" />
    </div>
    <div class="slds-icon_container"> 
    <c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#account" category="standard" size="large" name="account" class="slds-icon"/>
    </div>
     <div class="slds-icon_container"> 
    <c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#contact" category="standard" size="large" name="contact" />
    </div>
</aura:component>

Output:
--------


References:
https://archive-2_1_4.lightningdesignsystem.com/resources/lightning-svg-icon-component-helper
https://trailhead.salesforce.com/en/modules/lightning_design_system/units/lightning-design-system5
https://www.lightningdesignsystem.com/icons/

Tuesday, 27 February 2018

Test Setup Methods

Hi,

Test setup methods can be time-saving when you need to create reference or prerequisite data for all test methods, or a common set of records that all test methods operate on.

We have to use "@testSetup" annotation to write test setup method.


Small Use Case for you:


Case is updating with an account when case is created with different scenarios.


Then for creating test class for the same requirement i have to create an account in each method for covering different scenarios in the logic.

But with "testsetup" method we can avoid creating the same account in multiple methods instead we can create once in testsetup method then we can utilize the same in all test methods.

Syntax:
@testSetup static void methodName() {

}


Eg:
--
@isTest
private class CommonTestSetup {

    @testSetup static void setup() {
        // Create common test accounts
        Account accountObj = new Account(Name='ABCD Account');
        insert accountObj;       
    }
   
    @isTest static void testMethod1() {
       //Create case with a scenario it can take account data from the above test method to update on case based on your original logic to cover your code
    }

    @isTest static void testMethod2() {
        //Create case with a scenario it can take account data from the above test method  to update on case based on your original logic to cover your code
    }

}
  


Note:
If a test class contains a test setup method, the testing framework executes the test setup method first, before any test method in the class. Records that are created in a test setup method are available to all test methods in the test class and are rolled back at the end of test class execution. If a test method changes those records,such as record field updates or record deletions, those changes are rolled back after
 each test method finishes execution. The next executing test method gets access to the original unmodified state of those records.


Tuesday, 20 February 2018

Named Credentials

Hi ,

A named credential specifies the URL of a callout endpoint and its required authentication parameters in one definition. To simplify the setup of authenticated callouts, specify a named credential as the callout endpoint. If you instead specify a URL as the callout endpoint, you must register that URL in your org’s remote site settings and handle the authentication yourself. For example, for an Apex callout, your code would need to handle authentication, which can be less secure and especially complicated for OAuth implementations.


Salesforce manages all authentication for callouts that specify a named credential as the callout endpoint so that you don’t have to. You can also skip remote site settings, which are otherwise required for callouts to external sites, for the site defined in the named credential.

Named credentials are supported in these types of callout definitions:
§  Apex callouts
§  External data sources of these types:
o   Salesforce Connect: OData 2.0
o   Salesforce Connect: OData 4.0
o   Salesforce Connect: Custom (developed with the Apex Connector Framework)

By separating the endpoint URL and authentication from the callout definition, named credentials make callouts easier to maintain. For example, if an endpoint URL changes, you update only the named credential. All callouts that reference the named credential simply continue to work.
Named credentials support basic password authentication and OAuth 2.0. You can set up each named credential to use an org-wide named principal or to use per-user authentication so that users can manage their own credentials.

To reference a named credential from a callout definition, use the named credential URL. A named credential URL contains the scheme callout:, the name of the named credential, and an optional path. For example: callout:My_Named_Credential/some_path.
You can append a query string to a named credential URL. Use a question mark (?) as the separator between the named credential URL and the query string. For example: callout:My_Named_Credential/some_path?format=json.

Example

In the following Apex code, a named credential and an appended path specify the callout’s endpoint.
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:My_Named_Credential/some_path');
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
The referenced named credential specifies the endpoint URL and the authentication settings.
Path:Setup->Administer->Security Controls-> Named Credentials

Named credential detail page
If you use OAuth instead of password authentication, the Apex code remains the same. The authentication settings differ in the named credential, which references an authentication provider that’s defined in the org.
Named credential authentiation settings with OAuth options
In contrast, let’s see what the Apex code looks like without a named credential. Notice that the code becomes more complex to handle authentication, even if we stick with basic password authentication. Coding OAuth is even more complex and is an ideal use case for named credentials.
HttpRequest req = new HttpRequest();
req.setEndpoint('https://my_endpoint.example.com/some_path');
req.setMethod('GET');

// Because we didn't set the endpoint as a named credential, 
// our code has to specify:
// - The required username and password to access the endpoint
// - The header and header information
 
String username = 'myname';
String password = 'mypwd';
  
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
   
// Create a new http object to send the request object
// A response object is generated as a result of the request  
  
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
Reference:https://help.salesforce.com/articleView?id=named_credentials_about.htm&type=5
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm

Getting Reference FieldsI(Lookup or Master detail) through dynamic apex

Hi , We  had a scenario If  we get a parameter "id" in the  url  then we should  be  able to find out    object reference is ...