+ Start a Discussion
Jauhien LeaniukJauhien Leaniuk 
Only name column in my table shown when I start my app.
When I type something in search box or all fields of the table appears, but at the start of the component, only name filed showed.

Here is my
component
<aura:component controller="SortableAccountTableController"
                description="Account table with column sorting example"
                implements="flexiPage:availableForAllPageTypes">
    
    <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>
   <!--aura attributes--> 
    <aura:attribute name="contactColumns" type="List"/>
    <aura:attribute name="contactData" type="Object"/>
    <aura:attribute name="sortBy" type="String"/>
    <aura:attribute name="sortDirection" type="String"/>
    <aura:attribute name="filteredData" type="Map"/>
    
    
    
    <!--Page header-->
    <div class="slds-page-header" role="banner">
        <span class="slds-text-heading_medium">Contacts List</span>
        <span class="slds-page-header__title">10 per Page</span>
    </div>
    <!-- New button added -->
	<lightning:button label="New" onclick="{!c.newContact}" />
    
    
    <lightning:input onchange="{!c.searchTable}" type="search" label="Searh" variant="label-hidden" placeholder="Enter search term" aura:id="SearchBox"/>
    
    
    <!--Lightning data table markup-->
    <lightning:datatable aura:id="accountTable"
                         keyField="Id"
                         hideCheckboxColumn="true"
                         columns="{!v.contactColumns}"
                         data="{!v.filteredData}"
                         sortedBy="{!v.sortBy}"
                         sortedDirection="{!v.sortDirection}"
                         onsort="{!c.handleSort}"/>
    
</aura:component>


controller

