01 Mar 2017

Add Your Own Fields to the Calendar: Using Lightning Modal Boxes in Salesforce

Access more fields in Lightning Experience

One of the features we really like in the Salesforce Lightning Experience are the Modal Boxes provided for creation and editing of records. They provide a consistent and attractive interface for the user, and although they’re not directly customizeable, they honor the record layout field order and resize and scroll accordingly.

For DayBack Calendar, they can provide a seamless way to interact with fields that aren’t available in the standard DayBack popover. This lets you access additional fields without having to leave the calendar and still take advantage of DayBack’s drag and drop editing.

Update, May 2017: DayBack now lets you customize the calendar’s popover by including additional fields

Here’s a preview:

Note: This doesn’t quite work in Safari: Salesforce throws a CSS error as it tries to resize the modal. This is a known issue and something I’m sure they’ll be fixing, but for now you’d need to dismiss that error dialog 3 times before editing your event. (Report that this issue affects you, here.)

Let’s take a look at how we can access these modals by adding a little customization to DayBack. Though we’re showing some code here, this is all stuff you just copy and paste so admins can jump right in and make this mod.

For Developers: Throughout this post we’ll include special notes for developers as there is some cool stuff happening here behind the scenes.

For starters, DayBack lives as a Canvas app on a Visualforce page. We love this approach as we can use the same tab in Visualforce and Lightning with just a few small css changes. Additionally, we can make use of the sforce.one methods via JavaScript from our Visualforce page when we’re in Lightning. These give us some basic Modal Box functionality that we’ll use for this example. In order to do this, we need to use the Canvas platform’s publish/subscribe model to publish an event from DayBack to its containing Visualforce Page. The Visualforce page then needs a corresponding subscription which will trigger the sforce.one method to bring up a Modal Box. We can use a DayBack Custom Action to publish an event to begin this flow, but we also need to add the subscription to the JavaScript Static Resource that’s loaded with the Visualforce page. Fortunately, DayBack provides a method for editing the Static Resource even though it’s part of a Managed Package.

Instructions

Step 1. Adding the Subscription to the Static Resource

To edit the JavaScript Static Resource for DayBack, navigate over to Setup and use the Quick Find to locate and select Static Resources. The one we’re looking for is DayBackJS.

Setup / Static Resources

Click on “DayBackJS” and then click the “View File” link: you’ll see the JavaScript in plain text where we can copy it into your favorite text editor (I like Atom).

DayBackJS.js

Once you have the text copied into an editor, scan down to about line 91 where we have a comment block indicating where to add your subscriptions.  Here, we’ll add two objects to the array for our Canvas events. Note that this event model allows for an event payload (e), so we can publish the necessary data we need for our sforce.one methods from DayBack.

As noted in the comments, we don’t recommend any other changes to this file.

Here’s the text to copy and paste:

We can now save this new JavaScript file and upload it to our organization as a new Static Resource. You can name it anything, but “My_DayBackJS.js” is the default value and makes set-up a little bit quicker. Once you’ve save the file to your desktop, return to the list of static resources and click the “New” button centered above the list. Fill out the form shown below, choose your “My_DayBackJS.js” file and click “Save”:

Alternate DayBack JavaScript Static Resource

Once that’s saved, check that the file size is greater than 0 bytes: if it says zero you had trouble uploading: just delete the resource and try again.n. Once you’ve uploaded the file successfully, you’ll need to tell DayBack to load this version of the JavaScript file and not the stock one DayBack started with. This is done in a simple Custom Setting in the DayBack package.  From All Setup, type Custom Setting into the Quick Find and locate DayBack Alternate Javascript and click “Manage”:

Custom Setting for loading alternate JavaScript

Click the New button below the Custom Setting and enter the name of the new Static Resource you created. It defaults to My_DayBackJS, so if that’s what you used for your Static Resource, you can just press Save:

Finishing the Custom Setting

Step 2. Creating the Custom Action

Now, when DayBack loads, it will load our new JavaScript file and activate our two new subscriptions. We can now set up buttons (Custom Actions) in DayBack that use this JavaScript. Let’s start with a very basic button from the Event object: this button will open up a Modal Box for editing the Event. What’s cool about this is that the Modal Box will show custom fields that aren’t available in DayBack’s Event popover.

For Developers: Here, we’ll create a payload object that contains the Event Id and then publish it to our edit subscription using the Canvas JavaScript SDK which is available in the Custom Action scope. Basically we just call the subscription we set up by name, and include a simple payload object using Data Tokens to get the Id of the current Event.

In DayBack Calendar, click “Administrator Settings” on the calendar’s Settings tab, then select “Salesforce” under Calendar Sources. Select the “Events” source and scroll all the  way down until you see the Custom Actions for Events. Click “Add New custom Action” and give it the name “Edit Event”, pasting the following code in where it says “URl or Function” (note that this is the same code you’ll  use for ANY Salesforce object–not just Events):

