Display the File Last Updated Date Using jQuery in SharePoint

In this example, assume there is a dashboard page on a SharePoint site that displays a number of graphs and charts. This dashboard is based on data contained in a single file located in a document library on the same site. Whenever this file is updated, the last modified date of the file needs to be automatically reflected on the dashboard page. This allows the page viewer to know the freshness of the dashboard data without requiring the content owner to edit the dashboard page itself with every data change. The following code will display the file last updated date using jQuery, the SharePoint Client Object Model (sp.js), and a bit of HTML. The formatDate function is used to format the file last modified timestamp in dd-mon-yyyy format.

Add a Content Editor Web Part to the dashboard page and include the following script in the source (or as a reference to a script file).

Change the FileUrl variable in getFileInfo() to the appropriate file path. When the code executes, it will replace the contents of the “data_last_update_date” container with the formatted last modified timestamp.

Source Code

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

<script language='javascript'>
  function getFileInfo() {
    var clientContext = SP.ClientContext.get_current();
    var web = clientContext.get_web();
    var FileUrl = '/path/to/file.txt';
    var file = web.getFileByServerRelativeUrl(FileUrl);


      function() {
        $('#data_last_update_date').html("Data Last Updated: " + formatDate(file.get_timeLastModified()));
      function(sender, args) {
        console.log('Function getFileInfo() failed: ' + args.get_message());

  function formatDate(timestamp) {
    var month_names = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
    var pad = "00";

    if(timestamp) {
      var d = new Date(timestamp);

      return (pad + d.getDate()).slice(-pad.length) + "-" + month_names[d.getMonth()] + "-" + d.getFullYear();

  $(document).ready(function() {
    ExecuteOrDelayUntilScriptLoaded(getFileInfo, "sp.js");

<p> </p>
<div id='data_last_update_date' style='text-align:center; width:100%;'></div>

Microsoft InfoPath Lessons Learned

Microsoft InfoPath is a solid tool for creating customized forms to collect data, especially when integrated with SharePoint. Creating the form is simple through a WYSIWYG editor and a largely drag and drop process. The word “simple” applies only to creating the form. It typically becomes complicated as soon as the form is published (or attempted to be published). The form will start throwing weird errors with incomprehensible messages. If you do manage to publish the form, then it will exhibit strange behaviors or unexpected results.

Although Microsoft announced that InfoPath would be discontinued on January 31, 2014, I’m still using it to create new forms and thought I would share some lessons learned.

A duplicate field name “<field name>” was found

You have just created a fancy new InfoPath form and you attempt to publish it. Everything seems ready to go and then InfoPath displays the following error message:

A duplicate field name “<field name>” was found.

Others have posted workarounds that involve editing list definitions within the .CAB file. I wasn’t able to try these methods with my limited access to the server and effectively no administrative permissions.

In my case, the SharePoint site had a few global site columns defined which were used in a number of different lists. I was able to create and publish InfoPath forms for those other lists without an issue. However, this one particular list kept throwing the duplicate field name error.

The solution that worked in this instance was to create a new list column. I transferred the existing data from the site column to the newly created column. Once the data was copied, I deleted the site column from the list. I was able to leave the site column definition available in the site settings for the other lists that were working fine. I was then able to update the InfoPath form with the new column and publish without error. Unfortunately, the list used a number of site columns so I had to repeat the process for each site column in the list.

InfoPath Form Refreshes on Every Change in Field Focus

This behavior appears to happen in InfoPath forms with secondary data sources. Each time a form field loses focus, a postback is executed and the form refreshes. This creates a delay for the user and a noticeable screen flicker. For fields that do not need a postback, I have found that changing the “Browser forms” properties of the field to never send data will eliminate the problem. Using the REST web service API instead of connecting to an external SharePoint library or list as your secondary data connection seems to have a positive effect as well.

Microsoft InfoPath - Browser Forms Properties
Microsoft InfoPath – Browser Forms Properties

Long Running Script Warning in Internet Explorer

With InfoPath forms using a secondary data source to connect to an external SharePoint library or list, I have experienced errors in Internet Explorer when the user attempts to save the data. The browser will display the following warning message:

Stop running this script? A script on this page is causing your web browser to run slowly. If it continues to run, your computer might become unresponsive.

This happens consistently if the secondary data source is returning a large number of rows. As best as I can tell, the save action initiates a postback which triggers a refresh on the secondary data source. The time needed by Internet Explorer to parse and process the data will cause the “Stop running this script” warning message. This behavior appears to be limited only to certain versions of Internet Explorer. Firefox, Chrome, and other browsers behaved as expected and without incident.

As a workaround, a REST web service data source can be used instead of the connection to a SharePoint library or list. For a reason unknown to me, the postback and data source refresh for REST data sources does not occur when the form data is saved.

State Service Error Occurred While Processing Your Request

The InfoPath form has been published and users are now able to begin saving data. The form has been thoroughly tested and it is working perfectly…

…until the first non-test user attempts to save data and the following error is displayed:

Microsoft InfoPath - Critical Error State Service
Microsoft InfoPath – Critical Error State Service

This error message apparently means that the user does not have permission to enumerate files and folders in a Web site using SharePoint Designer and Web DAV interfaces. The user will either need to be assigned to a permission level that has this permission selected or it needs to be activated on one of the existing permission levels.

Microsoft InfoPath - Browse Directories Permission Setting
Microsoft InfoPath – Browse Directories Permission Setting

Using the SharePoint REST Web Service

SharePoint sites have a REST web service available through listdata.svc.It is accessible by calling the following URL (obviously adjust the parts in between <> for your particular site and remove the <> characters):

http://<site address>/_vti_bin/listdata.svc/<list name>

To return only a subset of columns in the list:

http://<site address>/_vti_bin/listdata.svc/<list name>?$select=<Column 1 Name>,<Column 2 Name>

To sort the data in a particular way:

http://<site address>/_vti_bin/listdata.svc/<list name>?$select=<Column 1 Name>,<Column 2 Name>&$orderby=<Column 1 Name>

To filter the data:

http://<site address>/_vti_bin/listdata.svc/<list name>?$select=<Column 1 Name>,<Column 2 Name>&$orderby=<Column 1 Name>&$filter=<Column 3 Name> eq 'XYZ' and substringof(<Column Name 5>, trim('<     ABC     >')) eq true

In this last example, I am filtering <Column 3 Name> to only return rows where it is equal to the string “XYZ” and where <Column Name 5> contains the substring “ABC” with leading and trailing whitespace removed. There are a number of functions and conditions available to filter data.

Creating a Rule to Change the REST URL in InfoPath

One of the actions available in InfoPath is “Change REST URL”. This is a nice feature because it allows for dynamic filtering of data returned from your external data source. Using the above example for filtering data using listdata.svc , you can create a formula in the action using concatenation and field data entered by the user in the form. As an example, a series of cascading select lists can be created using this method.

concat("http://<site address>/_vti_bin/listdata.svc/<list name>?$select=<Column 1 Name>,<Column 2 Name>&$orderby=<Column 1 Name>&$filter=<Column 3 Name> eq '", <Field Name 1>, "' and substringof(<Column Name 5>, trim('", <Field Name 7>, "')) eq true")

Add a second action to query using a data connection and the filtered results will be returned.

Detecting Changes on Multiple Selection Checkbox Fields

Rules and actions associated with changes to multiple selection checkbox fields do not behave as I would expect. A multiple selection checkbox field is a single field that contains multiple data values that can each be individually checked or unchecked. A rule set up with a condition to execute when the field changes will trigger as expected when items are checked. However, if a checked item is unchecked, the action will not be triggered.

In this example, assume the multiple selection checkbox field is called Products.

  • Create a text box field called “hidden_field”. This field does not need to be visible on the form.
  • On the field properties for hidden_field, set the “Default Value” to the Products field and check the “Refresh value when formula is recalculated” field.
  • On the field properties for Products, create a new rule that is triggered when the field is changed. Add an action to set hidden_field’s value equal to the Products field’s value.

Once these rules are set, checking or unchecking values in the Products field will result in the value of hidden_field changing. Since hidden_field is a standard text box and rules are triggered as expected on a text box, we can then create additional rules using hidden_field to execute based on changes.

Hide SharePoint Ribbons Using jQuery

Using the jQuery library, the following code may be used to hide SharePoint ribbons from appearing at the top of a SharePoint page. In this example, I am using it to hide the ribbon associated with Quest web parts which are used for generating various charts and graphs. I was not able to find or did not have access to a configurable setting to hide the ribbon, so I had to resort to hiding it programmatically in order to reduce clutter on the screen.

Add a Content Editor Web Part to the page and include the following script in the source (or as a reference to a script file). The setTimeout timer should be modified to meet your individual needs. In this particular instance, there is a slight delay after the page is loaded before the ribbon appears so I set the delay to 100 milliseconds to ensure that hide() was called after the ribbon was displayed.

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

<script language='javascript'>
  $(document).ready(function() {
    setTimeout(function() {
    }, 100);

The hardest part is trying to identify the appropriate ID of the element that needs to be hidden especially if the ribbon is generated dynamically as part of a script. I was able to find the ID using the inspect element capability in Firefox, but you may also use the following script to cycle through each of the ribbon tabs to find the one you want to hide.

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

<script language='javascript'>
  $(document).ready(function() {
    setTimeout(function() {
      $("a.ms-cui-tt-a").each(function() {
        var strTabID = $(this).parent().attr("id");
    }, 5000);