({
    onInit : function(component,event,helper){
        // Setting column information.To make a column sortable,set sortable as true on component load
        component.set("v.contactColumns",[
            { label : 'Name', fieldName : 'Name', type : 'Name', sortable : true },
            { label : 'Phone', fieldName : 'Phone', type : 'Phone', sortable : true },
            { label : 'Contact Level', fieldName : 'Contact_Level__c', type : 'Picklist', sortable : true },
            { label : 'Account', fieldName : 'Account', type : 'Lookup', sortable : true },
            { label : 'Owner', fieldName : 'OwnerId', type : 'lookup', sortable : true },
            { label : 'Created By', fieldName : 'CreatedById', type : 'Lookup(User)', sortable : true },
            { label : 'Created Date', fieldName : 'CreatedDate', type : 'Date/Time', sortable : true },
        ]);
        var action = component.get("c.fetchData");
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.contactData", response.getReturnValue());
                component.set("v.filteredData", response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
        // call helper function to fetch account data from apex
        helper.getAccountData(component);
    },
    
    //Method gets called by onsort action,
    handleSort : function(component,event,helper){
        //Returns the field which has to be sorted
        var sortBy = event.getParam("fieldName");
        //returns the direction of sorting like asc or desc
        var sortDirection = event.getParam("sortDirection");
        //Set the sortBy and SortDirection attributessadsad
        component.set("v.sortBy",sortBy);
        component.set("v.sortDirection",sortDirection);
        // call sortData helper function
        helper.sortData(component,sortBy,sortDirection);
    },
            
   	searchTable : function(cmp,event,helper) {
        var allRecords = cmp.get("v.contactData");
        var searchFilter = event.getSource().get("v.value").toUpperCase();
        
        var tempArray = [];
        var i;

        for(i=0; i < allRecords.length; i++){
            if((allRecords[i].Name && allRecords[i].Name.toUpperCase().indexOf(searchFilter) != -1))
            {
                tempArray.push(allRecords[i]);
            }
        }
        cmp.set("v.filteredData",tempArray);
    },
    
    // Function used to create a new Contact
    newContact: function(component, event, helper) {
        // Global event force:createRecord is used
        var createContact = $A.get("e.force:createRecord");
        // Parameters like apiName and defaultValues are set
        createContact.setParams({
            "entityApiName": "Contact",
            "defaultFieldValues": {
                "AccountId": component.get("v.recordId")
            }
        });
        // Event fired and new contact dialog open
        createContact.fire();
    },
})

helper
({
    getAccountData : function(component){
        //Load the Account data from apex
        var action = component.get("c.getAccounts");
        var toastReference = $A.get("e.force:showToast");
        action.setCallback(this,function(response){
            var state = response.getState();
            if(state == "SUCCESS"){
                var accountWrapper = response.getReturnValue();
                if(accountWrapper.success){
                    //Setting data to be displayed in table
                    component.set("v.contactData",accountWrapper.contactList);
                    toastReference.setParams({
                        "type" : "Success",
                        "title" : "Success",
                        "message" : accountWrapper.message,
                        "mode" : "dismissible"
                    });
                } // handel server side erroes, display error msg from response 
                else{
                    toastReference.setParams({
                        "type" : "Error",
                        "title" : "Error",
                        "message" : accountWrapper.message,
                        "mode" : "sticky"
                    }); 
                }
            } // handel callback error 
            else{
                toastReference.setParams({
                    "type" : "Error",
                    "title" : "Error",
                    "message" : 'An error occurred during initialization '+state,
                    "mode" : "sticky"
                });
            }
            toastReference.fire();
        });
        $A.enqueueAction(action);
    },
    
    sortData : function(component,fieldName,sortDirection){
        var data = component.get("v.filteredData");
        //function to return the value stored in the field
        var key = function(a) { return a[fieldName]; }
        var reverse = sortDirection == 'asc' ? 1: -1;
        
        // to handel number/currency type fields 
        if(fieldName == 'NumberOfEmployees'){ 
            data.sort(function(a,b){
                var a = key(a) ? key(a) : '';
                 var b = key(b) ? key(b) : '';
                return reverse * ((a>b) - (b>a));
            }); 
        }
        else{// to handel text type fields 
            data.sort(function(a,b){ 
                var a = key(a) ? key(a).toLowerCase() : ''; //To handle null values , uppercase records during sorting
                var b = key(b) ? key(b).toLowerCase() : '';
                return reverse * ((a>b) - (b>a));
            });    
        }
        //set sorted data to accountData attribute
        component.set("v.filteredData",data);
    }
    
})

Apex class
public class SortableAccountTableController {
   // wrapper class 
    public class AccountWrapper{
        @AuraEnabled
        public String message;
        @AuraEnabled
        public List<Contact> contactList;
        @AuraEnabled
        public Boolean success;
    }
    
    //Return account records and message to be displayed in toast
    @AuraEnabled
    public static AccountWrapper getAccounts(){
        AccountWrapper accountWrapper = new AccountWrapper();
        try{
            accountWrapper.contactList = [SELECT ID, Name, Phone, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate
                                           FROM Contact
                                           LIMIT 50];
            accountWrapper.message = 'Account records are retrieved ';
            accountWrapper.success = true;
        }
        catch(Exception e){
            accountWrapper.message = e.getMessage();
            accountWrapper.success = false;
        }
        return accountWrapper;
    }
    
	@AuraEnabled
    public static List<sObject> fetchData() {
        //Query and return list of Contacts
        List<SObject> objRecords = [SELECT Name from Contact LIMIT 20];
        return objRecords;
	}
}

 
Best Answer chosen by Jauhien Leaniuk
Jauhien LeaniukJauhien Leaniuk
Ok I didnt pay attention to the last method. True version is this:
@AuraEnabled
    public static List<sObject> fetchData() {
        //Query and return list of Contacts
        List<SObject> objRecords = [SELECT Name, Phone, Contact_Level__c, AccountId, OwnerId, CreatedById, CreatedDate from Contact LIMIT 20];
        return objRecords;
	}

 
Evan KimmeyEvan Kimmey 
I am trying to populate an account field that is Free Text (Long) with a multi-select picklist field on the opportunity object. Workflow builder doesn't allow for a multi-select picklist cannot be used as the operator. In process builder I was running into the issue where I could not select the desired multi-select opp field. Is this because of the field type being multi-select or is there something I am missing?
Best Answer chosen by Evan Kimmey
AbhishekAbhishek (Salesforce Developers) 
I don't think we can do that unless you override the Standard Page Layout with a Custom Visualforce if you need this to happen real-time! Otherwise, it would be like this - 

User selects the Options from the Multi-select Picklist
Hit the Save button
A Workflow Rule would execute and as a result of which a Field Update fires.This fills the Long Text Area with all the "selected" Competitors line by line.
But the caveat is that, you or the User has to hit the Save button and then edit again to start filling the same.

Another option would be do this using a Flow. Where - 

The first Screen would show options[Multi-select Values aka the Competitors]
And then Loop iterates over the collection and show Screens to enter values for each of them
Finally collects the required information in a Text based Variable
Updates the Record
Yes, it sounds a little to overwhelming but I feel it should be doable.

And I also strongly feel that these should have been separate entities or objects instead of the Multi-Select Picklist and Long Text Area!

You can think of it like this - There will be a Custom Object called Competitor which would store the Names and Details of all know Competitors. You can then create another Custom Object called say "OpportunityCompetitor" which will be a junction object between Competitor and Opportunity(I am using Opportunity as an example). This could house the Price and other relevant fields too!

Yes it looks a little too broad and may it's late for you but still worth from a "long run" standpoint. As compared to the native options, there are ways to customize and the data becomes reportable which is what we need at the end of the day!


Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.

Thanks.
Lisa FrenchLisa French 
I had some help writing a trigger to pull information from a description field into account lookup fields so that we can click on the name and have quick access to the associated account record.  The problem is that now when we try to change that field, it will not let us.  We can change it, but as soon as we hit save, it goes back to the auto-populated data pulled in from the trigger.  We need to be able to change that and I am not a Salesforce Developer, I am an admin and have been puzzling over this way too long.  Any help would be greatly appreciated.  Please see the code below:

Trigger OpportunityTrigger on Opportunity (after insert, after update) {
    public List<String> contactTypeList = New List<String>{'General Contractor','Architect','Developer','Owner','Consultant'}; 
    LargoDataTest__c ltd = LargoDataTest__c.getOrgDefaults();
  
    if(trigger.isAfter && APEXUtil.IsNewTrigger==false && !ltd.StopTrigger__c){
        if(trigger.isInsert||trigger.isUpdate){
            List<Opportunity> AllOppList = New List<Opportunity>();             
            List<Opportunity> OpptoUpdateList = New List<Opportunity>(); 
            List<Account> AcctoInsertList = New List<Account>(); 
            List<String> AccNames = New List<String>();
            MAP<String,String> contactTypeMAP = New MAP<String,String>(); 
            MAP<String,Account> accMAP = New MAP<String,Account>();
            MAP<Id,MAP<String,String>> OpportunityMAP = New MAP<Id,MAP<String,String>>();
                        
            for(Account acc: [Select Name From Account]){accMAP.put(acc.Name, acc);} 
            
            for(Opportunity opp : trigger.new){AllOppList.add(New Opportunity(Id=opp.ID, Description = opp.Description));} 
            
            for(Opportunity opp : AllOppList){ 
                if(opp.Description!=null?opp.Description.contains('Contact Information')?true:false:false){               
                    contactTypeMAP = getContactType(opp.Description, contactTypeList);
                    for(String AccName: contactTypeMAP.values()){if(!AccNames.Contains(AccName)?(AccName!=null?true:false):false){AccNames.add(AccName);}}                    
                    for(String AccName: AccNames){if(!accMAP.Containskey(AccName)){AcctoInsertList.add(New Account(Name=AccName));}}                   
                    OpportunityMAP.put(opp.Id,contactTypeMAP);
                }          
            } 
            
            if(!AcctoInsertList.isEmpty()){                
                Database.SaveResult[] rsResult = Database.Insert(AcctoInsertList,false);
                for(Database.SaveResult database: rsResult){if(!database.isSuccess()){for(Database.Error err : database.getErrors()) {System.debug('Insert Error-->'+err.getMessage());}}}
                for(Account acc: AcctoInsertList){if(acc.Id != null) accMAP.put(acc.Name, acc);}
            }
            
            
            for(Opportunity oppT : AllOppList){
                for(Id oppId : OpportunityMAP.keySet()){
                    if(oppT.Id == oppId){
                        System.debug('oppT.Id-->'+oppT.Id);
                        oppT.General_Contractor__c=OpportunityMAP.get(oppId).Containskey('General Contractor')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('General Contractor'))?accMAP.get(OpportunityMAP.get(oppId).get('General Contractor')).Id:null):null;
                        oppT.Architect__c=OpportunityMAP.get(oppId).Containskey('Architect')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('Architect'))?accMAP.get(OpportunityMAP.get(oppId).get('Architect')).Id:null):null;
                        oppT.Architect_2__c=OpportunityMAP.get(oppId).Containskey('Architect2')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('Architect2'))?accMAP.get(OpportunityMAP.get(oppId).get('Architect2')).Id:null):null;
                        oppT.Developer__c=OpportunityMAP.get(oppId).Containskey('Developer')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('Developer'))?accMAP.get(OpportunityMAP.get(oppId).get('Developer')).Id:null):null;
                        oppT.Owner__c=OpportunityMAP.get(oppId).Containskey('Owner')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('Owner'))?accMAP.get(OpportunityMAP.get(oppId).get('Owner')).Id:null):null;
                        oppT.Consultant__c=OpportunityMAP.get(oppId).Containskey('Consultant')?(accMAP.containsKey(OpportunityMAP.get(oppId).get('Consultant'))?accMAP.get(OpportunityMAP.get(oppId).get('Consultant')).Id:null):null;
                        OpptoUpdateList.add(oppT);                             
                    }                           
                }                
            }           
            if(!OpptoUpdateList.isEmpty()){
                APEXUtil.IsNewTrigger = true;                
                Database.SaveResult[] rsResult = Database.update(OpptoUpdateList,false);
                for(Database.SaveResult database: rsResult){if(!database.isSuccess()){for(Database.Error err : database.getErrors()) {System.debug('Update Error-->'+err.getMessage());}}}          
            }           
        } 
    }
    
    public MAP<String,String> getContactType (String Description, List<String> contactTypeListAux){
        MAP<String,String> contactTypeMAP = New MAP<String,String>();
        Integer indexCTAux0 = Description.indexOf('Contact Information'), indexCTAux1 = -1,indexCTAux2 = -1;     
            
        for(String ct: contactTypeListAux){            
            if(Description.contains(ct)){
                indexCTAux1 = Description.indexOf(ct+':',indexCTAux0)!=-1?Description.indexOf(ct+':',indexCTAux0):Description.indexOf(ct+',',indexCTAux0)!=-1?Description.indexOf(ct+',',indexCTAux0):-1;
                System.debug('ct1-->indexCTAux1:' + ct+'-->'+indexCTAux1);
                if(indexCTAux1!=-1?(Description.charAt(indexCTAux1-1)==10 || Description.charAt(indexCTAux1-1)==32?true:false):false){                        
                    contactTypeMAP.put(ct,getAccount(Description,indexCTAux1));
                    if(ct=='Architect'){
                        indexCTAux2=indexCTAux1;
                        indexCTAux1 = Description.indexOf(ct+':',indexCTAux2+1)!=-1?Description.indexOf(ct+':',indexCTAux2+1):Description.indexOf(ct+',',indexCTAux2+1)!=-1?Description.indexOf(ct+',',indexCTAux2+1):-1;
                        if(indexCTAux1!=-1?(Description.charAt(indexCTAux1-1)==10 || Description.charAt(indexCTAux1-1)==32?true:false):false){
                            contactTypeMAP.put('Architect2',getAccount(Description,indexCTAux1));                      
                        }                             
                    }
                }                
              
            }
        }        
        return contactTypeMAP;
    }
    
    public String getAccount (String Description, Integer indexCT){
        Integer StartNA = Description.indexOfChar(10,indexCT); 
        Integer EndNA = StartNA!=-1?Description.indexOfChar(10,StartNA+1):-1;
        return StartNA!=-1 && StartNA!=-1?Description.substring(StartNA+1, EndNA-1):Null;
    }   
}
Best Answer chosen by Lisa French
AbhishekAbhishek (Salesforce Developers) 
https://salesforce.stackexchange.com/questions/25320/how-to-write-a-trigger-on-opportunity

