This is the final part to my multi-part series on building a sign-up form using Lightning Components. If you have read the previous two posts in this series please read part 1 and part 2 before proceeding.
We ended part 2 with implementing a saving spinner, UI messaging, and data validity enforcement. Today we will be adding two more items to close off this project.
- Allowing the user to remove forms added to the page.
- Configuring a Salesforce community that allows the sign-up form to be accessed publicly without logging into Salesforce.
Let’s get started!
Adding Capability to Remove Forms
In part 1 we added the ability to have the user added multiple people in the sign up form. If we are going let people add additional forms then we might as well add the ability to remove them as well.
Updates to the PublicFormNewLeadComp Component
To handle request to remove a form we will be registering a new event called “removeLeadFormEvent”.
<aura:component > <aura:attribute name=”count” type=”Decimal” /> <aura:attribute name=”newLead” type=”Lead” default=”{‘sobjectType’:’Lead’}”/> <aura:attribute name=”showAddLeadBtn” type=”Boolean” default=”true”/> <aura:attribute name=”showMsg” type=”Boolean” default=”false”/> <aura:attribute name=”errMsg” type=”String” /><aura:registerEvent name=”addFormEvent” type=”c:addLeadFormEvent”/> <aura:registerEvent name=”removeFormEvent” type=”c:removeLeadFormEvent”/><lightning:card > <aura:set attribute=”title”> New Sign-up ({!v.count}) </aura:set> <lightning:recordEditForm objectApiName=”Lead” aura:id=”leadEdit”> </lightning:recordEditForm> <aura:if isTrue=”{!v.showAddLeadBtn}”> <lightning:button variant=”brand” label=”Add Additional Person” onclick=”{!c.fireAddFormEvent}”/> </lightning:card> </aura:component> |
In addition to the new event registration a lightning button will be added where users can click to remove the latest added form. The button is only displayed if it is not the initial form that is loaded since we want at least one form to be displayed for the sign-up page. The logic is controlled by an aura:if component that only renders the “Remove Person” button when the count attribute is greater than 1.
The button itself executes a new controller function labeled as fireRemoveFormEvent which will handle firing the remove event notifying any components that is listening for the event.
The Event
The remove event consists of two attributes that will store the current count attribute value of the lead form component and the count attribute value of the previously created component. The count values will be used by the PublicMainFormComp component when it detects the event fire.
<aura:event type=”COMPONENT” description=”Notifies listener to remove latest added form”> <aura:attribute name=”currentCnt” type=”Decimal” /> <aura:attribute name=”previousCnt” type=”Decimal” /> </aura:event> |
Updates to the PublicFormNewLeadComp Controller
As mentioned above, the Remove Person lightning button calls the fireRemoveFormEvent controller function. The function gets the count attribute value and the registered remove eventI The parameters are set and the event is fired.
fireRemoveFormEvent : function(component, event, helper){ var currCnt = component.get(‘v.count’); var removeEvt = component.getEvent(‘removeFormEvent’);console.log(‘current count before event fire: ‘ + currCnt);removeEvt.setParams( { ‘currentCnt’ : (currCnt-2), ‘previousCnt’ : –currCnt } ); removeEvt.fire(); }, |
Notice that I am decrementing the current count value by two when setting it as a parameter for the event. You might be asking why I am doing this. Recall in part 1 of this series I am dynamically creating form components and in order to accomplish that I needed to add the v.body attribute to the end of the body of the PublicFormMainComp component. As far as I can tell any components dynamically added to page document will start with an index position of zero (0). I needed to take in consideration of this in order to reference to correct component to be removed when handling the event in the PublicFormMainComp controller. So for instance if the count value is 2, the component’s position index is actually at zero (since the first form component is not dynamically added to to the page document.
Updates to the PublicFormMainComp Component
The only addition to this component is handling the event being fired.
<aura:component controller=”PublicContactFormController”>
………………………………….. |
The controller function handleRemoveLeadEvent will be called when the event occurs.
Updates to the PublicFormMainComp Controller
As mentioned above the event handler will execute the handleRemoveLeadEvent function. The function will retrieve the parameter values from the fired event. The body of the document will also be retrieved from the component. The value of currCnt will be used to remove the latest lead form component from the page document via the body.splice function.
handleRemoveLeadEvent : function(component, event, helper){ console.log(‘handling remove form event’); var currCnt = parseInt(event.getParam(“currentCnt”)); var prevCnt = event.getParam(“previousCnt”); var body = component.get(‘v.body’);console.log(‘current index: ‘ + currCnt); console.log(‘previous count: ‘ + prevCnt);//remove component by current count as index body.splice(currCnt, 1); //push updated body back to component var prevFormCmp = component.find(‘cntFrm’ + prevCnt); if(prevFormCmp){ var personCnt = component.get(‘v.personCnt’); }, |
After removing the component from the body we will push the update back to the component by setting the value of v.body. The previously added component will also be updated so that the “Add Additional Person” button is displayed (since it is now the most current lead form component on the page). The personCnt attribute will also be decremented by 1 in order to keep the correct count of lead form components.
Update Lightning App to be publicly accessible
Making the lightning app publicly accessible requires the user of a Salesforce community and using Lightning Out and Allow Guest Access features. I will set up a community that uses Tab + Visualforce and have the main page load a Visualforce page where I will surfacing the lightning app.
The Community
We will be using a Tab + Visualforce community for this exercise.
From the Admin settings of the community I will set the Community Home to the Visualforce page that will be hosting the Lightning App.
Lightning Out App
I created a separate Lightning App that extends ltng:outApp and ltng:allowGuestAccess. The visualforce page will be referencing this new app. The app consists of a dependency referencing the PublicFormMainComp component.
<aura:application extends=”ltng:outApp” implements=”ltng:allowGuestAccess”> <aura:dependency resource=”c:PublicFormMainComp” /> </aura:application> |
The Visualforce Page
The page will not be using any visualforce components, we will be using a div to indicate where the lightning app and its components should be loaded. In order to use lightning components within a visualforce page we must include the apex:includeLightning tag which will include all resources needed.
<apex:page standardStylesheets=”false” showHeader=”false” sidebar=”false”>
<apex:includeLightning /> <div id=”lightning”> </div> <script type=”text/javascript”> $Lightning.use(“c:PublicFormLtngOutApp”, // name of the Lightning app </script> </apex:page> |
The above javascript code will execute which will load the lightning app by referencing the name of the app, the name of the dependent component, a callback function (which will only print a message to console for this page), and the community url.
The url referenced in the code sample actually does work so feel free to check out the components in action for yourselves (I put measures in place to clear our any lead records created in case anyone wants to use up all the data storage of the dev org 😉 ).
Conclusion
This multi-part series now draws to an end. I hope you enjoyed reading the posts and found it helpful in learning how to build lightning apps. All completed code is already available my Github repo so please feel free to check it out from there as well!