You need to sign in to do that
Don't have an account?
Denise Crosby
lightning component to create and save event
Hello Salesforce experts,
I am creating my first lightning component to get a list of contacts from an account, display input fields for an event subject and description and then create/save that event back to Salesforce. I am stuck on the creation of the event. I may be missing something very basic. Was wondering if anyone could point me in the right direction.
ContactListController.aspx
NewMeetingController.js
NewMeetingHelper.js
I tried doing something like this in my helper Javascript, but couldn't get it working:
I am creating my first lightning component to get a list of contacts from an account, display input fields for an event subject and description and then create/save that event back to Salesforce. I am stuck on the creation of the event. I may be missing something very basic. Was wondering if anyone could point me in the right direction.
ContactListController.aspx
public with sharing class ContactListController { @AuraEnabled public static List<Contact> getContacts(Id recordId) { return [Select Id, FirstName, LastName, Email, Phone, Title From Contact Where AccountId = :recordId]; } }NewMeeting.cmp
<aura:component controller="ContactListController" implements="force:lightningQuickAction,force:hasRecordId" access="global"> <aura:attribute name="recordId" type="Id" /> <aura:attribute name="Account" type="Account" /> <aura:attribute name="Contacts" type="Contact" /> <aura:attribute name="Columns" type="List" /> <!-- <aura:attribute name="EventID" type="String" access="Public" default=""/> <aura:attribute name="newEvent" type="Object" access="Private" /> <aura:attribute name="newEventFields" type="Object" access="Private" /> --> <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> <force:recordData aura:id="accountRecord" recordId="{!v.recordId}" targetFields="{!v.Account}" layoutType="FULL" /> <lightning:card iconName="standard:contact" title="{! 'New Meeting for ' + v.Account.Name}"> <!-- <lightning:input Name="Subject" value="{!v.newEventFields.Subject}" label="Subject" placeholder="Subject" /> --> <lightning:input Name="Subject" value="Subject" label="Subject" placeholder="Subject" /> <br/> <lightning:textarea Name="Desc" value="Notes from your meeting" label="Description" placeholder="Notes from your meeting" /> <br/> <lightning:datatable data="{! v.Contacts }" columns="{! v.Columns }" /> </lightning:card> <div class="slds-text-align_center"> <lightning:button variant="brand" label="Save" onclick="{!c.onSave}" /> </div> </aura:component>
NewMeetingController.js
({ doInit : function(component, event, helper) { helper.onInit(component,event,helper); } })
NewMeetingHelper.js
({ onInit: function(component,event,helper) { component.set("v.Columns",[ {label:"First Name", fieldName:"FirstName", type:"text"}, {label:"Last Name", fieldName:"LastName", type:"text"}, {label:"Title", fieldName:"Title", type:"text"} ]); var action = component.get("c.getContacts"); action.setParams({ recordId: component.get("v.recordId") }); action.setCallback(this, function(data) { component.set("v.Contacts", data.getReturnValue()); }); $A.enqueueAction(action); } })
I tried doing something like this in my helper Javascript, but couldn't get it working:
if (component.get('v.EventID') == '') { component.find("newEvent").getNewRecord( "Event", // sObject type (objectApiName) null, // recordTypeId false, // skip cache? $A.getCallback(function() { var rec = component.get("v.newEvent"); }) )}
The promises are not necessary here (for next time, with complicated callouts for instance).
action.setParams({
evt: myevents[0],
eventRelations: myeventrelations
});
We didn't get feedbacks from other people for improving the current code.
Your code works and seems stable (it is already a victory with Lex components).
Alain
All Answers
Behind the force:recordData and getNewRecord, you have the very new Beta Lightning Data Service
Lightning Data Service is powerful and simple to use. However, it’s not a complete replacement for writing your own data access code. Here are some considerations to keep in mind when using it.
Supported Objects: Lightning Data Service supports custom objects and the following.
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/data_service_considerations.htm
... and Event is not supported by the Data Service (you tried something ... impossible by that way).
We can develop the creation of Event in LEX with the "old" alternative (an apex controller, the one you used for the reading) without the very new Data Service even if Salesforce is very proud of it and promotes that way all the time.
Here is a solution which "works". As I said, there are always many problems with the Lightning components.
A new annoying problem with the toasts and a popup in Lex (among many other, Beta)
Lightning Component force:showToast event displays toast message behind action window in Lightning Experience and Salesforce1
https://success.salesforce.com/issues_view?id=a1p3A000000mCRqQAM&title=lightning-component-force-showtoast-displays-toast-message-behind-action-window-in-lightning-experience-and-salesforce1
Component: new version WithoutHeader. ContactListController: JS controller: onSave is the part that you want.
Still missing:
I hope that will help you.
Alain
component.set("v.simpleNewEvent.WhatId", component.get("v.recordId"));Useless above.
OK, I got it to work. I'm going to make sure I understand everything that you did and may try to create just one event with multiple contacts if multiple contacts are selected... thank you!!!
And thanks for the explanation. LEX has a long way to go...but we are already on LEX and they want mobile development, so I have to learn it!
Thanks again...awesome!
Denise
Let me know for the problems with the current code and I could try to solve these new problems (but not the toast message behind the action window for example, these problems are exhausting and time consuming; is it my code or is it a new issue of Lex?).
It would be interesting if other people express their points of view on the Lex components but I feel lonely here.
You just want to know if the data service was usable here at the beginning. Other people could have a point of view, but in fact, a relatively few number of people are using these Lex components (it is difficult to overcome certain obstacles) and there is again a lot of "false lex" with underlying old VF Pages and just a new charter SLDS.
I tried answering another question here to initiate the basis of the discussion (without success):
https://developer.salesforce.com/forums/ForumsMain?id=9060G000000MOcrQAG
Alain
Thanks for the explanation and code. I see the limitations of LEX. Hopefully some improvements will come soon. I was able to modify your code to save a single event (with eventRelations) for multiple contacts. I still need to do the validations and it's looking good.
Your problem was to create only one event with mutliple attendees. My code adds different event for each contact that was not your need indeed.
Another problem with Lex is that you don't have a real lookup component like in the "point and click" layout (mutli-objects combobox + pills).
So you have created only one "event" (outside the Data Service) and mutliple "eventrelation"(s) for your solution.
The creation of event relations is a better choice (real meeting) than multiple events with one different contact (spam) and was clearly missing in my solution (I missed this obvious part for your need).
It is interesting for the forum if you post your creation of the event relations (and choose your solution as best answer).
You have already tested many options of Lex and built a real solution for this event.
The big problem is the missing of a real lookup component like below (perhaps an open-source on github?) instead of a simple list even this alternative is heavily used and sufficient.
This custom lookup is too basic (not multi contacts possible)
https://developer.salesforce.com/blogs/developer-relations/2015/06/salesforce-lightning-inputlookup-missing-component.html
A real Aura lookup component would be like below: (impossible to do with the current avalaible components).
It is the mix of a mutli-object combobox and pills (that seems very difficult to write even for Salesforce and its army of developers):
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_pill.htm
https://www.lightningdesignsystem.com/components/pills
Alain
NewMeetingLEX.aspx
NewMeetingLEX.cmp
NewMeetingLEXController.js
NewMeetingLEXHelper.js
If you want to impress the javascript experts, just say that you have used the very new "Promises" one day.
I am not sure if these promises could be useful for the code here for our nested $A.enqueueAction(action).
I am going to try to find an example of Promises used for chaining $A.enqueueAction(action).
1) Validate that an Attribute Value is Defined
var isDefined = !$A.util.isUndefined(cmp.get("v.label"));
2) Validate that an Attribute Value is Empty
var isEmpty = $A.util.isEmpty(cmp.get("v.label"));
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_attr_values.htm
3) Default Error Handling
The framework can handle and display errors using the default error component, ui:inputDefaultError. This component is dynamically created when you set the errors using the inputCmp.set("v.errors",[{message:"my error message"}]) syntax. The following example shows how you can handle a validation error and display an error message. Here is the markup.
<ui:inputNumber aura:id="inputCmp"/>
inputCmp.set("v.errors", [{message:"Input not a number: " + value}]);
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_validate_fields.htm
4) Throwing and Handling Errors
throw new Error("You don't have permission to edit this record.");
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_throw_error.htm?search_text=throwing
5) Using JavaScript Promises (advanced technique).
Create a Promise This firstPromise function returns a Promise.
Chaining Promises
When you need to coordinate or chain together multiple callbacks, promises can be useful. The generic pattern is:
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_promises.htm
We need to improve that part.
Advanced technique: Using Javascript Promises to chain asynchronous actions in Salesforce Lightning
$A.enqueueAction(appendAction) tells Lightning to make the server-side call to append() at some later time. Once the framework has a result from the server, it calls the callback function so that you can do something with that result. In this case, updating the message attribute on our component.
This is fine until you need to start chaining calls to the server e.g. we want to append more than one “a” to the string.
You could just extend what we have already, and make another call in the callback:
We’re entering both callback hell and the pyramid of doom. Every further action that we need to chain is going to add another layer to this pyramid, and I haven’t even included error handlers here.
Promises are a way to avoid all of this.
http://nebulaconsulting.co.uk/using-javascript-promises-to-chain-asynchronous-actions-in-salesforce-lightning/
I will improve your posted code for the best result as possible (avoiding the callback hell (pyramid) and better error handling.
The promises are not necessary here (for next time, with complicated callouts for instance).
action.setParams({
evt: myevents[0],
eventRelations: myeventrelations
});
We didn't get feedbacks from other people for improving the current code.
Your code works and seems stable (it is already a victory with Lex components).
Alain
I am glad that I helped you. I am less involved on the forum these days because I am passing the very new Superbadge Lightning Component Framework Specialist (very difficult, I am on the 8th challenge, but even if that works, the robot refused the solution, I am like a locksmith trying all the keys, exhausting). I prefer not to think about the ultimate superbadge (coming soon).
( a good idea of the difficulty is when there are very few people having already it among the "champions": https://trailhead-leaderboard-developer-edition.na35.force.com/ )
Superbadge Lightning Component Framework Specialist is very important because of this ..
http://certification.salesforce.com/platformdeveloperII
I have used some parts of the code posted here so helping you helps me too and I think you could try this Superbadge (very difficult, and takes a long time to gothrough because we don't know all the needed "tricks" ... and the whims of the robot) .
While solving the puzzles of Salesforce, I am experimenting many new techniques at least (needed by the solutions) that could help us in the future.
Have a nice evening.
Alain
The last challenges (3/10) were simpler than the first ones. I won 7,000 points (10 challenges x 500 + 2000 points bonus) with this superbadge that's why they are also very interesting for the goal of the 200,000 points (about 200 badges) for me. The "champions" are over 300 badges.
The most difficult challenge with Salesforce is still here for the 5,000 points (it is really very difficult for getting the best answers) but by chance, I met some people like you who also build complete solutions with the Lex components and who don't forget to select a best answer
Thanks..
Congratulations, I'm glad I could help you. :) I also want to finish those superbadges. I am still on Apex Specialist...