Changing the way Salesforce Admins and Developers think about client solutions.

Category: Mobile

Geoff.Dreamforce@gmail.com – I’d do it again


*Hint – not a real email address*

This is a quick post to show you guys why I decided to cut yet another completely free Developer Edition of Salesforce for the sole purpose of attending and functioning at Dreamforce this year.

Even though I consider it a strength, my wife would say that I’m slightly compulsive when it comes to planning itineraries, especially around travel.  The more I looked at the Dreamforce15 app the less comfortable I got with relying solely on it for my travels.  Hopefully everyone gets to see a few reasons why getting more than one developer org can be helpful, even for small and short use cases like this

Continue reading

The Wife App Part 2 – Build



In the previous post I talked about how my wife had mentioned that maybe I could build her an app to help her manage our new baby.  When I tell this story in 10 years time I’m sure I’ll be telling it slightly differently and more like this:

My Wife: Take me to bed or lose me forever

Me: I’ll build you an app instead!


Continue reading

Mileage Part 2 – Mobilizing

In the last post I went over how to create a very simple mileage object to automatically log mileage on my car each day I have to drive it somewhere.

To Summarize:

  • It’s basic, and would need formula adjustments every time I add a new destination
  • There are fail-safes to make sure I don’t screw up when entering data
  • There are not fail-safes if I mess up my formula
  • My goal is to have a way to quickly enter my miles on a daily basis

I went to use this today and I knew that it would take a few clicks in Salesforce1 to get what I wanted.  You take for granted on a desktop just how quickly clicks can be made, but they take that much longer on a phone.

I also forget if I mentioned it, but you can always emulate Salesforce1 by adding “/one/one.app” to the end of your SF URL so that it’s something like na16.salesforce.com/one/one.app


Do enter a mileage record on Salesforce1, even after automating the actual KM calculation:

  1. Open Salesforce1
  2. Open the side menu, scroll to Mileage if it’s even there – you need to have been to that object recently.
  3. Open the Mileage Tab (you may have to click on Show More here as well)
  4. Click the New button
  5. Choose Location from the picklist and confirm other fields are correct
  6. Click Save

So that’s 6 clicks, potentially more, just to enter a mileage.  Hard to do in the time it takes for an elevator to show up or a cross walk light to change.  I don’t like this at all, time to see what can be done.

Steps to better mobilization

What I really need to get rid of a few clicks right off the bat is a Global Publisher Action.  This will allow me to quickly create a mileage record right from the first page I see. I do this through:
Setup > Create > Global Actions > Actions and set the key fields


My Action is to create a mileage record.  Pretty self explanatory.  Saving this takes me to another page where I can determine what fields I want to pre-populate, and a button to change the layout:


Predefined values have in my experience been under-appreciated so far.  I’m not going to use it here because I do bounce around, but if I was working with the same client for a full month, I might set the location to always be a set value.  The key here is that I can always change it, but I’m pre-populating values for the 95% of cases.  This is all about saving clicks.  Think of it like the default value in text fields.  If you noticed in the last post I used this same idea at the field level to default the date.  In this case we are only defaulting on the mobile platform.  Think of it as what are they most likely to be entering while on the road, not necessarily what they are most likely to be entering overall.

The other piece is adjusting the layout for the publisher action.  It’s a similar idea – you don’t want to clog things up with unnecessary fields, so keep it simple.  Mine is basic, and designed for one-handed operation where possible.  Note that in general, everything is in line.  I only move to the other side of the page if I need to enter a custom value


On a routine day where I’ve remembered to do it right after getting out of the car, all I have to enter here is the location.

Once you have your layout and your pre-defined values, you need to add to the global publisher layout.  The default layout is:


In a word – cluttered.  In another word – useless.  Clean this up to only have what you will use.  Remember, you’ll be adding your own over time, you don’t want stuff here that will never be used.  It’s a dev org, who are you really going to Poll or Question?


That’s better, and I’ve now added the new publisher action for a new Mileage record.

Back to clicks again:

  1. Open Salesforce1
  2. Click on Publisher Actions and Create New Mileage.  I consider this basically the same as a picklist in terms of number of actions it’s so easy
  3. Choose Location
  4. Click Save

