Blog

Setting up ‘Last Viewed By’ in Salesforce

12

Every record created in salesforce includes some audit information as standard; such as the Created By and Last Modified By fields which display the username and date/time stamp to indicate who created or updated the record and when it took place. This can be useful when trying to trace modifications to a record, but what if you wanted to know who last Viewed a record? There’s no way to do this in salesforce (as of Winter ’10). It would be great if you could see on a record if anyone has recently viewed it, so I came up with this solution:

1. Decide which object to use
Firstly you’ll need to decide which object you want to setup Last Viewed By on, you can set this up on both standard and custom objects. For the purposes of the demo I’m going to setup the functionality using the Account Object.

2. Create a new custom text field
On the Account object, create a new custom text field called Last Viewed By – I used the maximum characters (255) just in case there are any users with long names.

3. Create your Visualforce page
To create a new page go to Setup > App Setup > Develop > Pages and click New. Call it lastViewed, then use the code below in your page:

<apex:page action="{!updateField}" extensions="lastViewed" showheader="false" sidebar="false" standardcontroller="Account"></apex:page>

Note: The page uses a standard controller with an extension – this is so that we can drag it onto the Account page layout (were it a custom controller it would’nt be available for selection) 4. Create your Apex Class Create an Apex class to populate the Last Viewed By text field when the visual force page is invoked. Go to Setup > App Setup > Develop > Apex Classes and click New. Call it lastViewed and populate it using the code below:

public class lastViewed{

	public Datetime cDT; 
	public String LongDate; 
	public String firstname; 
	public String lastname;    
	public String userid;

	private final Account acct;

	public lastViewed(ApexPages.StandardController stdController) {
		this.acct = (Account)stdController.getRecord();    }

    			public String getLongDate() {        
				cDT = System.now();        //Format the datetime value to your locale        
				LongDate = cDT.format('dd/MM/yyyy HH:mm');    return LongDate;    
			}

    	public void updateField() {
        //Get the user info from the current user        
	firstname = System.Userinfo.getFirstName();        
	lastname = System.Userinfo.getLastName();       
	userid = System.Userinfo.getUserId();

        //Get the account record to be updated        
	Account a = [select Last_Viewed_By__c from account where id = :acct.id limit 1];        

	//Assign values to Last Viewed By field & update the record        
	a.Last_Viewed_By__c = (firstname + ' ' + lastname + ', ' + getLongDate());        
	update a;    
	}

}

5. Edit the page layout
Next drop the Visualforce page onto the Account Page Layout so that when a user views an account record, the Visualforce page is invoked – calling the Apex class and updating the record. Click on Edit Page Layout and then select ‘Visualforce Pages’ from the left hand menu. You will see your page appear for selection, drag it over onto the page – you can put it wherever you like (see below).

Now alter the settings so that the page doesn’t appear so large (it doesn’t contain anything visual and we’d rather the users didn’t know it was there). Click on the spaner in the top right hand side of the visualforce component for the settings menu to appear, then set the height in pixels to 0 and make sure the Show scrollbars and Show label options are deselected.

Now add the Last Viewed By field itself, so that the populated value is visible to the end user. Add the field to the page using the page layout editor as normal.

6. Try it out
The next step is to test it out. The Last Viewed By field will appear blank at first,┬áthis is because the visualforce page has not yet been invoked and therefore hasn’t populated the field. Hit refresh on the record you’re viewing and you will see the field populated with your name and the current date/time.

7. Notes

1) Last Modified By field will get updated along with the Last Viewed By field (as the record is being modified each time)
2) The username is not a hyperlink. This could be resolved using a formula field and some concatenation, update to follow perhaps?
3) Contribute! If there are areas that could be improved please add a comment. I’m aware this may not be the ‘perfect’ solution.
3) Any code provided on this site comes with no support or warranty whatsoever.

  • jeffdonthemic

    This is awesome! I had never thought of doing a "last viewed" but it would come in handy. Great job!

  • frasuy

    Never thought of this use case before but nice solution!

  • M. Smith

    Absolutely Brilliant!

  • Amar Joshi

    its nice stuff but i want to throw some lights on this
    1. you must have to unable VF and Apex class in the user's profiles otherwise it will not work for that user and if the user view that page but VF page and apex class will not enable then ListViewBy field will not update.
    2.now Lets assume u have enabled the VF page and Apex Class now some user have open that page to view the data but he is not editing anything though the Lastmodifiedby field will update coz the VF page will autometicaly run and data will update in LastViewBy Field

    Hope you can get what i want to explain here but inspite of this its awesome idea i will do it for my customer

    Thanks,
    Amar
    Salesforce.com Developer
    ServiceMax,Inc
    Bangalore,India

  • Hannes Ellerbrock

    The idea of a "last viewed" feature is great.

    To work-around the "last edited" problem I would set up a new custom object "Last View" with three fields:
    1. ID [Lookup Account] contains the ID of the related object, could probably also be a String field.
    2. last_view_date [long date] contains the date when 'ID' was last viewed
    3. name [String] holds the name of the person who viewed the object

    And on the account you would have to add a lookup on "last view" which can be hidden.

    When the VF element is opened and calls the action, the controller would try to select a "last view" object for this.account. When it finds one it updates the fields, if there is none yet it inserts it… Maybe an upsert would do the job even easier.

    Not sure if there is any chance to write the controller so it works with any kind of sObject. Would come in handy.

    On the Account you would put a formula field that displays "name" + "last view date" from the related "last view" object. This data can be easily derived via the lookup to to "last view"

    Now, if you have a running org you would have a "last edit" == "last view" for the edit where the account gets a "last view" child, but for all new orgs you wouldn't have that problem.

    Btw.: I've build something similar with leads: A field that displays for how long a lead has not been read by the current owner, e.g. after it has been transferred. This is a very interesting information for us and not yet a standard salesforce feature.

    So far,
    Hannes

    P.S.: Deleted my previous post because I forgot something to add.

  • lodoss118

    This can be done as a formula field or workflow rule with some imagination don't need visualforce to do this, you will just get the current user id, name and current time and hyper link.

  • Rhonda

    Very clever!

  • success with SF

    Good use case.. But i have got a doubt.. So, when you view the detail page of a record the last viewed by would be you isn't it? Whereas it should show who visited before you

  • forcedotcom

    Hi Hannes,

    Apologies for taking so long to get back to you. I like your ideas and had thought along similar lines, although unfortuantely at present it is not possible to create polymorphic relationships in salesforce (many to many) which would allow us to have an object to store record views on any other salesforce object (like task already has). Once SFDC get around to enabling this it may be worth writing something a little more 'slick' – I think it would be nice functionality.

  • forcedotcom

    Hi lodoss118,

    Yes indeed a formula field / workflow combination could also achieve similar results. To be honest I was hoping I would be able to get around the LastModified issue through Apex but sadly salesforce don't allow us to temporarily 'unlock' these audit fields (for info you can request salesforce open them up but they will only do this for a specified length of time).

  • Hannes Ellerbrock

    Hi 'forcedotcom',

    yes, it would be nice to have one custom object which could be used to "last view" information on all objects.

    I've uploaded my solution (which only applies to Accounts) to the AppExchange: https://login.salesforce.com/?startURL=%2Fpackaging%2FinstallPackage.apexp%3Fp0%3D04tA00000005Ww6

    Hope others like it…

    Cheers,
    //Hannes

  • Ash

    Hi

    Anyone got a test class for this?

    Thanks