Use the code snippet as mentioned suggested in the above blog.


For further reference check this too (https://trailblazers.salesforce.com/answers?id=9063A000000pOAvQAM).
SFDC Admin12SFDC Admin12 
Our app has the need of storing access_token and refresh_token in the DB, but as we compare the size to Salesforce's same tokens - it's much larger: access_token in MS 2150 chars vs access_token in SF 112 chars (similar ratio for refresh tokens). We are using the On-Behalf-Of flow : https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow My understanding is that OAuth2 spec wouldn't specify the size of the tokens, it's open to implementations. The question is if cookie based storage is not preferred, or for cases where custom apps would need to use DB access/refresh token serializations - isn't the length/size an issue or constrain? thanks
Best Answer chosen by SFDC Admin12
AbhishekAbhishek (Salesforce Developers) 
There are no known size limits for AAD tokens.

For further reference, you can check this too,

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens

Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.

Thanks.
Sascha DeinertSascha Deinert 
Hi,

how can I add to my visualforce an inputfield with the possibility to change the formatting - text like bold or to change the color ....?  

Like this -->
html

Thanks,
Sascha
Best Answer chosen by Sascha Deinert
ANUTEJANUTEJ (Salesforce Developers) 
Hi Sascha,

I see that it is similar to a rich text input field so you can try the below tag once:

<apex:inputtextarea label="RichText" richtext="true" value="{!body}" id="Body" cols="100" rows="15"/>

Link: https://salesforce.stackexchange.com/questions/135647/rich-text-area-field-in-visualforce-page

Let me know if it helps you and close your query by marking it as solved so that it can help others in the future.  

Thanks.
Developer BaseDeveloper Base 
Hello there!

I created two record types on the Account object. Record that were already existent remained with an unassigned record type Id. Seems like this is an expected behaviour, but I can't find an explanation in the documentation.

Can anyone help me with the research and explanation?

Thank you
DevBase
Best Answer chosen by Developer Base
AnudeepAnudeep (Salesforce Developers) 
Yes, this is working as designed. We see this issue if the records were created before the two record types were created. There isn't any documentation that I can point you to but you can try setting an option to automatically insert your default record type when you create records.

https://help.salesforce.com/articleView?id=user_recordtype.htm&type=5

I recommend taking a look at this post where this issue is already discussed 

Let me know if this helps, if it does, please close the query by marking it as solved. It may help others in the community. Thank You!
Shatrughna SalunkeShatrughna Salunke 
Hello,

Is there any aletrnative way to achive the  below  sosl and soql error?

For the below code I am getting error

Error : Invalid IN fields group: PERSONEMAIL OR Custome_Email__C

  @AuraEnabled
   public static List<Account>  getData(String entityType)
    {   
       List<account> getDetails=new List<account>();
        List<List<Account>>  accList = [FIND : entityType IN PersonEmail Fields RETURNING Account(id,PersonEmail) limit 1];
        for(List<Account> accountList1 : accList){
            for(Account accountList2 : accountList1){
                if(accountList2.PersonEmail != null )
                {
                    if((accountList2.PersonEmail).equalsIgnoreCase(entityType)  )
                    {
                        getDetails.add(accountList2);
                    }
                }
            }
        }
        return getDetails;
    }
}