So by adding a global publisher action and an appropriate layout we’ve managed to reduce our clicks by a third.  Not just clicks, but we’ve really been able to reduce our navigation requirements.  Everything is done right from the Chatter feed.  Saving two clicks doesn’t sound like a lot, but try it and tell me that this isn’t now twice as fast as it was before.  I just checked and even with an internet lag, from the time it took me to open the app to the time it took me to put my phone back in my pocket logging a 200km trip to Waterloo – 10 seconds.

I’m still not happy with the scalability of my object, and we’ll be addressing that in a future blog post with both a more object oriented approach, and some custom code we can use to make it even better


Goal #2 – Tracking Mileage


I’m terrible at mileage – I start every week with the best intentions, and then two months later I’m backtracking through my calendar trying to figure out where I was every day – not ideal.  This is a classic example of something that can be easily tracked in Salesforce, and entered via mobile while you are waiting for an elevator.

We are going to go through this exercise a few times, because I want to show you how to start with something simple to solve a business problem, and then develop it over time into a solution that is much more robust.

I’m using Mileage as my example, but this same thing could hold true for other items like:

  • Tracking your exercise if your routes are standardized
  • Tracking how many donuts you eat a week and subsequent calories if you are into that kind of thing
  • I’ll add any more that people think of and message me about

Step 1: Getting the information in there


Here is my very basic mileage page.

Location: Picklist that is maintained in the background.  5 entries currently exist, no default.

Date: Any date can be chosen, but I’ve set the default to TODAY().

Round Trip?: Default is checked, but I can uncheck if for some reason I only went one way

KMs: Formula field based on the picklist that populates a value

“Waterloo”, 200,
“Stoney Creek”, 100,
“Brampton”, 60,
“Downtown Office”, 40,
“Burlington”, 100,

Custom Mileage: Just in case I’m not going to one of the places in the picklist

Custom Mileage Details: The taxman will still want to know where I went, best to enter it here

System Information Fields: All you really need to know here is that I made the Name an Auto-number because I don’t care about it outside of having a unique record identifier.


Assuming I do everything right, and don’t mess things up, the KMs for Trip will calculate perfectly every time based on the following formula:

ISPICKVAL(Location__c, “”),
Custom_Mileage__c ,
Round_Trip__c = TRUE,
KMs__c ,
KMs__c / 2
/*If no location has been set, use the custom mileage, otherwise use the mileage from the location field assuming it was a round trip. If it was one way, divide by 2 – does not apply to custom mileage*/

Note that you can put comments in formulas in Salesforce.  Very useful for the more complicated ones that could take you awhile to unwind if you had to come back to them.  In this case it’s pretty simple.

Now this all assumes that I don’t screw up.  If I enter anything in custom mileage, the location is completely ignored.  So what I needed was a few failsafes for when I’m not paying attention.

Failsafe 1: If a custom mileage, say where I went

This is for the taxman, they will want to know.  Simple validation rule

NOT(ISBLANK( Custom_Mileage__c ))
ISBLANK( Custom_Mileage_Notes__c )


Failsafe 2: Cannot have both a location listed, and a custom mileage

NOT(ISPICKVAL( Location__c , “”)),

Custom Mile22


So those will help keep me in line and make sure I don’t screw up.

Note that I could have combined these into a single validation rule but that would have stuck me with only a single error message.  If the reasons for failure cannot be explained with the same message, the better practice is to split the validation rules so that you can clearly articulate to the end user why you are failing what they are trying to do.


Without having to make a single change for mobile, here’s how I would be entering the exact same thing on my phone:


All the same fields are there.  If I found that from my phone I was only ever entering “Standard” locations because I would have to go back and check mileage for Custom locations, I can adjust that through publisher actions and we’ll address that use case in another post.


So I’m calling this iteration 1.  It works, I can use it, but it has limitations.  There is nothing fancy, just a few formulas, and a few checks and balances.

1. Scaleability – what if I have lots of sites to go to?  I don’t want to keep adjusting picklist values AND the corresponding formula.  It could get unwieldy very quickly.

2. Over time I may stop going to places but since the field is a formula I have to be very careful about removing values.  I don’t have a great audit trail.

3. I haven’t figured out how to report on it yet.

Over the next few posts we’ll look at different ways to improve this, discuss the pros and cons of different solutions, and hopefully end up on something that can be considered both optimal for us, and worthy of providing as a business solution.

© 2018 ExploitedDevOrgs

Theme by Anders NorenUp ↑