-
ChatterFeed
-
0Best Answers
-
1Likes Received
-
0Likes Given
-
61Questions
-
68Replies
Remove contact from related cases and service contracts before delete
Hi,
We use cases and service contracts and as SF prevent a contact being deleted that is associated to one of these records, when we want to delete a contact that is associated to a case or service contract each of these records needs to be individually updated to remove the contact.
I was hoping to remove the contact from these records on a before delete trigger on the contact. This is failing though as I think the SF code that is checking if the contact belongs to any cases or service contracts is rolling back my updates in my before trigger.
Does anyone know if this is possible thorugh a trigger?
I don't really want to launch a flow to delete the relationships on an individual contact record as I would like to be able to mass delete contacts.
This is the method that is called from the contact trigger on a beforeDelete
We use cases and service contracts and as SF prevent a contact being deleted that is associated to one of these records, when we want to delete a contact that is associated to a case or service contract each of these records needs to be individually updated to remove the contact.
I was hoping to remove the contact from these records on a before delete trigger on the contact. This is failing though as I think the SF code that is checking if the contact belongs to any cases or service contracts is rolling back my updates in my before trigger.
Does anyone know if this is possible thorugh a trigger?
I don't really want to launch a flow to delete the relationships on an individual contact record as I would like to be able to mass delete contacts.
This is the method that is called from the contact trigger on a beforeDelete
private static void removeContactFromRelatedObjects(Map<Id, Contact> oldContactsMap) { List<Contact> myContacts = new List<Contact>([SELECT ID, (SELECT Id, CaseNumber FROM Cases), (SELECT ID, ContractNumber FROM ServiceContracts) FROM Contact WHERE Id in : oldContactsMap.keyset()]); List<ServiceContract> mySCs = new List<ServiceContract>(); List<Case> myCases = new List<Case>(); for(Contact c : myContacts) { mySCs.addAll(c.ServiceContracts); myCases.addAll(c.Cases); } for(ServiceContract sc : mySCs) { sc.Contact = null; } for(Case c : myCases) { c.Contact = null; } database.update(mySCs, false); database.update(myCases, false); }Many thanks for any help
- louisa barrett 7
- May 31, 2022
- Like
- 0
Visual Studio Code and Prettier not respecting print width field
Hi all,
I have decided to swap from the dev console to visual studio code.I read there was no built in support for formatting apex and it was suggested to install Prettier, which I have done.
When the code is formatted (Shift, Alt + F) parameters in methods are being dropped to the next line. This means that only 1/4 of the actual line space is being used. Below is a screen shot of what it looks like after formatting and what I would like it to look like. After some research it was suggested to change the Prettier:Print Width property from the default value or 80 to 120, which I've done. This made no difference, I've tried increasing it 250 and it the behaviour is still the same. It has also been mentioned that the print width property doesn't work if tsLint is enabled, but I don't have that installed, so I don't think that is the issue.
I've attached some screen shots and code snippets for clarity.
Code formatting example:
There is more than enough room on the same line without the parameters dropping to the next line
Print width property
.prettierrc file
settings.json file;
Many thanks
I have decided to swap from the dev console to visual studio code.I read there was no built in support for formatting apex and it was suggested to install Prettier, which I have done.
When the code is formatted (Shift, Alt + F) parameters in methods are being dropped to the next line. This means that only 1/4 of the actual line space is being used. Below is a screen shot of what it looks like after formatting and what I would like it to look like. After some research it was suggested to change the Prettier:Print Width property from the default value or 80 to 120, which I've done. This made no difference, I've tried increasing it 250 and it the behaviour is still the same. It has also been mentioned that the print width property doesn't work if tsLint is enabled, but I don't have that installed, so I don't think that is the issue.
I've attached some screen shots and code snippets for clarity.
Code formatting example:
//Desired formatting public void OnAfterUpdate(Asset[] oldAssets, Map<ID, Asset> oldAssetsMap, Asset[] updatedAssets,Map<ID, Asset> assetsMap){ fetchAssetCounts(updatedAssets, assetsMap); } //After formatting in VS Code using Prettier public void OnAfterUpdate( Asset[] oldAssets, Map<ID, Asset> oldAssetsMap, Asset[] updatedAssets, Map<ID, Asset> assetsMap ) { fetchAssetCounts(updatedAssets, assetsMap); }Screen shot of VS Code:
There is more than enough room on the same line without the parameters dropping to the next line
Print width property
.prettierrc file
{ "trailingComma": "none", "overrides": [ { "files": "**/lwc/**/*.html", "options": { "parser": "lwc"} }, { "files": "*.{cmp,page,component}", "options": { "parser": "html" } } ] }
settings.json file;
{ "workbench.colorTheme": "Visual Studio Dark", "salesforcedx-vscode-apex.java.home": "C:\\Program Files\\Java\\jdk-11.0.12", "editor.defaultFormatter": "esbenp.prettier-vscode", "prettier.requireConfig": true, "prettier.arrowParens": "avoid", "prettier.useTabs": true, "prettier.printWidth": 120, "salesforcedx-vscode-core.retrieve-test-code-coverage": true, "prettier.proseWrap": "never", "prettier.tabWidth": 4, "eslint.runtime": "" }Does anyone have any suggestions?
Many thanks
- louisa barrett 7
- September 09, 2021
- Like
- 0
Call future method from trigger handler class method
Hi,
This is my first time using the @future annotation and was wondering if I could get some guidance.
I have a trigger on the contact, which is handled by a handler class. When a contact is deleted, I need to perfom a call out, so within the handler class I need to call a future method to perform that call out. As a future method only takes primitive data types, I have created another method which passes just the IDs to the future method. Is this the correct way to do this, or is there a better way?
I'm also a little concerned what happens if a mass delete is performed. How do you bulkify call outs?
Trigger:
Trigger handler class:
Many thanks
This is my first time using the @future annotation and was wondering if I could get some guidance.
I have a trigger on the contact, which is handled by a handler class. When a contact is deleted, I need to perfom a call out, so within the handler class I need to call a future method to perform that call out. As a future method only takes primitive data types, I have created another method which passes just the IDs to the future method. Is this the correct way to do this, or is there a better way?
I'm also a little concerned what happens if a mass delete is performed. How do you bulkify call outs?
Trigger:
trigger ContactTrigger on Contact (before delete, before insert, before update, after delete, after insert, after update) { ContactTriggerHandler handler = new ContactTriggerHandler(Trigger.isExecuting, Trigger.size); if (Trigger.isInsert && Trigger.isBefore) { handler.OnBeforeInsert(Trigger.new); } else if (Trigger.isInsert && Trigger.isAfter) { handler.OnAfterInsert(Trigger.new, Trigger.newMap); } else if (Trigger.isUpdate && Trigger.isBefore) { handler.OnBeforeUpdate(Trigger.old, Trigger.oldmap, Trigger.new, Trigger.newmap); } else if (Trigger.isUpdate && Trigger.isAfter) { handler.OnAfterUpdate(Trigger.old, Trigger.oldmap, Trigger.new, Trigger.newmap); } else if(Trigger.isDelete && Trigger.isBefore) { handler.onBeforeDelete(trigger.old, trigger.oldMap); } else if(Trigger.isDelete && Trigger.isAfter) { handler.onAfterDelete(trigger.old, trigger.oldMap); } }
Trigger handler class:
public class ContactTriggerHandler extends BaseTriggerHandler { public ContactTriggerHandler(boolean isExecuting, integer size) { super(isExecuting, size); } public void OnBeforeInsert(Contact[] newContacts) {} public void OnAfterInsert(Contact[] newContacts, Map<ID, Contact> newContactsMap) {} public void OnBeforeUpdate(Contact[] oldContacts, Map<ID, Contact> oldContactsMap, Contact[] updatedContacts, Map<ID, Contact> updatedContactsMap) {} public void OnAfterUpdate(Contact[] oldContacts, Map<ID, Contact> oldContactsMap, Contact[] updatedContacts, Map<ID, Contact> updatedContactsMap) {} public void OnBeforeDelete(Contact[] oldContacts, Map<ID, Contact> oldContactsMap) {} public void OnAfterDelete(Contact[] oldContacts, Map<ID, Contact> oldContactsMap) { passIDsToCallOut(oldContactsMap); } Private void passIDsToCallOut(Map<ID, Contact> contactsMap) { Set<Id> conIds = contactsMap.keySet(); system.debug('con Ids for forget request'); system.debug(conIds); sendForgetRequestGDPR(conIds); } @future(callout=true) Public static void sendForgetRequestGDPR(Set<id> contactIds) { Http http = new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint('https://****.com/api/auth/v1/login?email=myemail@email.co.uk&password=myPassword'); request.setMethod('POST'); request.setHeader('Content-Type', 'application/x-www-form-urlencoded'); request.setHeader('Accept', 'application/json'); HttpResponse authResponse = http.send(request); if (authResponse.getStatusCode() == 200) { system.debug('got auth!'); // Deserialize the JSON string into collections of primitive data types. Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(authResponse.getBody()); List<Object> myresults = new List<Object>(); for(Object obj : results.values()) { myresults.add(obj); } string sessionId = string.ValueOf(myresults[0]); system.debug('session Id = ' +sessionId); request = new HttpRequest(); request.setEndpoint('https://*****.com/api/v1/services/*****/gdpr/forget'); request.setMethod('POST'); request.setHeader('Content-Type','application/x-www-form-urlencoded'); request.setHeader('Accept','application/json'); request.setHeader('X-SESSION-ID',sessionId); string comment = 'API Call'; string contactId; for(Id conId : contactIds) { contactId = conId; request.setBody('record_id='+contactId+'&table_name=Contact&comment=' + EncodingUtil.urlEncode(comment, 'UTF-8')); system.debug(request); HttpResponse forgetResponse = http.send(request); if(forgetResponse.getStatusCode() == 200) { system.debug('got GDPR!'); } else { system.debug('Forget Broken =' + forgetResponse.getStatusCode()); } } } else { system.debug('Auth Broken =' + authResponse.getStatusCode()); } } }
Many thanks
- louisa barrett 7
- July 22, 2021
- Like
- 0
Send notification to Own BackUp via API when record is deleted
Hi,
I've never attempted an API link before so was wondering if someone could point me in the right direction of how this is best handled.
We currently use Own BackUp for all Salesforce data and metadata back ups. When a contact is deleted in Salesforce, at the moment I'm manually going into Own BackUp and creating a GDPR Forget request. Own BackUp have an API which allows you to send a forget request ( Forget Record (https://cdn2.hubspot.net/hubfs/2571574/api%20document-1.html#tag/GDPR/paths/~1api~1v1~1services~1{service_id}~1gdpr~1forget/post) ) and I would very much like to automate this when a contact is deleted in SF. I'm used to writing triggers, but have never done anything with APIs. If someone could give me base to start it would be very much appreciated.
Many thanks
I've never attempted an API link before so was wondering if someone could point me in the right direction of how this is best handled.
We currently use Own BackUp for all Salesforce data and metadata back ups. When a contact is deleted in Salesforce, at the moment I'm manually going into Own BackUp and creating a GDPR Forget request. Own BackUp have an API which allows you to send a forget request ( Forget Record (https://cdn2.hubspot.net/hubfs/2571574/api%20document-1.html#tag/GDPR/paths/~1api~1v1~1services~1{service_id}~1gdpr~1forget/post) ) and I would very much like to automate this when a contact is deleted in SF. I'm used to writing triggers, but have never done anything with APIs. If someone could give me base to start it would be very much appreciated.
Many thanks
- louisa barrett 7
- July 20, 2021
- Like
- 0
Lightning:InputField to automatically adjust height based on content
Hi All,
I have a recordEditForm on an Aura component which displays the core fields from the case object.
My issue is I need the standard description field to automatically expand it's height to show all the content, like it does on the detail page.
Currently I get scoll bars and the ability to drag the box to expose the text.
Is it possible with a lightning:inputfield?
I have a recordEditForm on an Aura component which displays the core fields from the case object.
My issue is I need the standard description field to automatically expand it's height to show all the content, like it does on the detail page.
Currently I get scoll bars and the ability to drag the box to expose the text.
Is it possible with a lightning:inputfield?
<div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-1"> <lightning:inputField fieldName="Description" onchange="{!c.enableButtons}"/> </div> </div>
- louisa barrett 7
- June 11, 2021
- Like
- 0
lightning:unsavedChanges and record edit form
Hi,
I have a aura component which uses a lightning:recordEditForm and a standard Lighting:button of type 'submit' to save the data. I want to implement the lightning:unsavedChanges component, which is halfway there, but when the user presses 'Save' on the unsaved changes dialog I cannot figure out how to either call the standard save function from submit button or to close the unsaved changes dialog so the user has to press save on the form.
Here is my code:
Component:
Helper:
Many thanks
I have a aura component which uses a lightning:recordEditForm and a standard Lighting:button of type 'submit' to save the data. I want to implement the lightning:unsavedChanges component, which is halfway there, but when the user presses 'Save' on the unsaved changes dialog I cannot figure out how to either call the standard save function from submit button or to close the unsaved changes dialog so the user has to press save on the form.
Here is my code:
Component:
<aura:component controller="CaseController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" > <aura:attribute name="reloadForm" type="boolean" default="true"/> <aura:attribute name="saveDisabled" type="boolean" default="true"/> <aura:attribute name="cancelDisabled" type="boolean" default="true"/> <lightning:unsavedChanges aura:id="unsaved" onsave="{!c.handleSave}" ondiscard="{!c.handleDiscard}"/> <!-- Notification library to show notifications--> <lightning:notificationsLibrary aura:id="notifLib"/> <lightning:card title="Case #"> <div class="slds-p-left_large slds-p-right_medium"> <lightning:recordEditForm aura:id="recordEditForm" objectApiName="Case" recordId="{!v.recordId}" onsuccess="{!c.handleSuccess}" density="comfy"> <aura:if isTrue="{!v.reloadForm}"> <lightning:messages /> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-2"> <lightning:inputField fieldName="Status" onchange="{!c.enableButtons}"/> <lightning:inputField aura:id="asset" fieldName="AssetId" onchange="{!c.handleAssetChange}"/> <lightning:inputField aura:id="assFaultCat" fieldName="Fault_Category__c" disabled="true" onchange="{!c.enableButtons}" /> <lightning:inputField aura:id="assFaultType" fieldName="Fault_Type__c" onchange="{!c.enableButtons}" /> </div> <div class="slds-col slds-size_1-of-2"> <lightning:inputField fieldName="Priority" onchange="{!c.enableButtons}"/> <lightning:inputField aura:id="assMakeModel" fieldName="Asset_Make_and_Model__c" /> <lightning:inputField fieldName="Interface_Type__c"/> <lightning:inputField fieldName="Connection_Method__c"/> </div> </div> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-1"> <lightning:inputField fieldName="Description" onchange="{!c.enableButtons}"/> </div> <div class="slds-col slds-size_1-of-1"> <lightning:inputField fieldName="Help_Required__c" onchange="{!c.enableButtons}"/> </div> </div> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-2"> <lightning:inputField fieldName="Solution__c"/> </div> <div class="slds-col slds-size_1-of-2"> <lightning:inputField fieldName="Solution_Details__c" onchange="{!c.enableButtons}" /> </div> </div> <aura:set attribute="else"> Saving... </aura:set> </aura:if> <lightning:button class="slds-m-top_small" name="cancel" label="Cancel" disabled = "{!v.cancelDisabled}" onclick="{!c.handleReset}"/> <lightning:button class="slds-m-top_small" variant="brand" type="submit" name="save" label="Save" disabled = "{!v.saveDisabled}" /> </lightning:recordEditForm> </div> </lightning:card> </aura:component>Controller:
({ handleAssetChange: function(component, event, helper) { console.log('asset changed'); var newID = event.getParam("value"); if(newID.length >0) { if(newID.length > 0) { console.log('helper called'); console.log(newID[0]); helper.updateAsset(component, newID[0]); } } }, enableButtons: function(component, event, helper) { console.log('field changed'); var unSavedChange = component.find('unsaved'); unSavedChange.setUnsavedChanges(true, { label: 'You have unsaved changes. Do you want to Continue?' }); helper.toggleButtons(component, false, false); }, handleSave : function(component, event, helper) { var unSavedChange = component.find('unsaved'); unSavedChange.setUnsavedChanges(false); }, handleSuccess : function(component, event, helper) { console.log('success handled'); helper.handleSuccess(component, event, helper); }, handleReset: function(component, event, helper) { console.log('Cancel clicked'); helper.toggleButtons(component, true, true); helper.reshowForm(component); } })
Helper:
({ updateAsset : function(component, assetId){ var action = component.get("c.fetchAsset"); console.log('Helper - New asset Id = ' + assetId); action.setParams({ "assetId": assetId }); action.setCallback(this, function(result){ var serverState = result.getState(); console.log('Server state = ' + serverState); console.log('Asset Update'); var res = result.getReturnValue(); console.log('res result'); console.log(res); //Ideally put a check in here to see if the new asset is covered under contract and if not, display an error. Will also have to check that the case doesn't already have a PO number assigned if (component.isValid() && serverState === "SUCCESS"){ component.find('assFaultCat').set('v.value', res.Product_Category__c); component.find('assFaultType').set('v.value', null); var toastEvent = $A.get("e.force:showToast"); console.log('the asset was changed'); /*toastEvent.setParams({ "title": "Success", "message": "The asset has been updated", "type" : "success" }); toastEvent.fire();*/ } else if (serverState === "ERROR") { var errors = result.getError(); console.log('There are errors'); console.error(errors); if(errors){ if(errors[0] && errors[0].message){ var toastEvent = $A.get("e.force:showToast"); toastEvent.setParams({ "title": "Error!", "message": errors[0].message, "mode" : "sticky", "type" : "error" }); toastEvent.fire(); } } } }); $A.enqueueAction(action); }, handleSuccess : function(component, event, helper){ console.log('handle success helper called'); component.find('notifLib').showToast({ "variant": "success", "title": "Success!", "message": "The record has been successfully updated" }); this.toggleButtons(component, true, true); }, toggleButtons: function(component, saveDisabled, cancelDisabled) { console.log('toggle buttons -' + 'Save = ' + saveDisabled + 'Cancel = '+ cancelDisabled); component.set("v.saveDisabled", saveDisabled); component.set("v.cancelDisabled", cancelDisabled); }, reshowForm: function(component) { console.log('reshow form'); component.set("v.reloadForm", false); component.set("v.reloadForm", true); } })
Many thanks
- louisa barrett 7
- May 26, 2021
- Like
- 0
How to stop all instances of a component listening for a platform event
Hi All,
On the opportunity record page I have an Aura component which has a Lightning:DataTable that displays all open tasks that meet a certain criteria. Also on the opportunity record page there is an Actions & Recommendations component which has access to 5 quick actions which create a task. What I want to be able to do is when a new task is created, the datatable to automatically refresh. I've tried using platform events(which this is the first time I've used them, so not really too sure what I'm doing). I've got an If statement in the callback to check if the task whatId matches the record Id, but this still means that every opportunity that is open on a tab is listening for the event. Not all opportunities have the data table component on the record page, and it doesn't seem that the subscription is destroyed when the tab is closed.
How do I unscribe to the event when the tab is closed? If the page is refreshed then it seems to be fine.
If there is another way to do this I'd be more than grateful for suggestions
Task Trigger Handler Code:
Component:
Controller:
Helper:
On the opportunity record page I have an Aura component which has a Lightning:DataTable that displays all open tasks that meet a certain criteria. Also on the opportunity record page there is an Actions & Recommendations component which has access to 5 quick actions which create a task. What I want to be able to do is when a new task is created, the datatable to automatically refresh. I've tried using platform events(which this is the first time I've used them, so not really too sure what I'm doing). I've got an If statement in the callback to check if the task whatId matches the record Id, but this still means that every opportunity that is open on a tab is listening for the event. Not all opportunities have the data table component on the record page, and it doesn't seem that the subscription is destroyed when the tab is closed.
How do I unscribe to the event when the tab is closed? If the page is refreshed then it seems to be fine.
If there is another way to do this I'd be more than grateful for suggestions
Task Trigger Handler Code:
Private void psTaskCreated(Task[] tasks) { List<Task_Creation_Event__e> taeList = new List< Task_Creation_Event__e>(); for(task tsk : tasks) { Task_Creation_Event__e taskEvent = new Task_Creation_Event__e(); if(tsk.whatId != null && tsk.WhatId.getSObjectType() == Opportunity.sObjectType && tsk.Project_Task__c) { Task_Creation_Event__e tce = new Task_Creation_Event__e(); tce.Opp_Id__c = tsk.WhatId; taeList.add(tce); } } //Publish event try{ if(taeList.size()>0) EventBus.publish(taeList); }catch(Exception e){ throw new auraHandledException('Broken!'); } }
Component:
<aura:component controller="OpportunityController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" > <aura:handler name="init" action="{!c.doInit}" value="{!this}"/> <aura:attribute name="mydata" type="Object"/> <aura:attribute name="mycolumns" type="List"/> <aura:attribute name="listSize" type="integer"/> <aura:attribute name="draftValues" type="Object" default="[]"/> <aura:attribute name="Task" type="Task" default="{'sObjectType':'Task'}"/> <aura:attribute name="showSpinner" type="boolean" default="false"/> <lightning:empApi aura:id="empApi" /> <div> <lightning:notificationsLibrary aura:id="notifLib"/> <aura:if isTrue="{!v.showSpinner }"> <lightning:spinner alternativeText="Loading" /> <aura:set attribute="else"> <!--To Do List Table--> <div class="slds-m-top--none slds-box slds-theme_default" > <div class="slds-align_absolute--left"> <div class="slds-text-heading_small slds-text-color_default"> Things I need to do ({!v.listSize}) <lightning:buttonicon iconName="utility:refresh" alternativeText="Refresh" variant = "brand" class=" slds-button_icon-x-small" onclick="{!c.doInit}"/> </div> </div> <div style="height: 175px;"> <lightning:datatable data="{! v.mydata }" columns="{! v.mycolumns }" keyField="Id" draftValues="{!v.draftValues}" onrowaction="{!c.handleRowAction}" onsave="{!c.handleSaveEdition}"/> </div> </div> </aura:set> </aura:if> </div> </aura:component>
Controller:
//get tasks from apex controller doInit : function(component, event, helper) { console.log('do init called'); var channel = '/event/Task_Creation_Event__e'; const replayId = -1; const empApi = component.find("empApi"); //A callback function that's invoked for every event received const callback = function (message) { var msg = message.data.payload; console.log('msg = '+JSON.stringify(msg)); console.log('Message returned : ' +msg.Opp_Id__c ); if(msg.Opp_Id__c === component.get("v.recordId")) { console.log('Fetch tasks about to be called'); helper.fetchTasks_Active(component); } }; // Subscribe to the channel and save the returned subscription object. empApi.subscribe(channel, replayId, callback).then(function(newSubscription) { console.log("Subscribed to channel 1" + channel); }); const errorHandler = function (message) { console.error("Received error ", JSON.stringify(message)); }; empApi.onError(errorHandler); helper.fetchTasks_Active(component); },
Helper:
fetchTasks_Active : function(component){ var actions = [ {label: 'Show comments', name:'show_comments'}, {label: 'Complete task', name:'complete_task'}, {label: 'View task', name:'view_task'} ]; component.set('v.mycolumns', [ {label: 'Due Date', fieldName: 'ActivityDate', type: 'date', editable:'true'}, {label: 'Task Type', fieldName: 'Task_Type__c', type: 'text'}, {label: 'Subject', fieldName: 'Subject', type: 'text', editable:'true'}, {label: 'Comments', fieldName: 'Description', type: 'text', wrapText: true, editable:'true'}, {label: 'Contact', fieldName: 'WhoName', type: 'text'}, {label: 'Status', fieldName: 'Status', type: 'text'}, {type: 'action', typeAttributes: {rowActions: actions}} ]); var action = component.get("c.fetchOpenProjectTasks"); action.setParams({ "oppId": component.get("v.recordId") }); action.setCallback(this, function(result){ var serverState = result.getState(); console.log('Server state = ' + serverState); console.log('Fetch active tasks'); var res = result.getReturnValue(); console.log('res result'); console.log(res); if (component.isValid() && serverState === "SUCCESS"){ component.set("v.listSize",res.length); var rows = res; for (var i = 0; i < rows.length; i++) { var row = rows[i]; if(row.Who) { row.WhoName = row.Who.Name; if(row.TaskRelations.length >1) { var relatedWho = row.TaskRelations.length -1; row.WhoName = row.Who.Name + ' +' + relatedWho.toString(); } } } component.set("v.mydata",res); } else if (serverState === "ERROR") { var errors = result.getError(); console.log('There are errors'); console.error(errors); if(errors){ if(errors[0] && errors[0].message){ self.fetchErrors(component, errors, self); } } } }); $A.enqueueAction(action); },Many thanks
- louisa barrett 7
- April 30, 2021
- Like
- 0
Aura datatable to show error messages on inline edit
Hi All,
I am fairly new to lightning components and am struggling to get a datatbale to show any server side errors. I have looked at the documentation (Salesforce Documention (https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/example#lightningcomponentdemo:exampleDatatableInlineEdit) )and tried to implement it to my scenario but cannot get it to work.
This is my code:
Component:
Controller:
Apex Controller:
(I'm not doing any validation in this method at the moment, but I will)
Any help would be much appreciated,
Thank you
I am fairly new to lightning components and am struggling to get a datatbale to show any server side errors. I have looked at the documentation (Salesforce Documention (https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/example#lightningcomponentdemo:exampleDatatableInlineEdit) )and tried to implement it to my scenario but cannot get it to work.
This is my code:
Component:
<aura:component controller="BuildUpChecklistController" implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId"> <aura:handler name="init" action="{!c.doInit}" value="{!this}"/> <aura:handler event="force:refreshView" action="{!c.doInit}"/> <aura:attribute name="mydata" type="Object"/> <aura:attribute name="mycolumns" type="List"/> <aura:attribute name="errors" type="Object" default="[]"/> <aura:attribute name="draftValues" type="Object" default="[]"/> <aura:attribute name="listSize" type="Integer" default="0"/> <!--User List Table--> <div class="slds-m-top--none slds-box slds-theme_default" > <div class="slds-align_absolute--left"> <div class="slds-text-heading_small slds-text-color_default"> Update build notes and on site fields <lightning:helptext content="Help!"/> </div> </div> <lightning:datatable data="{! v.mydata }" columns="{! v.mycolumns }" showRowNumberColumn= "true" wrapTextMaxLines="3" keyField="Id" errors="{!v.errors}" draftValues="{!v.draftValues}" onsave="{!c.handleSaveEdition}"/> </div> </aura:component>
Controller:
handleSaveEdition: function (component, event, helper) { var draftValues = event.getParam('draftValues'); var action = component.get("c.updateOLIs"); action.setParams({"OLIs" : draftValues}); action.setCallback(this, function(result){ var state = result.getState(); if(state === "SUCCESS"){ component.set("v.errors", []); component.set("v.draftValues", []); var toastEvent = $A.get("e.force:showToast"); toastEvent.setParams({ "title": "Success", "message": "The opportunity line items have been updated", "type" : "success" }); toastEvent.fire(); $A.get('e.force:refreshView').fire(); //} } else if(state === "ERROR"){ //I don't know what to use here to display any server side errors //on the relevant rows of the datatable // } else if (status === "INCOMPLETE"){ var toastEvent = $A.get("e.force:showToast"); toastEvent.setParams({ "title": "Error!", "message": "'No response from server or client'", "type" : "error" }); toastEvent.fire(); $A.get('e.force:refreshView').fire(); } }); $A.enqueueAction(action); },
Apex Controller:
(I'm not doing any validation in this method at the moment, but I will)
@AuraEnabled public static void updateOLIs(List<OpportunityLineItem> OLIs) { update OLIs; }
Any help would be much appreciated,
Thank you
- louisa barrett 7
- March 19, 2021
- Like
- 0
Event being handled even when tab is not open
I have a custom tab that displays a lighning component which on a click event allows a user to edit a record.
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
Many thanks,
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
<aura:handler event="force:showToast" action="{!c.handleToastEvent}"/> handleToastEvent: function(component, event, helper){ var toastMessageParams = event.getParams(); var message = toastMessageParams.message; if(message.includes('Resource Placeholder') && message.includes('was saved')){ var calendar = component.get('v._Calendar'); var calendarEvent = event.getParam("calendarEvent") helper.fetchCalendarEvents(component, calendar, calendarEvent); } }
Many thanks,
- louisa barrett 7
- August 10, 2020
- Like
- 1
lightning component get mouse position on nested components
Hi,
I have a scenario where I need to get the mouse position for nested aura components.
I have tried using getBoundingClientRect, clientX/Y, pageX/Y, offsetLeft/Top, but they are not taking into consideration the space that the other component could be taking up above or to the side of it.
So in the example below I need to get the mouse position from within the Calendar_Scheduling component, but that component is not aware of the CalendarFilters component that is sitting above it. So when using any of the getBoundingClientRect, clientY, pageY or offsetTop the position that is being returned is incorrect.
Is there a property that I can use that will return the correct co-ordinates regardless of any other components that are on the page
Many thanks
I have a scenario where I need to get the mouse position for nested aura components.
I have tried using getBoundingClientRect, clientX/Y, pageX/Y, offsetLeft/Top, but they are not taking into consideration the space that the other component could be taking up above or to the side of it.
So in the example below I need to get the mouse position from within the Calendar_Scheduling component, but that component is not aware of the CalendarFilters component that is sitting above it. So when using any of the getBoundingClientRect, clientY, pageY or offsetTop the position that is being returned is incorrect.
Is there a property that I can use that will return the correct co-ordinates regardless of any other components that are on the page
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global"> <lightning:layout class="slds-theme_default" multipleRows = "true"> <lightning:layoutItem size="12" mediumDeviceSize="12" padding="around-small"> <c:CalendarFilters Initialised="{!v.initialised}" Department="{!v.resourceDepartment}" Location="{!v.resourceLocation}" ShowWorkOrders="{!v.showWorkOrders}" ShowProfessionalServiceWork="{!v.showPSWork}" ShowPlaceholders="{!v.showPlaceholders}" IsSchedulingCalendar="{!v.isSchedulingCalendar}" ProjectManager="{!v.projectManager}"/> </lightning:layoutItem> <lightning:layoutItem size="12"> <c.Calendar_Scheduling Enabled="{!v.initialised}" Department="{!v.resourceDepartment}" Location="{!v.resourceLocation}" ProjectManager="{!v.projectManager}" IsSchedulingCalendar="{!v.isSchedulingCalendar}"/> </lightning:layoutItem> </lightning:layout> </aura:component>
Many thanks
- louisa barrett 7
- May 25, 2020
- Like
- 0
SLDS Table with horizontal and vertical scroll and fixed headers
Hi,
I have a table with horizontal and vertical scroll bars and would like to lock the column headers when scrolling in either direction.
At the moment it's scrolling ok, and when you scroll vertically the headers are fixed, but the column headers do not move when scrolling horizontally. I'm guessing it's because of the slds-cell-fixed, but I'm not sure what to change it to.
Any help would be much appreciated
I have a table with horizontal and vertical scroll bars and would like to lock the column headers when scrolling in either direction.
<lightning:layoutItem size="12" padding="around-small"><b>Work Orders</b> <div class="external-events slds-table--header-fixed_container" style="height:20rem;"> <div class=" slds-scrollable " style="height:100%;"> <table class="slds-table slds-table_bordered slds-table_cell-buffer slds-table--header-fixed"> <thead> <tr> <th scope="col"> <div class="slds-cell-fixed">WO#</div> </th> <th scope="col"> <div class="slds-cell-fixed">Account</div> </th> <th scope="col"> <div class="slds-cell-fixed">Postcode</div> </th> <th scope="col"> <div class="slds-cell-fixed">Status</div> </th> <th scope="col"> <div class="slds-cell-fixed" >Subject</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.woList}" var="item"> <tr> <td> <div class="{!'fc-event ' + item.className}" data-id="{!item.id}" data-tag="{!item.tag}" onclick="{!c.handleClick}">{!item.WorkOrderNumber} </div> </td> <td> <div>{!item.accountName}</div> </td> <td> <div>{!item.postcode}</div> </td> <td> <div>{!item.Status}</div> </td> <td> <div>{!item.Subject}</div> </td> </tr> </aura:iteration> </tbody> </table> </div> </div> </lightning:layoutItem
At the moment it's scrolling ok, and when you scroll vertically the headers are fixed, but the column headers do not move when scrolling horizontally. I'm guessing it's because of the slds-cell-fixed, but I'm not sure what to change it to.
Any help would be much appreciated
- louisa barrett 7
- May 20, 2020
- Like
- 0
SLDS Tooltip text is not wrapping
Hi,
I am trying to show a tooltip within an aura:iteration. The tooltip is now displaying but the text is not wrapping onto the next line, it's continuing beyond the boundaries of the toolttip containiner.
I've changed the text colour to make it a little clearer what's happening
Component
Controller:
Any help would be much appreciated
Thanks
I am trying to show a tooltip within an aura:iteration. The tooltip is now displaying but the text is not wrapping onto the next line, it's continuing beyond the boundaries of the toolttip containiner.
I've changed the text colour to make it a little clearer what's happening
Component
<lightning:layoutItem size="12" padding="around-small"><b>Professional Services</b> <div class="psWork-events slds-scrollable"> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr> <th scope="col"> <div>Work</div> </th> <th scope="col"> <div>Account Name</div> </th> <th scope="col"> <div>Start</div> </th> <th scope="col"> <div># Days</div> </th> <th scope="col"> <div># Alloc</div> </th> <th scope="col"> <div># Req</div> </th> <th scope="col"> <div>Project Manager</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.swList}" var="item" indexVar="index"> <tr data-selected-Index="{!index}"> <td> <div class="{!'fc-event ' + item.className}" data-id="{!item.id}" data-title="{!item.title}" data-tag="{!item.tag}" data-starts="{!item.starts}" data-opp = "{!item.navigationId}" data-index="{!index}" onmouseover="{!c.handleMouseOver}" onmouseout="{!c.handleMouseOut}" onclick="{!c.handleClick}"> {!item.title} <div aura:id="ps-hover" class="slds-hide slds-popover slds-popover_tooltip slds-nubbin_left" style="position:absolute;top:-4px;left:35px"> <div class="slds-popover__body" style="color:red;"> Some really long text that should drop onto the next line, but what's actually happening is the text is continuing outside of the tooltip boundaries </div> </div> </div> </td> <td> <div>{!item.accountName}</div> </td> <td> <div><lightning:formattedDateTime value ="{!item.starts}" month="short" day="2-digit" /> </div> </td> <td> <div>{!item.numberOfDays}</div> </td> <td> <div>{!item.alcTechCount}</div> </td> <td> <div>{!item.reqTechCount}</div> </td> <td> <div>{!item.ProjectManager}</div> </td> </tr> </aura:iteration> </tbody> </table> </div> </lightning:layoutItem>
Controller:
handleMouseOver : function(component,event,helper){ console.log('Mouse entered'); var items = component.find("ps-hover"); if(!items.length) items = [items]; console.log('Removing class for =', parseInt(event.target.dataset.index )); $A.util.removeClass(items[parseInt(event.target.dataset.index)],'slds-hide'); }, handleMouseOut : function(component,event,helper){ console.log('Mouse left'); var items = component.find("ps-hover"); if(!items.length) items = [items]; console.log('Adding class for =', parseInt(event.target.dataset.index )); $A.util.addClass(items[parseInt(event.target.dataset.index)],'slds-hide'); }
Any help would be much appreciated
Thanks
- louisa barrett 7
- May 12, 2020
- Like
- 0
Full Calendar V4 and tooltips
Hi,
Has anyone had any joy in using tooltips (popper and tooltip.js) with the Full Calendar Scheduler V4 resource timeline view?
I have created a very simple cut down version to demonstrate the issue I'm having. The tooltip is being created but it isn't being displayed. If I create the project in codepen using the exact same files as are in my static resources it works as intended.
Component
Controller:
Style:
I have also tried removing everything from the style class with the same result
From the browser console you can see the tooltip is being created, but it isn't being displayed. As this is working in codepen I'm assuming Salesforce is blocking something, but I'm not really too sure where to start
Any help would be much appreciated
Has anyone had any joy in using tooltips (popper and tooltip.js) with the Full Calendar Scheduler V4 resource timeline view?
I have created a very simple cut down version to demonstrate the issue I'm having. The tooltip is being created but it isn't being displayed. If I create the project in codepen using the exact same files as are in my static resources it works as intended.
Component
<aura:component implements="force:appHostable" access="global"> <ltng:require scripts="{!join(',', $Resource.FullCalendarCoreMainV4_3_1JS, $Resource.FullCalendarInteractionV4_3_1JS, $Resource.FullCalendarDayGridMainV4_3_1JS, $Resource.FullCalendarTimelineMainV4_3_1JS, $Resource.FullCalendarTimegridMainV4_3_1JS, $Resource.FullCalendarResourceCommonMainV4_3_1JS, $Resource.FullCalendarResourceTimelineMainV4_3_1JS, $Resource.FullCalendarResourceDayGridMainV4_3_1JS, $Resource.FullCalendarResourceTimegridMainV4_3_1JS, $Resource.PopperMin, $Resource.TooltipMin )}" styles="{!join(',', $Resource.FullCalendarCoreMainV4_3_1CSS, $Resource.FullCalendarDayGridMainV4_3_1CSS, $Resource.FullCalendarTimelineMainV4_3_1CSS, $Resource.FullCalendarResourceTimelineMainV4_3_1CSS)}" afterScriptsLoaded="{!c.scriptsLoaded}" /> <!-- COMPONENT UI --> <div id="calendar"/> </aura:component>
Controller:
({ scriptsLoaded : function(component, event, helper) { console.log('Calendar scripts loaded'); var calendarElement = document.getElementById('calendar'); var calendar = new FullCalendar.Calendar(calendarElement,{ plugins:['resourceTimeline', 'dayGrid'], header: { left: 'prev,next today', center: 'title', right: 'timelineFiveDays, resourceTimelineDay, dayGridMonth' }, defaultView: 'timelineFiveDays', views: { timelineFiveDays:{ type: 'resourceTimeline', duration: { weeks: 1 }, slotDuration: {days: 1}, weekends: false, buttonText: '5 Days' }, }, resources:[ { id:'a', title:'Person A' }, { id:'b', title:'Person B' } ], events: [ { title: 'Event 1', description: 'Description for Event 1', start: '2020-04-27', resourceId: 'a' }, { title: 'Event 2', description: 'Description for Event 2', start: '2020-04-28', resourceId: 'a' }, { title: 'Event 3', description: 'Description for Event 3', start: '2020-04-29', resourceId: 'a' } ], eventRender: function(info) { var tooltip = new Tooltip(info.el, { title: info.event.extendedProps.description, placement: 'top', trigger: 'hover', container: 'body' }); console.log(tooltip); }, }); calendar.render(); }, })
Style:
I have also tried removing everything from the style class with the same result
.THIS .popper .tooltip { position: absolute; z-index: 9999; background: #FFC107; color: black; width: 150px; border-radius: 3px; box-shadow: 0 0 2px rgba(0,0,0,0.5); padding: 10px; text-align: center; } .THIS .style5 .tooltip { background: #1E252B; color: #FFFFFF; max-width: 200px; width: auto; font-size: .8rem; padding: .5em 1em; } .THIS .popper .popper__arrow .tooltip .tooltip-arrow { width: 0; height: 0; border-style: solid; position: absolute; margin: 5px; } .THIS .tooltip .tooltip-arrow .popper .popper__arrow { border-color: #FFC107; } .THIS .style5 .tooltip .tooltip-arrow { border-color: #1E252B; } .THIS .popper[x-placement^="top"] .tooltip[x-placement^="top"] { margin-bottom: 5px; } .THIS .popper[x-placement^="top"] .popper__arrow .tooltip[x-placement^="top"] .tooltip-arrow { border-width: 5px 5px 0 5px; border-left-color: transparent; border-right-color: transparent; border-bottom-color: transparent; bottom: -5px; left: calc(50% - 5px); margin-top: 0; margin-bottom: 0; } .THIS .popper[x-placement^="bottom"] .tooltip[x-placement^="bottom"] { margin-top: 5px; } .THIS .tooltip[x-placement^="bottom"] .tooltip-arrow .popper[x-placement^="bottom"] .popper__arrow { border-width: 0 5px 5px 5px; border-left-color: transparent; border-right-color: transparent; border-top-color: transparent; top: -5px; left: calc(50% - 5px); margin-top: 0; margin-bottom: 0; } .THIS .tooltip[x-placement^="right"] .popper[x-placement^="right"] { margin-left: 5px; } .THIS .popper[x-placement^="right"] .popper__arrow .tooltip[x-placement^="right"] .tooltip-arrow { border-width: 5px 5px 5px 0; border-left-color: transparent; border-top-color: transparent; border-bottom-color: transparent; left: -5px; top: calc(50% - 5px); margin-left: 0; margin-right: 0; } .THIS .popper[x-placement^="left"] .tooltip[x-placement^="left"] { margin-right: 5px; } .THIS .popper[x-placement^="left"] .popper__arrow .tooltip[x-placement^="left"] .tooltip-arrow { border-width: 5px 0 5px 5px; border-top-color: transparent; border-right-color: transparent; border-bottom-color: transparent; right: -5px; top: calc(50% - 5px); margin-left: 0; margin-right: 0; }Browser Console
From the browser console you can see the tooltip is being created, but it isn't being displayed. As this is working in codepen I'm assuming Salesforce is blocking something, but I'm not really too sure where to start
Any help would be much appreciated
- louisa barrett 7
- April 29, 2020
- Like
- 0
Get field values from metadata.layoutItem
I was wondering if anyone knew of a way to get the values of the field within a page layout section. Within a trigger I want to grab the fields and values assigned, that are within a particular section, and then calculate an average based on the field values.
I've got the field names and was hoping there was a way I could get the value.
Many thanks
I've got the field names and was hoping there was a way I could get the value.
private void setFusionScore(Training_Self_Assessment__c[] newSAs) { for(Training_Self_Assessment__c tsa : newSAs) { system.debug('TSA trigger'); List<Metadata.Metadata> layouts = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, new List<String> {'Training_Self_Assessment__c-Training Record Layout'}); system.assertEquals(1, layouts.size()); Metadata.Layout layoutMd = (Metadata.Layout)layouts.get(0); for (Metadata.LayoutSection section : layoutMd.layoutSections) { if(section.label == 'Fusion') { for (Metadata.LayoutColumn column : section.layoutColumns) { if (column.layoutItems != null) { for (Metadata.LayoutItem item : column.layoutItems) { system.debug('Field Name = ' + item.field); system.debug('Field Value = ' + item.??); } } } } } } }
Many thanks
- louisa barrett 7
- February 24, 2020
- Like
- 0
Lightning Console close workspace and sub tabs
Does anyone know how to close a workspace(primary) tab and it's sub tabs?
The below only returns the subtab. I need to close the primary and any subtabs.
The below only returns the subtab. I need to close the primary and any subtabs.
var workspaceAPI = component.find("workspace"); workspaceAPI.getEnclosingTabId().then(function(tabId) { var enclosingTabId = tabId; workspaceAPI.closeTab({tabId: enclosingTabId}); })Many thanks
- louisa barrett 7
- November 14, 2019
- Like
- 0
Lightning recordEditForm onSuccess method is not being called if component is hidden in the onSubmit method
I have a lightning component that closes a case. Depending on the button that is pressed it either closes the case and leaves the workspace tab open or closes the case and the workspace tab.
All is working great until I set the visibility on the component. I don't want it to show if the case status is closed.
When the above criteria is set on the component, the onSuccess method is not called, only the onLoad and handleSumbit function that is called from the click event of the 2 save buttons.
Is there a way I can set a visibility criteria on the component and still have the onSuccess method being called?
Component
Thanks
All is working great until I set the visibility on the component. I don't want it to show if the case status is closed.
When the above criteria is set on the component, the onSuccess method is not called, only the onLoad and handleSumbit function that is called from the click event of the 2 save buttons.
Is there a way I can set a visibility criteria on the component and still have the onSuccess method being called?
Component
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId"> <lightning:workspaceAPI aura:id="workspace"/> <aura:attribute name="showSpinner" type="Boolean" default="true"/> <aura:attribute name="closeTab" type="Boolean" default="true"/> <aura:if isTrue="{!v.showSpinner}"> <lightning:spinner /> </aura:if> <div class="slds-box slds-theme_default"> <div class="slds-text-title_bold">Close the Case</div> <lightning:recordEditForm aura:id="recordEditor" onload="{!c.handleLoad}" onsuccess="{!c.handleSuccess}" recordId = "{!v.recordId}" objectApiName="Case"> <lightning:messages /> <div class="slds-grid"> <div class="slds-col slds-size_1-of-2"> <lightning:inputField aura:id="fieldStatus" fieldName="Status" disabled="true" /> <lightning:inputField aura:id="field" fieldName="Fault_Type__c" /> <lightning:inputField aura:id="field" fieldName="Solution_Details__c" /> </div> <div class="slds-col slds-size_1-of-2"> <lightning:inputField aura:id="field" fieldName="Fault_Category__c" disabled="true" /> <lightning:inputField aura:id="field" fieldName="Solution__c" /> </div> </div> <div class="slds-m-top_medium"> <lightning:button aura:id="button3" variant="neutral" name="Cancel" label="Cancel" onclick="{!c.handleCancel}" /> <lightning:button aura:id="button2" variant="brand" type="button" name="save2" label="Close Case" onclick="{!c.handleSubmit}" /> <lightning:button aura:id="button1" variant="brand" type="button" name="save" label="Close Case and Tab" onclick="{!c.handleSubmit}"/> </div> </lightning:recordEditForm> </div> </aura:component>Controller
({ handleLoad : function(component, event, helper) { console.log('handle handleLoad'); component.find("fieldStatus").set("v.value", "Closed"); component.set("v.showSpinner", false); }, handleSubmit : function(component, event, helper) { event.preventDefault(); // Prevent default submit component.find('recordEditor').submit(); // Submit form console.log('handle handleSubmit'); if(event.getSource().getLocalId() == 'button2'){ component.set("v.closeTab", false); } }, handleSuccess : function(component, event, helper) { console.log('record updated successfully'); component.set("v.showSpinner", false); // Success! Prepare a toast UI message var resultsToast = $A.get("e.force:showToast"); resultsToast.setParams({ "title": "Case Saved", "message": "The case has been closed" }); resultsToast.fire(); var closeTab2 = component.get("v.closeTab"); console.log(closeTab2); //Below should only fire if a specific lighting button was pressed if(closeTab2){ var workspaceAPI = component.find("workspace"); console.log('closing tab'); workspaceAPI.getFocusedTabInfo().then(function(response) { var focusedTabId = response.tabId; workspaceAPI.closeTab({tabId: focusedTabId}); }) .catch(function(error) { console.log(error); }); } }, handleCancel: function(component, event, helper) { console.log('updated cancelled'); component.find('field').forEach(function(f) { f.reset(); }); } })
Thanks
- louisa barrett 7
- November 13, 2019
- Like
- 0
Get ID of lightning:button that was used in the onsuccess attribute on a Lightning:recordEditForm
Hi,
I was wondering if there was a way to get the ID of the button that was clicked on a recordEditForm within the onsuccess method.
I have tried
console.log(event.getSource().getLocalId());
but that just returns the ID of the recordEditForm, not the button that was clicked.
The reason I need this is I want to display two buttons, one that simply updates the case and the other which updates the case and closes the workspace tab
This is my component
Any help would be much appreciated
I was wondering if there was a way to get the ID of the button that was clicked on a recordEditForm within the onsuccess method.
I have tried
console.log(event.getSource().getLocalId());
but that just returns the ID of the recordEditForm, not the button that was clicked.
The reason I need this is I want to display two buttons, one that simply updates the case and the other which updates the case and closes the workspace tab
This is my component
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId"> <lightning:workspaceAPI aura:id="workspace"/> <aura:attribute name="showSpinner" type="Boolean" default="true"/> <aura:if isTrue="{!v.showSpinner}"> <lightning:spinner /> </aura:if> <div class="slds-box slds-theme_default"> <div class="slds-text-title_bold">Updates the status to closed and closes the primary tab</div> <lightning:recordEditForm aura:id="recordEditor" onload="{!c.handleLoad}" onsubmit="{!c.handleSubmit}" onsuccess="{!c.handleSuccess}" recordId = "{!v.recordId}" objectApiName="Case"> <lightning:messages /> <lightning:inputField fieldName="Fault_Category__c" disabled="true" /> <lightning:inputField fieldName="Fault_Type__c" /> <lightning:inputField fieldName="Solution__c" /> <lightning:inputField fieldName="Solution_Details__c" /> <div class="slds-m-top_medium"> <lightning:button aura:id="button1" value="value1" variant="brand" type="submit" name="save" label="Close Case and Tab" /> <lightning:button aura:id="button2" value="value2" variant="brand" type="submit" name="save2" label="Close Case" /> </div> </lightning:recordEditForm> </div> </aura:component>This is the controller
({ handleLoad : function(component, event, helper) { console.log('handle handleLoad'); component.set("v.showSpinner", false); }, handleSubmit : function(component, event, helper) { event.preventDefault(); // Prevent default submit var fields = event.getParam("fields"); fields["Status"] = 'Hold'; component.find('recordEditor').submit(fields); // Submit form console.log('handle handleSubmit'); }, handleSuccess : function(component, event, helper) { console.log('record updated successfully'); //The below is returning the id of the Lighting:recordEditForm console.log(event.getSource().getLocalId()); component.set("v.showSpinner", false); // Success! Prepare a toast UI message var resultsToast = $A.get("e.force:showToast"); resultsToast.setParams({ "title": "Case Saved", "message": "The case has been closed" }); resultsToast.fire(); //Below should only fire if a specific lighting button was pressed var workspaceAPI = component.find("workspace"); console.log('closing tab'); workspaceAPI.getFocusedTabInfo().then(function(response) { var focusedTabId = response.tabId; workspaceAPI.closeTab({tabId: focusedTabId}); }) .catch(function(error) { console.log(error); }); } })I have highlighted the commented code in bold in the controller where I need to reference the button that was clicked
Any help would be much appreciated
- louisa barrett 7
- November 12, 2019
- Like
- 0
Before trigger and roll up summary fields
I was hoping someone could explain to me why the below trigger is working.
My test class for the below trigger is failing, which I understand why. Roll Up summaries are calculated once the after trigger has run, so in my before tiggers the values have not yet been updated.
What I don't understand though is why the trigger is working though.
The field 'Hardware_Maintenance_Total__c' is a formula field based on a roll up summary and 2 standard currency field.
The trigger simply increments the 'Change_Revision__c' value by 1 if the hardware total is changed
Method called by before trigger
Debug when ran changing values in the record page itself
11:12:40.3 (61046491)|USER_DEBUG|[90]|DEBUG|New Hardware maintenance total = 43.72 Old Hardware maintenance total = 21.33
Debug when running test class
11:44:29.779 (7880532817)|USER_DEBUG|[78]|DEBUG|New Hardware maintenance total = 21.33 Old Hardware maintenance total = 21.33
As I say, I understand why the test class is failing, the roll up summaries will not have been calculated as yet, so the formula field I am checking 'Hardware_Maintenance_Total__c' will not have been updated at that point.
So why is the trigger actually working?
Many thanks
My test class for the below trigger is failing, which I understand why. Roll Up summaries are calculated once the after trigger has run, so in my before tiggers the values have not yet been updated.
What I don't understand though is why the trigger is working though.
The field 'Hardware_Maintenance_Total__c' is a formula field based on a roll up summary and 2 standard currency field.
The trigger simply increments the 'Change_Revision__c' value by 1 if the hardware total is changed
Method called by before trigger
private void updateChangeRevision(Map<ID, Opportunity> oldOppsMap, Opportunity[] opps) { for(Opportunity opp : opps) { Opportunity oldOpp = oldOppsMap != null ? oldOppsMap.get(opp.Id) : null; system.debug('New Hardware maintenance total = ' + opp.Hardware_Maintenance_Total__c + ' Old Hardware maintenance total = ' + oldOpp.Hardware_Maintenance_Total__c); if(oldOpp != null && opp.Hardware_Maintenance_Total__c != oldOpp.Hardware_Maintenance_Total__c) { opp.Change_Revision__c = opp.Change_Revision__c != null ? opp.Change_Revision__c +1 : 1; } } }
Debug when ran changing values in the record page itself
11:12:40.3 (61046491)|USER_DEBUG|[90]|DEBUG|New Hardware maintenance total = 43.72 Old Hardware maintenance total = 21.33
Debug when running test class
11:44:29.779 (7880532817)|USER_DEBUG|[78]|DEBUG|New Hardware maintenance total = 21.33 Old Hardware maintenance total = 21.33
As I say, I understand why the test class is failing, the roll up summaries will not have been calculated as yet, so the formula field I am checking 'Hardware_Maintenance_Total__c' will not have been updated at that point.
So why is the trigger actually working?
Many thanks
- louisa barrett 7
- July 29, 2019
- Like
- 0
flow from VF page being called twice
I have a VF page which uses a lightning component to call a flow(checks and decisions are made in the flow to determine if the asset should be deleted) to delete an asset. Depending on whether the user is in Classic or a console view the behaviour should be different. I use an identical page to delete a case rather than an asset and it works perfectly.
However when the asset is deleted. the flow appears to be called again. I'm getting the following error via email
This is my VF page that calls the flow
If I use the original method to call the flow(commented text at the top of the page' it works fine.
Any help would be much appreciated
However when the asset is deleted. the flow appears to be called again. I'm getting the following error via email
Flow Details Flow API Name: Delete_Asset Type: Screen Flow Version: 1 Status: Active Org: CRB Cunninghams (00Db0000000eIN5) Flow Interview Details Interview Label: Delete Asset 18/03/2019 10:27 Current User: Louisa Barrett (005b0000003IbLU) Start time: 18/03/2019 10:27 Duration: 0 seconds How the Interview Started Louisa Barrett (005b0000003IbLU) started the flow interview. Some of this flow's variables were set when the interview started. AssetID = 02i0J00000XVygLQAT FAST LOOKUP: GetAsset Find all Asset records where: Id Equals {!AssetID} (02i0J00000XVygLQAT) Assign those records to {!Asset}. Save these field values in the variable: Id, Name, Added_to_Service_Contract__c, Service_Contract__c, Service_Contract_Status__c, Service_Contract_Start_Date__c, Service_Contract_End_Date__c, AccountId Result Failed to find records. ________________________________________ Salesforce Error ID: 624516304-414064 (-1789764336)
This is my VF page that calls the flow
<apex:page standardController="Asset" lightningStylesheets="true" > <!-- Orignal method to call flow --> <!--<flow:interview name="Delete_Asset" finishLocation="/{!Asset.AccountID}"> <apex:param name="AssetID" value="{!Asset.Id}"/> </flow:interview>--> <apex:includeScript value="/support/console/40.0/integration.js"/> <html> <head> <apex:includeLightning /> </head> <body class="slds-scope"> <div id="flowContainer" /> <script type="text/javascript"> var returnID = "{!Asset.Account.Id}"; var statusChange = function (event) { console.log('Status change = ' + event.getParam("status")); if(event.getParam("status") === "FINISHED") { // Use my return Id to open a tab if (sforce.console.isInConsole()) { sforce.console.getEnclosingTabId(closeSubtab); sforce.console.getFocusedPrimaryTabId(refreshPrimaryTab); } else { window.parent.location = '/' + returnID; } } }; $Lightning.use ("c:TestLightningApp2", function() { // Create the flow component console.log('function called'); $Lightning.createComponent("lightning:flow", {"onstatuschange":statusChange}, "flowContainer", function (component) { // Set my input variables var inputVariables = [ { name : 'AssetID', type : 'String', value : '{!Asset.Id}' } ]; // Start the flow and pass in the input variables component.startFlow("Delete_Asset", inputVariables); } ); } ); var closeSubtab = function closeSubtab(result) { var tabId = result.id; sforce.console.closeTab(tabId); } var refreshPrimaryTab = function getTabId(result) { var tabId = result.id; sforce.console.refreshPrimaryTabById(tabId, true); } </script> </body> </html> </apex:page>
If I use the original method to call the flow(commented text at the top of the page' it works fine.
Any help would be much appreciated
- louisa barrett 7
- March 18, 2019
- Like
- 0
Visual force pages with shared controller and visual flow
I need to get a collection variable from a flow and then pass it to another vf page.
The problem is the constructor is being called again and causing the flow variable to be null. I have set the redirect to be false, but this doesn't seem to be making any difference.
If I remove the flow aspect from the page, it works fine.
I've copied in the extension class and the two visual force pages.
Does anyone know if this is possible when calling a flow from the first page?
Extention class:
VF page(DeliveryNote3) that is called for the finish location. This page renders as a pdf:
Many thanks for any assistance
The problem is the constructor is being called again and causing the flow variable to be null. I have set the redirect to be false, but this doesn't seem to be making any difference.
If I remove the flow aspect from the page, it works fine.
I've copied in the extension class and the two visual force pages.
Does anyone know if this is possible when calling a flow from the first page?
Extention class:
public class DeliveryNoteFlowController { private final Opportunity myOpp; public DeliveryNoteFlowController(ApexPages.StandardController stdController) { this.myOpp = (Opportunity)stdController.getRecord(); system.debug('Opp ID = ' + myOpp.Id); } public Flow.Interview.DeliveryNote myflow { get; set; } public List<OpportunityLineItem> getMyOLIs() { if (myflow == null) { system.debug('Flow is null'); return null; } else { system.debug('OLI count = ' + myFlow.SelectedOLIs.Size()); return (List<OpportunityLineItem>)myflow.SelectedOLIs; } } public PageReference getFinishLocation() { PageReference pgr = Page.DeliveryNote3; pgr.setRedirect(true); return pgr; } }VF page that launches flow:
<apex:page standardController="Opportunity" extensions="DeliveryNoteFlowController"> <flow:interview name="DeliveryNote" interview="{!myFlow}" finishLocation="{!FinishLocation}"> <apex:param name="OppId" value="{!Opportunity.id}"/> </flow:interview> </apex:page>
VF page(DeliveryNote3) that is called for the finish location. This page renders as a pdf:
<apex:page standardController="Opportunity" extensions="DeliveryNoteFlowController" standardStylesheets="false" applyHtmlTag="false" sidebar="false" readOnly="true" showHeader="false" renderAs="pdf"> <head> <style type="text/CSS"> body{ font-family:"Verdana",Helvetica,Arial,sans-serif; } .table-bordered { border: 1px solid #A9A9A9; border-collapse : collapse; font-size : .7em; border-width: thin; } .table-noborder { border: 0; font-size : .7em; } thead>tr>th { vertical-align: bottom; border: 1px solid #202d79; border-spacing: 0; text-align:left; border-collapse: collapse; background : #202d79; color:white; } .td-noborder { vertical-align: bottom; border:0 ; border-spacing: 0; border-collapse: collapse; text-align:left; width:50%; } td { vertical-align: center; border: 1px solid #A9A9A9; border-spacing: 0; border-collapse: collapse; text-align:left; } .header>td{ font-weight:bold; background : #c4c4c4; } .echoArea>td{ padding:10px; } </style> </head> <body> <img src="{!$Resource.Logo}" alt="Our Logo" align="right" width="250" height="50"/> <header> <h2>Delivery note for <br/> {!Opportunity.Account.Name}</h2> {!myOppName} {!myOpp} </header> <p>Details</p> <table width="100%" class="table-noborder"> <tr> <td class="td-noborder">Delivery Note No: {!Opportunity.Opportunity_External_ID__c}</td> <td class="td-noborder" width="15%" align="left"> Install Date: <apex:outputField value="{!Opportunity.Install_Date__c}"/> </td> </tr> <tr> <td class="td-noborder">Project Manager: {!Opportunity.Project_Manager__c}</td> <td class="td-noborder" width="15%" align="left"></td> </tr> <tr> <td class="td-noborder">Address:<br/>{!Opportunity.Account.BillingStreet}<br/>{!Opportunity.Account.BillingCity}<br/>{!Opportunity.Account.BillingState}<br/>{!Opportunity.Account.BillingPostalCode}</td> <td class="td-noborder"></td> </tr> </table> <p>Products</p> <table width="100%" class="table-bordered"> <thead> <tr> <th>Product</th><th>Quantity</th> </tr> <apex:repeat var="oli" value="{!MyOLIs}" > <tr> <td align="left">{!oli.Name}</td> <td align="left">{!FLOOR(oli.Quantity)}</td> </tr> </apex:repeat> </thead> </table> <br/> <table width="100%" class="table-noborder"> <tr> <td class="td-noborder">Placeholder text </td> </tr> </table> <br/> <p>Received by</p> <p> <i>Signature__________________________________________________</i><br/> <br/> <i>Print name_________________________________________________</i> </p> <p> Date______________________________________________________ </p> </body> </apex:page>
Many thanks for any assistance
- louisa barrett 7
- February 04, 2019
- Like
- 0
Event being handled even when tab is not open
I have a custom tab that displays a lighning component which on a click event allows a user to edit a record.
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
Many thanks,
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
<aura:handler event="force:showToast" action="{!c.handleToastEvent}"/> handleToastEvent: function(component, event, helper){ var toastMessageParams = event.getParams(); var message = toastMessageParams.message; if(message.includes('Resource Placeholder') && message.includes('was saved')){ var calendar = component.get('v._Calendar'); var calendarEvent = event.getParam("calendarEvent") helper.fetchCalendarEvents(component, calendar, calendarEvent); } }
Many thanks,
- louisa barrett 7
- August 10, 2020
- Like
- 1
Call future method from trigger handler class method
Hi,
This is my first time using the @future annotation and was wondering if I could get some guidance.
I have a trigger on the contact, which is handled by a handler class. When a contact is deleted, I need to perfom a call out, so within the handler class I need to call a future method to perform that call out. As a future method only takes primitive data types, I have created another method which passes just the IDs to the future method. Is this the correct way to do this, or is there a better way?
I'm also a little concerned what happens if a mass delete is performed. How do you bulkify call outs?
Trigger:
Trigger handler class:
Many thanks
This is my first time using the @future annotation and was wondering if I could get some guidance.
I have a trigger on the contact, which is handled by a handler class. When a contact is deleted, I need to perfom a call out, so within the handler class I need to call a future method to perform that call out. As a future method only takes primitive data types, I have created another method which passes just the IDs to the future method. Is this the correct way to do this, or is there a better way?
I'm also a little concerned what happens if a mass delete is performed. How do you bulkify call outs?
Trigger:
trigger ContactTrigger on Contact (before delete, before insert, before update, after delete, after insert, after update) { ContactTriggerHandler handler = new ContactTriggerHandler(Trigger.isExecuting, Trigger.size); if (Trigger.isInsert && Trigger.isBefore) { handler.OnBeforeInsert(Trigger.new); } else if (Trigger.isInsert && Trigger.isAfter) { handler.OnAfterInsert(Trigger.new, Trigger.newMap); } else if (Trigger.isUpdate && Trigger.isBefore) { handler.OnBeforeUpdate(Trigger.old, Trigger.oldmap, Trigger.new, Trigger.newmap); } else if (Trigger.isUpdate && Trigger.isAfter) { handler.OnAfterUpdate(Trigger.old, Trigger.oldmap, Trigger.new, Trigger.newmap); } else if(Trigger.isDelete && Trigger.isBefore) { handler.onBeforeDelete(trigger.old, trigger.oldMap); } else if(Trigger.isDelete && Trigger.isAfter) { handler.onAfterDelete(trigger.old, trigger.oldMap); } }
Trigger handler class:
public class ContactTriggerHandler extends BaseTriggerHandler { public ContactTriggerHandler(boolean isExecuting, integer size) { super(isExecuting, size); } public void OnBeforeInsert(Contact[] newContacts) {} public void OnAfterInsert(Contact[] newContacts, Map<ID, Contact> newContactsMap) {} public void OnBeforeUpdate(Contact[] oldContacts, Map<ID, Contact> oldContactsMap, Contact[] updatedContacts, Map<ID, Contact> updatedContactsMap) {} public void OnAfterUpdate(Contact[] oldContacts, Map<ID, Contact> oldContactsMap, Contact[] updatedContacts, Map<ID, Contact> updatedContactsMap) {} public void OnBeforeDelete(Contact[] oldContacts, Map<ID, Contact> oldContactsMap) {} public void OnAfterDelete(Contact[] oldContacts, Map<ID, Contact> oldContactsMap) { passIDsToCallOut(oldContactsMap); } Private void passIDsToCallOut(Map<ID, Contact> contactsMap) { Set<Id> conIds = contactsMap.keySet(); system.debug('con Ids for forget request'); system.debug(conIds); sendForgetRequestGDPR(conIds); } @future(callout=true) Public static void sendForgetRequestGDPR(Set<id> contactIds) { Http http = new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint('https://****.com/api/auth/v1/login?email=myemail@email.co.uk&password=myPassword'); request.setMethod('POST'); request.setHeader('Content-Type', 'application/x-www-form-urlencoded'); request.setHeader('Accept', 'application/json'); HttpResponse authResponse = http.send(request); if (authResponse.getStatusCode() == 200) { system.debug('got auth!'); // Deserialize the JSON string into collections of primitive data types. Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(authResponse.getBody()); List<Object> myresults = new List<Object>(); for(Object obj : results.values()) { myresults.add(obj); } string sessionId = string.ValueOf(myresults[0]); system.debug('session Id = ' +sessionId); request = new HttpRequest(); request.setEndpoint('https://*****.com/api/v1/services/*****/gdpr/forget'); request.setMethod('POST'); request.setHeader('Content-Type','application/x-www-form-urlencoded'); request.setHeader('Accept','application/json'); request.setHeader('X-SESSION-ID',sessionId); string comment = 'API Call'; string contactId; for(Id conId : contactIds) { contactId = conId; request.setBody('record_id='+contactId+'&table_name=Contact&comment=' + EncodingUtil.urlEncode(comment, 'UTF-8')); system.debug(request); HttpResponse forgetResponse = http.send(request); if(forgetResponse.getStatusCode() == 200) { system.debug('got GDPR!'); } else { system.debug('Forget Broken =' + forgetResponse.getStatusCode()); } } } else { system.debug('Auth Broken =' + authResponse.getStatusCode()); } } }
Many thanks
- louisa barrett 7
- July 22, 2021
- Like
- 0
Lightning:InputField to automatically adjust height based on content
Hi All,
I have a recordEditForm on an Aura component which displays the core fields from the case object.
My issue is I need the standard description field to automatically expand it's height to show all the content, like it does on the detail page.
Currently I get scoll bars and the ability to drag the box to expose the text.
Is it possible with a lightning:inputfield?
I have a recordEditForm on an Aura component which displays the core fields from the case object.
My issue is I need the standard description field to automatically expand it's height to show all the content, like it does on the detail page.
Currently I get scoll bars and the ability to drag the box to expose the text.
Is it possible with a lightning:inputfield?
<div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-1"> <lightning:inputField fieldName="Description" onchange="{!c.enableButtons}"/> </div> </div>
- louisa barrett 7
- June 11, 2021
- Like
- 0
Is there a way to configure Chatter sub tabs
Hi All,
Currently I see the following sub tabs in Chatter feed.
'All Updates', 'Emails','Call Logs', 'Text Posts', 'Status Change'
Is there a way to supress some of the tabs .e.g supress 'Call Logs' tab ?
Regards,
Avinash
Currently I see the following sub tabs in Chatter feed.
'All Updates', 'Emails','Call Logs', 'Text Posts', 'Status Change'
Is there a way to supress some of the tabs .e.g supress 'Call Logs' tab ?
Regards,
Avinash
- Avinash Kumar 90
- April 29, 2021
- Like
- 0
Aura datatable to show error messages on inline edit
Hi All,
I am fairly new to lightning components and am struggling to get a datatbale to show any server side errors. I have looked at the documentation (Salesforce Documention (https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/example#lightningcomponentdemo:exampleDatatableInlineEdit) )and tried to implement it to my scenario but cannot get it to work.
This is my code:
Component:
Controller:
Apex Controller:
(I'm not doing any validation in this method at the moment, but I will)
Any help would be much appreciated,
Thank you
I am fairly new to lightning components and am struggling to get a datatbale to show any server side errors. I have looked at the documentation (Salesforce Documention (https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable/example#lightningcomponentdemo:exampleDatatableInlineEdit) )and tried to implement it to my scenario but cannot get it to work.
This is my code:
Component:
<aura:component controller="BuildUpChecklistController" implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId"> <aura:handler name="init" action="{!c.doInit}" value="{!this}"/> <aura:handler event="force:refreshView" action="{!c.doInit}"/> <aura:attribute name="mydata" type="Object"/> <aura:attribute name="mycolumns" type="List"/> <aura:attribute name="errors" type="Object" default="[]"/> <aura:attribute name="draftValues" type="Object" default="[]"/> <aura:attribute name="listSize" type="Integer" default="0"/> <!--User List Table--> <div class="slds-m-top--none slds-box slds-theme_default" > <div class="slds-align_absolute--left"> <div class="slds-text-heading_small slds-text-color_default"> Update build notes and on site fields <lightning:helptext content="Help!"/> </div> </div> <lightning:datatable data="{! v.mydata }" columns="{! v.mycolumns }" showRowNumberColumn= "true" wrapTextMaxLines="3" keyField="Id" errors="{!v.errors}" draftValues="{!v.draftValues}" onsave="{!c.handleSaveEdition}"/> </div> </aura:component>
Controller:
handleSaveEdition: function (component, event, helper) { var draftValues = event.getParam('draftValues'); var action = component.get("c.updateOLIs"); action.setParams({"OLIs" : draftValues}); action.setCallback(this, function(result){ var state = result.getState(); if(state === "SUCCESS"){ component.set("v.errors", []); component.set("v.draftValues", []); var toastEvent = $A.get("e.force:showToast"); toastEvent.setParams({ "title": "Success", "message": "The opportunity line items have been updated", "type" : "success" }); toastEvent.fire(); $A.get('e.force:refreshView').fire(); //} } else if(state === "ERROR"){ //I don't know what to use here to display any server side errors //on the relevant rows of the datatable // } else if (status === "INCOMPLETE"){ var toastEvent = $A.get("e.force:showToast"); toastEvent.setParams({ "title": "Error!", "message": "'No response from server or client'", "type" : "error" }); toastEvent.fire(); $A.get('e.force:refreshView').fire(); } }); $A.enqueueAction(action); },
Apex Controller:
(I'm not doing any validation in this method at the moment, but I will)
@AuraEnabled public static void updateOLIs(List<OpportunityLineItem> OLIs) { update OLIs; }
Any help would be much appreciated,
Thank you
- louisa barrett 7
- March 19, 2021
- Like
- 0
Event being handled even when tab is not open
I have a custom tab that displays a lighning component which on a click event allows a user to edit a record.
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
Many thanks,
I am trying to listen for a save success on the e.force:editRecord and after much searching I found no solution as apparently there is no standard callback for the editRecord
https://trailblazer.salesforce.com/ideaView?id=0873A000000CQQiQAO
As per a few other suggestions I have added an handler for the force:showToast
This is working, albeit a hack, but the problem is as this is an application event it is constantly being listened for even if the custom tab isn't open.
Does anyone have any ideas how I can remedy this
<aura:handler event="force:showToast" action="{!c.handleToastEvent}"/> handleToastEvent: function(component, event, helper){ var toastMessageParams = event.getParams(); var message = toastMessageParams.message; if(message.includes('Resource Placeholder') && message.includes('was saved')){ var calendar = component.get('v._Calendar'); var calendarEvent = event.getParam("calendarEvent") helper.fetchCalendarEvents(component, calendar, calendarEvent); } }
Many thanks,
- louisa barrett 7
- August 10, 2020
- Like
- 1
Test for Apex trigger on Order object not covering code (coverage 0%)
Hello,
I have created a trigger on the Order object that works fine. But I am not able to get any coverage of my trigger with my test class.
Even though I wrote a test class; the coverage of my trigger remains at 0%
Could someone tell me what am I doing wrong?
Thanks
Trigger:
Test class:
I have created a trigger on the Order object that works fine. But I am not able to get any coverage of my trigger with my test class.
Even though I wrote a test class; the coverage of my trigger remains at 0%
Could someone tell me what am I doing wrong?
Thanks
Trigger:
trigger UpdateAccountCA on Order (after update) { Map<Id, Decimal> mAccAmount = new Map<Id, Decimal>(); //Iterate through each Order for(Order o : Trigger.new) { if(mAccAmount.containskey(o.accountid)) { Decimal d = mAccAmount.get( o.AccountId ); System.debug('Decimal value ' +d); d += o.TotalAmount; mAccAmount.put( o.AccountId, d ); } else { mAccAmount.put( o.AccountId, o.TotalAmount ); } } List<Account> lAccs = [SELECT Id, Chiffre_d_affaire__c FROM Account WHERE Id = :mAccAmount.keySet()]; System.debug('Account Keyset: ' +mAccAmount.keySet()); //Iterate through each List of Accounts if(lAccs.size()>0) { for(Account acc : lAccs){ acc.Chiffre_d_affaire__c = acc.Chiffre_d_affaire__c + mAccAmount.get(acc.Id); } } update lAccs; }
Test class:
@isTest public class UpdateAccountCATest { @isTest static void test() { Account acc1 = new Account(Name = 'Test Account 1'); insert acc1; Id pricebookId = Test.getStandardPricebookId(); Product2 pd1 = new Product2(Name = 'Chemise Verte longue XYX', Family = 'Chemise'); Insert pd1; //Create the PricebookEntry PricebookEntry standardPrice = new PricebookEntry(); standardPrice.Pricebook2Id = pricebookId; standardPrice.Product2Id = pd1.Id; standardPrice.UnitPrice = 1020; standardPrice.IsActive = true; standardPrice.UseStandardPrice = false; Insert standardPrice; Order o1 = new Order(AccountId = acc1.Id, EffectiveDate=date.today(), Status='Draft', Pricebook2Id = pricebookId); insert o1; OrderItem oi1 = new OrderItem (OrderId = o1.Id, PricebookEntryId = standardPrice.Id, Quantity=10, UnitPrice = 150); insert oi1; OrderItem oi2 = new OrderItem (OrderId = o1.Id, PricebookEntryId = standardPrice.Id, Quantity=20, UnitPrice = 1000); insert oi2; } }
- Hermann Ouré
- August 10, 2020
- Like
- 0
SLDS Table with horizontal and vertical scroll and fixed headers
Hi,
I have a table with horizontal and vertical scroll bars and would like to lock the column headers when scrolling in either direction.
At the moment it's scrolling ok, and when you scroll vertically the headers are fixed, but the column headers do not move when scrolling horizontally. I'm guessing it's because of the slds-cell-fixed, but I'm not sure what to change it to.
Any help would be much appreciated
I have a table with horizontal and vertical scroll bars and would like to lock the column headers when scrolling in either direction.
<lightning:layoutItem size="12" padding="around-small"><b>Work Orders</b> <div class="external-events slds-table--header-fixed_container" style="height:20rem;"> <div class=" slds-scrollable " style="height:100%;"> <table class="slds-table slds-table_bordered slds-table_cell-buffer slds-table--header-fixed"> <thead> <tr> <th scope="col"> <div class="slds-cell-fixed">WO#</div> </th> <th scope="col"> <div class="slds-cell-fixed">Account</div> </th> <th scope="col"> <div class="slds-cell-fixed">Postcode</div> </th> <th scope="col"> <div class="slds-cell-fixed">Status</div> </th> <th scope="col"> <div class="slds-cell-fixed" >Subject</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.woList}" var="item"> <tr> <td> <div class="{!'fc-event ' + item.className}" data-id="{!item.id}" data-tag="{!item.tag}" onclick="{!c.handleClick}">{!item.WorkOrderNumber} </div> </td> <td> <div>{!item.accountName}</div> </td> <td> <div>{!item.postcode}</div> </td> <td> <div>{!item.Status}</div> </td> <td> <div>{!item.Subject}</div> </td> </tr> </aura:iteration> </tbody> </table> </div> </div> </lightning:layoutItem
At the moment it's scrolling ok, and when you scroll vertically the headers are fixed, but the column headers do not move when scrolling horizontally. I'm guessing it's because of the slds-cell-fixed, but I'm not sure what to change it to.
Any help would be much appreciated
- louisa barrett 7
- May 20, 2020
- Like
- 0
Lightning Console close workspace and sub tabs
Does anyone know how to close a workspace(primary) tab and it's sub tabs?
The below only returns the subtab. I need to close the primary and any subtabs.
The below only returns the subtab. I need to close the primary and any subtabs.
var workspaceAPI = component.find("workspace"); workspaceAPI.getEnclosingTabId().then(function(tabId) { var enclosingTabId = tabId; workspaceAPI.closeTab({tabId: enclosingTabId}); })Many thanks
- louisa barrett 7
- November 14, 2019
- Like
- 0
Apex Cpu Time Limit Error after Summer 19 release
I wanted to check if this is a known issue. On saturday our instance was upgraded to Summer 19, and on monday we started seeing Apex CPU time Limit Exceeded error on one of our objects.
Could someone let me know if they are aware of the issue.
Thanks
Ravi
Could someone let me know if they are aware of the issue.
Thanks
Ravi
- RK Bheemreddy
- June 19, 2019
- Like
- 0
Controlling picklist on VF page with read only FLS
Hi,
I have a vf page which has several page block tables on all with inline edit support enabled. Within the tables there are controlling(Product_Category__c) and dependent(Make__c) picklists. My issue is that the the controlling picklist has a FLS of read only as it is set via a trigger, when I put this field onto the vf page, I get the error of 'The inline edit-enabled dependent picklist 'Make' requires its controlling field 'Product Category' to be present on the page.' when a profile other than system admin views the page. If I remove the read only flags from the FLS and set it at a page layout level, the user can then view the vf page, but the controlling field becomes editable.
Does anyone have any suggestions how I can get around this?
This is my vf page. I have several pageblocktables within the page, but I've removed all but one for ease of reading.
Many thanks for any help
I have a vf page which has several page block tables on all with inline edit support enabled. Within the tables there are controlling(Product_Category__c) and dependent(Make__c) picklists. My issue is that the the controlling picklist has a FLS of read only as it is set via a trigger, when I put this field onto the vf page, I get the error of 'The inline edit-enabled dependent picklist 'Make' requires its controlling field 'Product Category' to be present on the page.' when a profile other than system admin views the page. If I remove the read only flags from the FLS and set it at a page layout level, the user can then view the vf page, but the controlling field becomes editable.
Does anyone have any suggestions how I can get around this?
This is my vf page. I have several pageblocktables within the page, but I've removed all but one for ease of reading.
Many thanks for any help
<apex:page standardController="Account" extensions="SiteSurvey"> <apex:form > <apex:pageBlock id="Block1" title="Active assets for {!Account.Name}" > <apex:panelGrid columns="2"> <apex:commandButton value="View as PDF" action="{!printAsPDF}"/> <apex:commandButton value="View as xls" action="{!printAsXLS}"/> </apex:panelGrid> <apex:pageBlockButtons > <apex:commandbutton value="Save" action="{!updateAssets}" id="saveButton" style="display:none"/> <apex:commandButton value="Cancel" action="{!cancelAssets}" id="cancelButton" style="display:none"/> </apex:pageBlockButtons> <apex:pageBlockSection id="tsSection" collapsible="true" title="Touchscreens [{!TouchscreenAssets.size}]" columns="1" rendered="{!TouchscreenAssets.size >0}" > <apex:pageBlockTable value="{!TouchscreenAssets}" var="a" style="table-layout:fixed"> <apex:column headerValue="Asset Name:"> <apex:outputLink value="/{!a.ID}" target="_blank"> {!a.Name} </apex:outputLink> </apex:column> <apex:column headerValue="Contract Status"> <apex:outputField value="{!a.Service_Contract_Status__c}"/> </apex:column> <apex:column headerValue="Category"> <apex:outputField value="{!a.Product_Category__c}" /> </apex:column> <apex:column headerValue="Make" > <apex:outputField value="{!a.Make__c}"/> </apex:column> <apex:column headerValue="Model" > <apex:outputField value="{!a.Model__c}"/> </apex:column> <apex:column headerValue="OS" > <apex:outputField value="{!a.Operating_System__c}"/> </apex:column> <apex:column headerValue="Location #" > <apex:outputField value="{!a.Location_Number__c}"/> </apex:column> <apex:column headerValue="IP" > <apex:outputField value="{!a.IP_Address__c}"/> </apex:column> <apex:column headerValue="User Name" > <apex:outputField value="{!a.User_Name__c}"/> </apex:column> <apex:column headerValue="Password" > <apex:outputField value="{!a.Password__c}"/> </apex:column> <apex:column headerValue="Drawer" > <apex:outputField value="{!a.Drawer_Type__c}"/> </apex:column> <apex:column headerValue="Network" > <apex:outputField value="{!a.Network_Communication__c}"/> </apex:column> <apex:column headerValue="Comms" > <apex:outputField value="{!a.Communication_Method__c}"/> </apex:column> <apex:column headerValue="Prox" > <apex:outputField value="{!a.Prox_Type__c}"/> </apex:column> <apex:column headerValue="Desc" > <apex:outputField value="{!a.Description}" style="white-space:normal"/> </apex:column> <apex:inlineEditSupport event="onClick" showOnEdit="saveButton, cancelButton"/> </apex:pageBlockTable> </apex:pageBlockSection> <script> twistSection(document.getElementById('{!$Component.Block1.tsSection}').getElementsByTagName('img')[0]) </script> </apex:pageBlock> </apex:form> </apex:page>
- louisa barrett 7
- January 02, 2019
- Like
- 0
SOQL to return user id and list of custom object
Hi,
I would like to return a user ID and a list of custom objects that the user is the owner of using an inner select, but I don't know where to find the child relationship name for the custom object.
example:
List<User> owners = [SELECT ID, Name,
(SELECT ID, Name, OwnerID, Month_Number__c
FROM Custom_Object__c)
FROM User
WHERE OwnerID IN : ownerIDs];
I basically want to end up with a map of <ID, List<Custom_Object__c>>(), where the ID is the user ID and the list is all the custom object records that the user is the owner of.
Normally I would just look on the object and get the child relationship name from there, but the user object does not show it's related objects.
Is this query possible from the user table?
Thanks
I would like to return a user ID and a list of custom objects that the user is the owner of using an inner select, but I don't know where to find the child relationship name for the custom object.
example:
List<User> owners = [SELECT ID, Name,
(SELECT ID, Name, OwnerID, Month_Number__c
FROM Custom_Object__c)
FROM User
WHERE OwnerID IN : ownerIDs];
I basically want to end up with a map of <ID, List<Custom_Object__c>>(), where the ID is the user ID and the list is all the custom object records that the user is the owner of.
Normally I would just look on the object and get the child relationship name from there, but the user object does not show it's related objects.
Is this query possible from the user table?
Thanks
- louisa barrett 7
- December 12, 2018
- Like
- 0
Visualforce select all option with inline editing
Hi,
I would like to add a select all option to a column(On_Site__c) that is bound to an outputfield on my VF page which is currently using inline editing
This is the page code:
<apex:page standardController="Build_Up_Checklist__c" extensions="BuildUpChecklist" showHeader="false" sidebar="false">
<style type="text/css">
.pbTitle {
white-space: nowrap;
}
</style>
<table width="98%" border="0" cellpadding="0" cellspacing="0">
<tr><td align ="right"><a href="javascript:window.print();">Print</a></td></tr>
</table>
<apex:form>
<apex:pageBlock title="Product list for: {!Build_Up_Checklist__c.Build_Up_Checklist_Opportunity__r.Name} - ({!Build_Up_Checklist__c.Opportunity_EDU__c})">
<apex:outputPanel >
<apex:commandbutton value="Save" action="{!updateOLIs}" id="saveButton" style="display:none"/>
<apex:commandButton value="Cancel" action="{!cancelUpdateOLIs}" id="cancelButton" style="display:none"/>
</apex:outputPanel>
<apex:pageblocktable value="{!OppProducts}" var="oli">
<apex:column value="{!oli.PriceBookEntry.Name}" />
<apex:column value="{!oli.Product_Notes__c}" />
<apex:column value="{!oli.Quantity}"/>
<apex:column headerValue="On Site">
<apex:outputField value="{!oli.On_Site__c}">
<apex:inlineEditSupport showOnEdit="saveButton, cancelButton" event="ondblclick" />
</apex:outputField>
</apex:column>
<apex:column value="{!oli.Replacement__c}"/>
</apex:pageblocktable>
</apex:pageBlock>
</apex:form>
</apex:page>
The editing and saving is working as intended, but it would be nice if the user didn't have to check the 'On_Site__c' checkbox on each row.
Many thanks
I would like to add a select all option to a column(On_Site__c) that is bound to an outputfield on my VF page which is currently using inline editing
This is the page code:
<apex:page standardController="Build_Up_Checklist__c" extensions="BuildUpChecklist" showHeader="false" sidebar="false">
<style type="text/css">
.pbTitle {
white-space: nowrap;
}
</style>
<table width="98%" border="0" cellpadding="0" cellspacing="0">
<tr><td align ="right"><a href="javascript:window.print();">Print</a></td></tr>
</table>
<apex:form>
<apex:pageBlock title="Product list for: {!Build_Up_Checklist__c.Build_Up_Checklist_Opportunity__r.Name} - ({!Build_Up_Checklist__c.Opportunity_EDU__c})">
<apex:outputPanel >
<apex:commandbutton value="Save" action="{!updateOLIs}" id="saveButton" style="display:none"/>
<apex:commandButton value="Cancel" action="{!cancelUpdateOLIs}" id="cancelButton" style="display:none"/>
</apex:outputPanel>
<apex:pageblocktable value="{!OppProducts}" var="oli">
<apex:column value="{!oli.PriceBookEntry.Name}" />
<apex:column value="{!oli.Product_Notes__c}" />
<apex:column value="{!oli.Quantity}"/>
<apex:column headerValue="On Site">
<apex:outputField value="{!oli.On_Site__c}">
<apex:inlineEditSupport showOnEdit="saveButton, cancelButton" event="ondblclick" />
</apex:outputField>
</apex:column>
<apex:column value="{!oli.Replacement__c}"/>
</apex:pageblocktable>
</apex:pageBlock>
</apex:form>
</apex:page>
The editing and saving is working as intended, but it would be nice if the user didn't have to check the 'On_Site__c' checkbox on each row.
Many thanks
- louisa barrett 7
- September 16, 2018
- Like
- 0
Flow finishLocation behaviour in Salesforce1/Lightning
Hello all,
I try to call a flow via a visualforce page. The flow is started from an Account (button and action), submitting the AccountID and simply creates a new object linked to this Accout.
My goal is to go back to the Account page after the flow completed. It works in Salesforce classic, but not in Lighning and SF1. As soon as I click finish here, I am not redirected to the Account page, but the page just freezes. Only possibility is to click cancel then.
Any suggestions from you?
Stefan
This is how my code looks like:
<apex:page standardController="Account">
<apex:variable var="getAccountId" value="{!Account.Id}"></apex:variable>
<flow:interview name="Assessment" finishLocation="{!URLFOR('/'+getAccountId)}">
<apex:param name="AccountID" value="{!Account.Id}"/>
</flow:interview>
</apex:page>
I try to call a flow via a visualforce page. The flow is started from an Account (button and action), submitting the AccountID and simply creates a new object linked to this Accout.
My goal is to go back to the Account page after the flow completed. It works in Salesforce classic, but not in Lighning and SF1. As soon as I click finish here, I am not redirected to the Account page, but the page just freezes. Only possibility is to click cancel then.
Any suggestions from you?
Stefan
This is how my code looks like:
<apex:page standardController="Account">
<apex:variable var="getAccountId" value="{!Account.Id}"></apex:variable>
<flow:interview name="Assessment" finishLocation="{!URLFOR('/'+getAccountId)}">
<apex:param name="AccountID" value="{!Account.Id}"/>
</flow:interview>
</apex:page>
- Stefan Fischer
- March 22, 2016
- Like
- 1
Refresh Service Cloud lists when new record is added
I need to have lists refresh when a new record is added. I would think that the Choose How Lists Refresh option and Push Notifications handle this, but that does not seem to work. Please help!
- Patrick Mayer 4
- November 07, 2014
- Like
- 0