Also,getting error for this soql as well 
[Select id,PersonEmail  from Account where PersonEmail =:emailIds]

Error: we canot filter query for PersonEmail

Note: passing email id' from aura method and need to be filter record based on the email id's

 
Best Answer chosen by Shatrughna Salunke
AnudeepAnudeep (Salesforce Developers) 
Ran the SOQL query in my org where I have Person Account enabled and I am not seeing this issue

User-added image

Guess the error you are seeing with your SOSL is expected though because In SOSL you can't search by string value of a Lookup field.

For Example:

Record in object Contact:
Name: David Sidhu

Now there's a related object "LookUpToContact" looking up to parent object Contact.

Try to search "David Sidhu" using SOSL in LookUpToContact Query:

String searchName = 'FIND {David*} IN ALL FIELDS RETURNING LookUptoContact__c(Id, Contact__r.FirstName)';

Returns nothing, just an error (can be verified using workbench).


https://help.salesforce.com/articleView?id=000176100&type=1
Satheesh1105Satheesh1105 
I dont know what's the error in this test class
In test Class Line no 4 List acc didn't return any value
Apex class
public with sharing class ShowOppurtunity {
    @AuraEnabled(cacheable=true)
    public static List<Opportunity> showoppurtunity(String AccId) {
        system.debug(AccId);
        List<Opportunity> lstOpportunity = [SELECT Name,StageName,TrackingNumber__c,LeadSource,Description FROM Opportunity WHERE AccountId = :AccId ];
        system.debug(lstOpportunity);
        return lstOpportunity;
    }
}