Click “Back to Calendar”in the upper left, and click “refresh” in your browser to make sure the new static resource you entered above has been loaded since you may have opened DayBack before uploading that resource. Back on the calendar you’ll see a new “Edit Event” button in the custom action drawer (click the gear in the event’s lower right to reveal the drawer)…

The “Edit Event” custom action showing up as a button

…and clicking on “Edit Event” works very nicely, overlaying the Modal Edit Box on top of DayBack. Notice that it even includes the custom field, “Event URL” we added to our event source:

Editing an Event in a Modal Box: showing the custom field “Event URL”

Clicking “Save” on the modal shown above will commit your edits to Salesforce and who a nice green confirmation in DayBack:

Having clicked “Save”

Step 3. No Callback, but a Workaround

This looks great, however, the sforce.one methods do not provide callbacks. This means that when the user is finished with the Modal Box, we don’t have anyway of notifying DayBack to refresh and reflect these changes. We get a nice Lightning notification that the event is saved (shown above), but we’d need to refresh DayBack manually to see any changes we made.

What we really want is to update DayBack with these changes, particularly if the date had changed, as soon as the Lightning Modal is saved.

For Developers: We can’t poll the DOM to see if the popover has been closed because we’re in a Canvas app, and therefore in a different domain. However, we can recursively poll Salesforce using the REST api via Canvas, every second or so, to see if our Event has been modified. If the LastModifiedDate field has changed, then we know the user pressed the save button in the Lightning Modal and we can refresh DayBack accordingly. Unfortunately, this doesn’t give us a way to detect if the user pressed cancel and our recursive polling will continue to run. To solve this, we have our Custom Action add a mouseover event listener to our DOM. This will fire as soon as the mouse moves after the Lightning Modal is closed, and will remove the listener and direct our recursive polling to stop.

To refresh the calendar after our changes, we’ll use the following Custom Action. You should be able to paste this without modification into your org’s custom action:

Now when we make a date change in our Modal Box, and click save, we get our nice green notification from Lightning, and we almost instantly refresh the calendar to reflect any changes. Since we’re presumably making all the changes we need to in the Lightning Modal Box, closing the DayBack popover here makes sense and flows nicely. Plus, if the date changes, we don’t want to leave the popover open pointing to its old spot.

Step 4. Beyond Buttons: Capturing Event Actions

In addition to using Custom Actions to make buttons that invoke these Modal Boxes, you can also call them from Event Actions.  We can use the exact same JavaScript we used for our Custom Action for an On Event Click Action. By disabling the default action, we can bypass our DayBack popover and go right to the Lightning Modal.  This may be the preferred experience for some users, particularly if they’re using lots of additional fields we can’t map to our DayBack popover. The only limitation here is that we don’t get a delete option as it’s not provided in the Lightning Modal. If deletion is important then using this code as a Custom Action may be the way to go as delete is available in DayBack’s popover.

Here’s what it looks like to use the action code above in an “On Event Click” Event Action:

The Event Action with Default Action Disabled

Step 5. Creating New Records Using Modals

We’ll want to change the JavaScript just a bit when we’re creating events so you’ll use paste in a slightly different script if you want to create new events in the modal as well.

For Developers: The sforce.one object does provide a method for calling a creation Modal Box, and we did add it that as a subscription to our Static Resource if you’d like to experiment with it. What we don’t like about this method is when the user presses Save, they are navigated away from the current tab and brought to the new record on its default detail layout. This is OK, as you can see your new record in context, but I think it defeats the whole purpose of using a Modal box, and in practice isn’t really different than needing to go to the native layout to create the record as that’s where you end up anyway. Instead, for our On Create Event, we’re going to continue to use the Edit Modal Box we have been, and we’ll make two modifications to our JavaScript. First, we’ll need to actually create the event in order to launch it in the Edit Modal Box, we can do this easily at the beginning of our routine via REST/Canvas. We know somethings about the event, like whether it’s all day and when it starts, based on the user click, so we’ll populate those fields on creation so they appear in the Modal. Second, if our cancel detection is triggered, we want to go ahead and use REST/Canvas to delete that event in the background to simulate the cancel behavior of using an actual Creation Modal Box.

This is the JavaScript we came up with for the On Create Event action with these the two additions described above. So use this version for your “On Create Event” action:

Conclusions

Even though we ran into some limitations with the sforce.one methods themselves, like having no callbacks, we’re still able to take advantage of them in DayBack both as both a Custom Action and as Event Actions. Salesforce Lightning users can take full advantage of DayBack’s drag and drop editing and still have access to additional fields that may not be available in the DayBack popover, providing the best of both worlds. Additionally, using the native Modal Box enforces the org’s particular business logic, like required fields, directly in the Lightning context. We hope you san make some nice use of these examples and stay tuned as we’ll continue to look at ways of incorporating these Modal Boxes more efficiently and in more ways for DayBack.

Leave a Comment