SharePoint and adding actions to date controls in 2010 and 2013

SharePoint and adding actions to date controls in 2010 and 2013

Overview

There are many instances where I want to add javascript to a SharePoint form. This may read and process field values, sometimes I can run this in the PreSaveAction () function that is called when the user presses the save button. Occasionally I need to add a function to the onchange event of a control. The script for doing this varies on the control type, with dropdowns (lookups or choice) in SharePoint 2007 or 2010 it varies based on the number of items in the dropdown.

Scenarios in SharePoint 2010

Date/Time controls are one of the trickier ones to deal with. If we imagine a SharePoint 2010 (I’ll look at 2013 in a bit) custom list with a date field as shown below:

The Start Time field is actually four separate things that we need to pay attention to:

  • Input box
  • Date Picker control
  • Hours Select
  • Minutes Select

The script to get a pointer to the input box and add an onchange event is straight forward:

MyDateField = getTagFromIdentifierAndTitle('Input', '', 'Start Time');  
MyDateField.onchange=function() {TimeHasChanged()};

The Ids given to the minute and hours dropdowns are the same as the same as the Id of the input field suffixed by the word Minutes or Hours. We can use the following to add actions to those (we want item 0 in the returned collection):

var MyMinuteField = $('#'+MyDateField.id+'Minutes');
var MyHourField = $('#'+MyDateField.id+'Hours');
MyMinuteField[0].onchange=function() {TimeHasChanged()};
MyHourField[0].onchange=function() {TimeHasChanged()};

It would be common sense that the input’s onchange event would fire when the date picker is used to set that date. However this is simply NOT the case, however hard you click on a day in the date picker that does not trigger the onchange for the associated input field, even though its value is clearly changed.

We can follow the article on Howdididothat and use the onvaluesetfrompicker function that also appears on the input field, even if we can’t see it in the debugger.

MyDateField.onvaluesetfrompicker=function() {TimeHasChanged()};

Simple and this case it is. However if you check the Howdididothat link you may notice a comment that it didn’t work for someone. Lets try a slightly different scenario: consider that instead of a custom list with a date control, we have a list created using SharePoint 2010’s Calendar template. The NewForm will look like:

The first important thing to notice is that if you change the Start Time the End Time will automatically change to the same date unless you have already altered the End Time. This is clearly a terrific time saver, normally you set the start date of something and you want the end date to follow you. However the downside is that the onvaluesetfrompicker function suddenly doesn’t get triggered. SharePoint changing date code must stamp out the function that we had been intercepting. On a custom list onvaluesetfrompicker will work, on the Start Time or End Time in a Calendar form onvaluesetfrompicker will not work for you. This post gives an alternative by overriding the ‘OnPickerFinish’ function from DatePicker.js with the following snippet:

//Override the OnPickerFinish function in DatePicker.js to fire the event when the date is updated from the date picker.
function OnPickerFinish(resultfield)
{
	clickDatePicker(null,"","");
	alert("Blah");
}

This seems to work in every circumstance of a date picker that I’ve tested. However it hooks into all dates on the form and seems to fire twice for each change. In my example I declared MyDateField as a global variable (did anyone spot that?) and used it to test whether the control I was interested in had been activated:

function OnPickerFinish(resultfield)
 {
    clickDatePicker(null,"","");
    if (resultfield.id == MyDateField.id)
    {
        alert(resultfield.value);
    }
 }

You can build in some other test so that you don’t alert (or presumably something more useful) twice. My entire code then is:

<script type="text/javascript" language="javascript" src="/Code%20Library/jquery-1.8.2.min.js"></script>
<script type="text/javascript" language="javascript" src="/Code%20Library/jquery.SPServices-0.7.2.min.js"></script>
<script type="text/javascript" language="javascript">// <![CDATA[
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
	var len = identifier.length;
	var tags = document.getElementsByTagName(tagName);
	for (var i=0; i < tags.length; i++) {
		var tempString = tags[i].id;
		if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {
			return tags[i];
		}
	}
	return null;
}
function TimeHasChanged() {
	alert('The time has changed');
}
//Override the OnPickerFinish function in DatePicker.js to fire the event when the date is updated from the date picker.
function OnPickerFinish(resultfield)
{
	clickDatePicker(null,"","");
	if (resultfield.id == MyDateField.id)
	{
		alert(resultfield.value);
	}
}
$(document).ready(function() {
	//alert("jQuery");
	//alert($().SPServices.SPGetCurrentUser());
	MyDateField = getTagFromIdentifierAndTitle('Input', '', 'Start Time');    
	MyDateField.onchange=function() {TimeHasChanged()};
	var MyMinuteField = $('#'+MyDateField.id+'Minutes');
	var MyHourField = $('#'+MyDateField.id+'Hours');
	MyMinuteField[0].onchange=function() {TimeHasChanged()};
	MyHourField[0].onchange=function() {TimeHasChanged()};
	MyDateField.onvaluesetfrompicker=function() {TimeHasChanged()};
});
function PreSaveAction()
{
	return true;
}
// ]]>
</script>
 

Scenarios in SharePoint 2013

The calendar new form in SharePoint 2013 looks slightly different:

What’s more significant though is that the End Time is no longer changed when the Start Time is updated. The feature seems to have suddenly disappeared; I can’t see it listed on: Changes from SharePoint 2010 to SharePoint 2013. What this means is that our old friend: onvaluesetfrompicker has started working for us again and we no longer need to use OnPickerFinish. This makes life better for picking up a change in the date control and means that Calendar dates are the same as custom dates. However if your users are used to the calendar date behaviour on 2010, they may not appreciate the change in 2013.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s