Apex test Class

@isTest
public with sharing class ShowOppurtunityTest {
    static testmethod void testData(){
        Test.startTest();
        List<Account> acc = [SELECT Id FROM ACCOUNT LIMIT 1];
        system.debug('1');
        system.debug(acc);
        if (acc != null) {
        List<Opportunity> opp =[SELECT Name,StageName,TrackingNumber__c,LeadSource,Description FROM Opportunity WHERE AccountId = :acc[0].Id];
        List<Opportunity> opt = ShowOppurtunity.showoppurtunity(String.valueOf(acc[0].Id));
        system.debug(opp);
        system.debug(opt);
        System.assertEquals(opp,opt);
        Test.stopTest();
        }
    }
}
 
Best Answer chosen by Satheesh1105
RituSharmaRituSharma
You need to create test data in your test class and only then your query will return the data. Refer this URl for details:

https://trailhead.salesforce.com/en/content/learn/modules/apex_testing/apex_testing_data
NamanBNamanB 
Add Your Branding to Embedded Chat" Trailhead Challenge
I am trying to complete the challenge above posted here https://trailhead.salesforce.com/content/learn/modules/web-chat/web_chat_branding but have not been successful in loading the Chat Box when I open the VF page named "Web Chat" as stated in this challenge. Can someone please suggest why the chat pop up is not working? See the screenshot below. I have made sure that the agent is Active.


User-added image
 
Best Answer chosen by NamanB
ANUTEJANUTEJ (Salesforce Developers) 
Hi,

For all the Certification and Trailhead Guidance please report it here,

https://trailhead.salesforce.com/en/help?support=home

https://trailhead.salesforce.com/help

So that our trailhead support engineers will look into it and get back to you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future.

Regards,
Salesforce Support.
balaji Jayararmanbalaji Jayararman 
As per winter 21 release notes, view all and modify all permissions are removed at object level for guest user profile.

In my case, i have apex class with sharing mode enabled and gave read and create permission for custom object(Technologies__c) for guest user profile. But no Technologies__c records are retrieved.

if i give view all permission for custom object(Technologies__c) for guest user profile. I see Technologies__c records are rerieved. Any work around for retreiving the records by giving read and create permission alone at object level for guest user profile?
Best Answer chosen by balaji Jayararman
AbhishekAbhishek (Salesforce Developers) 
With the Winter ’21 release, Salesforce is disabling the View All Data, Modify All Data, edit, and delete object permissions for guest users in existing Org's. These permissions are removed from Org's created in Winter ’21 and later. For existing orgs, reduce object permissions for guest users if they have View All Data, Modify All Data, edit, or delete permissions on a standard or custom object.

>> Release Note:

-- https://releasenotes.docs.salesforce.com/en-us/winter21/release-notes/rn_networks_reduce_object_perms.htm

It means that now you can be granted Read-Only access to records only through guest user sharing rules. If you have given read access on profile then it would not work.

Here are reference article for your reference:-

-- https://help.salesforce.com/articleView?id=networks_secure_guest_user_sharing.htm&type=5

-- https://help.salesforce.com/articleView?id=000352282&language=en_US&mode=1&type=1


Thanks