Category Archives: Javascript

DFFS v4.250 released

This release has multiple changes and additions from the previous production release (v4.200). You find the complete changelog her: https://spjsblog.com/dffs/dffs-change-log/

I will show you one enhancement in particular – the new options for side-by-side headings and labels:
IMG

This layout is achieved with this configuration
In the “Tabs” tab I have added this configuration:

IMG
Please note how the headers are moved to the side-by-side column using the “Header ID”.

In the Side-by-side tab I have added these labels:

IMG

In the Custom CSS section in the Misc tab I have added this code:
.dffs-vertical-text{
text-align:center;
transform: rotate(-90deg);
font-size:22px;
}
td.sbs_tdIndex_1, td.sbs_tdIndex_2, td.sbs_tdIndex_3, td.sbs_tdIndex_4{
	width:350px !important;
}
td.sbs_Field input.ms-long, td.sbs_Field div.sp-peoplepicker-topLevel{
	width:250px !important;
}
Comments and feedback

Please add any comments, questions or feedback in the forum: https://spjsblog.com/forums/forum/dynamic-forms-for-sharepoint/

Alexander

KPI for SharePoint 2010 and 2013

I received a question about the built in KPI in SP 2010. The user added the KPI to a list view that was filtered with a Query String Filter, but the KPI didn’t respect the filter and kept calculating based on the unfiltered view.

I don’t know if you can do anything about the built in KPI, but It’s a good opportunity to write some JavaScript!

Here is a solution you can drop in any list view to create a KPI that respects both Query String Filters and filters applied by the end user to the columns. The solution requires SP 2010 or 2013 (foundation or server), as it uses the JavaScript Client Object Model. It does NOT require jQuery.

IMG

Get the code for the file “SPJS-KPI.js” from here

Upload it to a document library where all users have read access, and add a HTML Form Web Part with this code in the list view or the web part page:

<table cellpadding="3" cellspacing="0">
	<tr style="font-size:24px;">
		<td valign="middle">KPI attached to list view:</td>
		<td valign="middle" id="kpi_1" style="height:55px;"><img style="margin:12px;" src="/_layouts/images/hig_progcircle_loading24.gif"></td>	
	</tr>

</table>
<script type="text/javascript" src="/SPJS/SimpleKPI/SPJS-KPI.js"></script>
<script type="text/javascript">

ExecuteOrDelayUntilScriptLoaded(function(){
	// KPI example 1
	var args = {
		// Placeholder for the KPI must be an existing HTML element in the page with this ID
		"placeholderID":"kpi_1",
		// Target list and base URL
		"listGUID":_spPageContextInfo.pageListId,
		"listBaseUrl":_spPageContextInfo.webServerRelativeUrl,
		// Target view - must be filled in to use "consumeFiltersFromList"
		"consumeFiltersFromViewGUID":"23233f84-531c-4096-b23b-d6711f117a2d",
		// URL Filter
		"URLfilterKey":"",
		"URLfilterTargetField":"",
		// KPI Indicator field and value
		"kpiIndicatorField":"Reviewed",		
		"kpiIndicatorFieldValue":true,
		// Text
		"noFilterMessage":"The URL filter \"{0}\" is missing.",
		"noItemsFoundMessage":"No items match the filter",
		// Threshold
		"greenThreshold":98,
		"yellowThreshold":80,
		// Icons
		"greenIcon":"/_layouts/images/kpidefaultlarge-0.gif",
		"yellowIcon":"/_layouts/images/kpidefaultlarge-1.gif",
		"redIcon":"/_layouts/images/kpidefaultlarge-2.gif"		
	};	
	spjs.kpi.init(args);	
}, "sp.js");
</script>

Update the link to the file “SPJS-KPI.js” in the code example.

Variables explained
  • placeholderID: This is the ID of a HTML element in the page where you want the KPI to appear.
  • listGUID: This is the list GUID of the list you want to attach the KPI to. If you are using a list view from the list itself (not a web part page), you can use the variable from the example. If not, add the GUID to the list here. To find the GUID, go to a list view, right click and view source. Look for “pageListId”.
  • listBaseUrl: If the KPI list is in the same site, use the variable from the example. If not, add the path like this: “/Sites/NameOfTheSite”
  • consumeFiltersFromViewGUID: To have the filter consume the filters from a list view, add the GUID of the view you are applying the filter to here. Find the list GUID by filtering the view and look at the URL. In SP 2010 you see “View=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”, in SP 2013 you see it like this: InplviewHashxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. The GUID is where the x’es are.
  • URLfilterKey: If you are using an URL filter, this is the key from the URL like this: …/AllItems.aspx?key=value
  • URLfilterTargetField: This is the FieldInternalName of the field in the list where the filter is applied.
  • kpiIndicatorField: This is the FieldInternalName of the field you calculate the KPI from.
  • kpiIndicatorFieldValue: This is the value found in the field you calculate the KPI from. If it is a Yes/No column, use boolean value true or false.
  • greenThreshold: The percentage needed to show the green icon.
  • yellowThreshold: The percentage needed to show the yellow icon (the rest is red).
  • greenIcon, yellowIcon and redIcon: URL to the images.

Ask if you need help or you find a bug.

Alexander

Resource management: Now compatible with DFFS

Change log
July 13, 2015
Changes in v2.42:
Added option to use {currentsite} in baseUrl variable.March 15, 2015
Changes in v2.37:
Fixed a bug where booked time range was missing the minutes – displayed as :00 – when using AM / PM time format.

August 20, 2014
Changes in v2.36:
Fixed bug where the validation messages did not show when the resource field was set to read only.

June 07, 2014
Changes in v2.35:

  • Fixed a bug in the field xml when creating or updating the list as the choices for the hours could not be set in datasheet view due to wrong case on the CHOICES tag. Update the list to fix this issue.
  • Added support for multiple ranges of bookable dates. A big thanks to Rudolf Vehring for extensive testing on this feature!

Please note that you must update the configuration list to the latest version. You find the instructions in the article below.

May 15, 2014
Changes in v2.2:
I have added back the missing features from v1.3. related to restricting bookable time range individually for each weekday. If you are upgrading form v2.1 you must look at the details below as you will have to update the configuration list with new fields (this is done automatically by the script when you trigger the update).

Please note that you must have the latest version of spjs-utility.js. If you use it with DFFS you must have v3.344 or later of dffs_min.js.

May 8, 2014
Changes in v2.1:
Added an option to configure bookable time ranges in a separate list. See detail below.

I have previously posted a solution for preventing double booking of resources. This is a remake of the resource management solution that is more lightweight, and can be used with DFFS. It can also be used as a standalone solution.
IMG

Please note:
This solution is made for unmodified SharePoint forms.
How to set it up with DFFS

Add a reference to SPJSRM_min.js from the CEWP or HTML Form Web Part where you include the DFFS solution. When using this with DFFS (v3.344 or above) you find the configuration in a separate tab like this:
IMG

If you have an older version of DFFS you can activate it by adding this code to the Custom JS section in the Misc tab:

var spjsRmArgs = {
"resourceField":"MeetingRoom",
"dateFrom":"StartDate",
"dateTo":"EndDate",
"timeFormat":24,
"bookableTimeRangeActive":false
};
spjs.rm.init(spjsRmArgs);
Use it as a standalone solution

You must include spjs-utility.js and add the code to the bottom of the form web part like this:

<script type="text/javascript" src="/Scripts/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript" src="/Scripts/SPJSRM/SPJSRM.js"></script>
<script type="text/javascript">

var spjsRmArgs = {
"resourceField":"MeetingRoom",
"dateFrom":"StartDate",
"dateTo":"EndDate",
"timeFormat":24,
"bookableTimeRangeActive":false
};
spjs.rm.init(spjsRmArgs);
</script>
Setup
  • resourceField: This is the FieldInternalName of the field you have the “resource” in. This can be a lookup column (single choice), a people picker (single choice) or any other single choice field present in the form.
  • dateFrom and dateTo: This is the FieldInternalName of the date fields. This solution will NOT handle recurring events.
  • timeFormat: This is either 12 or 24 and is for displaying the time ranges in the overlap message in the correct format.
  • bookableTimeRangeActive: true or false to control whether or not to use a separate list to restrict the bookable time range for the resources. See below.
Bookable time range

When this is used as a standalone solution you must “manually” create the list to hold the bookable time range settings. This is done by calling a function like this:

// Use this to set up the "SPJS-RM-BookableTimeRange" list.
spjs.rm.verifyTimeRangeList();

When this is done you find the list in “All site contents”. Do not let this code persist after the list is initially created as it will slow things down due to an unnecessary request.

SharePoint 2007

If you are using SP2007 you must provide the list GUID or DisplayName in the argument like this:

var spjsRmArgs = {
"listName":"TheListGuidOfThisList",
"resourceField":"MeetingRoom",
...
Download

Get spjsrm.js here (ensure you use v2.2 or above) and spjs-utility.js here.

Localization

To localize the text in the various messages from this solution, add this object to the CEWP alongside the function call:

spjs.rm.text = {
	"overlapMsg":"{0} has already been booked by {1} between {2} and {3}.",
	"endBeforeStartMsg":"End time cannot be less than or equal to start time.",
	"empty":"{0} cannot be left empty!",
	"wrongDateFormat":"Please use this date format: {0}",
	"notInTimeRange":["{0} can be booked from {1} on a {2}.","{0} can be booked to {1} on a {2}."],
	"notInDateRange":["{0} cannot be booked before {1}.","{0} cannot be booked after {1}."],
	"bookableDateRange":"The bookable date ranges for {0} are:
{1}",
	"dayNumObj":{0:"Sunday",1:"Monday",2:"Tuesday",3:"Wednesday",4:"Thursday",5:"Friday",6:"Saturday"}
};

Translate the text as you like, but keep the {placeholders}.

Update from a previous version

The configuration list in v2.2 looks like this (please note that v2.35 has removed the time selector from the dates):
IMG

This list is created automatically for you by the script the first time you set up the solution, but to upgrade you must check “manually” like this:

With DFFS

Click the “Check for updates to the configuration list” text:
IMG

Standalone

Add this function call to the CEWP below where you have loaded the file SPJSRM.js:

spjs.rm.verifyTimeRangeList();

Please note that this code must be commented out when the update is done.

I hope you enjoy the solution. Please post any bugs below.

Alexander

Make field read-only for other than the author

I got this request from @f_Techno:

@SPJavaScripts hello Alexander, I have task list in sps 2010. I want to dim DueDate after create the task. No one should change it except me.

This snippet must be places in the EditForm of the list or library where you want the field to be readonly. What this code does is to check if the logged in user is the author of the list item, and if not, make the field “StartDate” readonly. You can change the fieldnames in the example to target other fields.

<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">
var thisItemDBdata = spjs_getItemByID({"listName":_spPageContextInfo.pageListId,"id":GetUrlKeyValue("ID"),"viewFields":["Author"]});
if(thisItemDBdata !== null){
	var authorID = thisItemDBdata.Author.split(";#")[0];
	if(_spPageContextInfo.userId.toString() !== authorID){
		var fields = init_fields_v2();
		$(fields["StartDate"]).find("td.ms-formbody").hide().after("<td id='readOnly_StartDate' class='ms-formbody'> </td>");
		$(document).ready(function(){
			// Build the fields object again for SP 2013
			fields = init_fields_v2();
			var sDate = getFieldValue("StartDate");
			$("#readOnly_StartDate").html(sDate);
		});
	}
}
</script>

You find spjs-utiliy.js here.

Please note that this code in for SP 2010 or SP 2013. If you want to use it for SP 2007 you must change “_spPageContextInfo.pageListId” for the list DisplayName or GUID.

For more advanced options, check out Dynamic Forms for SharePoint her.

Alexander

Build a Site Map for SPJS Charts for SharePoint

Change log
January 1. 2014
v1.2 has these changes:
Fixed bug where the string representing the “tile” in the org chart exceeds 255 characters and thus halting the script. This is fixes by using a multiline text field in stead of the Title field in the list “SPJS-SiteMap”.

You find the updated code below.

Updating from a previous version?
Please note that you must delete the existing list and rerun the script to recreate it with the new fields. When the script has recreated the list, you must enter setup of your chart to reselect the list and fields for your SiteMap chart. See image below for changes in the chart setup (new field used in stead of the Title field).

I got a request from Stacy Draper ‏@stacyDraper on Twitter:

@SPJavaScripts do you have something that makes a site map? Using the logged in perms instead of having to be a site col admin would be nice

Unfortunately I do not know of a method of doing this without Site collection Administrator (SCA) rights, but thought I should post a solution anyways. This solution iterates trough all sites in the site collection and writes to a custom list in a format that can be rendered as a clickable organization chart using SPJS Charts for SharePoint.
IMG
The map must be created or updates by a SCA, but can be read by all users.

How to set it up
  1. Set up SPJS Charts for SharePoint v4 as described here. Please note that you need v4.03 or later.
  2. Download spjs-utility.js from here and save it in a document library or a folder created in SPD.
  3. Create a Web Part Page and add a HTML Form Web part to it. Add the code from the code block below in the source editor.

    You can also use a CEWP if you use the content link option to link to the code. Do not add the code directly in the source editor of the CEWP.

  4. Download jQuery from here.

When you reload the page, you will see a button named “Add or update site map”. Click this to set up the list. You should get a confirmation message when the list has been created. You need appropriate permissions to add a list. If you are a SCA, go ahead and populate the list with information about all sites in the site collection. This is done by clicking the same button again.

You will get a confirmation message with the count of items added, updated and removed. The information in the list SPJS-SiteMap is now static and will not reflect changes in the site structure live. To update the site map when a site has been added / updated or removed, an SCA must click the button “Add or update site map” again.

Code

You must update the script src to point to your local files.

<div id="siteMapBtn"></div>
<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">

var spjs = spjs || {};

spjs.siteMap = {
	"version":"1.2",
	"data":{
		"listName":"SPJS-SiteMap",
		"listBaseUrl":typeof _spPageContextInfo !== "undefined" ? _spPageContextInfo.siteServerRelativeUrl !== "/" ? _spPageContextInfo.siteServerRelativeUrl : "" : L_Menu_BaseUrl,
		"listDescription":"SPJS-SiteMap for SharePoint by Alexander Bautz / SharePoint JavaScripts: https://spjsblog.com. This list is used as datasource for SPJS Charts for SharePoint."
	},
	"showButton":function(){
		$("#siteMapBtn").html("<input type='button' onclick='spjs.siteMap.update()' value='Add or update site map' />");
	},
	"update":function(){		
		if(!confirm("You must be Site Collection Administrator to add or update the site map. Click OK to continue.")){
			return;
		}
		var b, webs, thisBaseUrl, p, currItems, currItemsObj, newList, uList, data, res, noChangeCount, uCount, nCount, dCount, error;
		b = '<GetAllSubWebCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />';
		webs = {};
		spjs_wrapSoapRequest(spjs.siteMap.data.listBaseUrl+'/_vti_bin/webs.asmx', 'http://schemas.microsoft.com/sharepoint/soap/GetAllSubWebCollection', b, function(data){
			$('Web', data).each(function(i,o){
				thisBaseUrl = $(o).attr("Url").replace(location.protocol+"//"+location.host,"");
				if(thisBaseUrl === ""){
					thisBaseUrl = "/";
				}
				p = $(o).attr("Url").replace(location.protocol+"//"+location.host,"");
				p = p.substring(0,p.lastIndexOf("/"));
				if(p === ""){
					p = "/";		
				}
				webs[thisBaseUrl] = {"title":$(o).attr("Title"),"parent":p};
			});
		});
		// Get current items
		currItems = spjs_QueryItems({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"query":"<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where>","viewFields":["ID","CurrentSite","Parent","URL"]});
		if(currItems.count === -1){
			if(confirm("It looks like the list named "+spjs.siteMap.data.listName+" does not exist.\n\nCreate it now?")){
				newList = spjs_AddList(spjs.siteMap.data.listName,spjs.siteMap.data.listBaseUrl,spjs.siteMap.data.listDescription);
				if(newList.success){
					uList = spjs_UpdateList(newList.id,L_Menu_BaseUrl,[{'Type':'Note','DisplayName':'CurrentSite'},{'Type':'Note','DisplayName':'Parent'},{'Type':'Note','DisplayName':'URL'}],[]);
					if(!uList.success){						
						alert(uList.errorText);
						return;
					}else{
						if(confirm("The list was created successfully. Click OK to populate the list.")){
							spjs.siteMap.update();
						}
					}										
				}else{
					alert("[spjs_AddList]\n\n"+newList.errorText);
					return;
				}
				return;
			}else{
				return;
			}
		}
		currItemsObj = {};
		noChangeCount = 0;
		uCount = 0;
		nCount = 0;
		dCount = 0;
		$.each(currItems.items,function(i,item){
			currItemsObj[item.URL === null ? "" : item.URL] = {"ID":item.ID,"CurrentSite":item.CurrentSite,"Parent":item.Parent,"URL":item.URL};
		});
		error = false;
		$.each(webs,function(url,o){
			data = {"Title":"[...]","CurrentSite":"{\"v\":\""+url+"\",\"f\":\"<a href='"+url+"' target='_blank'>"+o.title+"</a>\"}","URL":url,"Parent":o.parent}
			if(currItemsObj[url] !== undefined){			
				if(currItemsObj[url].CurrentSite === data.CurrentSite && currItemsObj[url].Parent === o.parent && currItemsObj[url].URL === url){
					delete currItemsObj[url];
					noChangeCount += 1;
					return;
				}	
				res = spjs_updateItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"id":currItemsObj[url].ID,"data":data});
				delete currItemsObj[url];
				if(!res.success){
					error = {"errorText":res.errorText,"code":res.errorCode};
					return false;
				}else{
					uCount += 1;
				}
			}else{
				res = spjs_addItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"data":data});
				if(!res.success){
					error = {"errorText":res.errorText,"code":res.errorCode};
					return false;
				}else{
					nCount += 1;
				}
			}				
		});	
		if(error !== false){
			alert("SPJS-SiteMap: An error occurred\n---------------------------------------\nAre you updating from a previous version? If the below error message tells you that one or more field types are not installed correctly, please delete the list \"SPJS-SiteMap\" and rerun this script. The list will be recreated with the missing fields.\n\nPlease note that you must edit the SiteMap chart to reselect the list and fields.\n\nError message\n---------------------------------------\n"+error.errorText);
		}	
		$.each(currItemsObj,function(url,obj){
			res = spjs_deleteItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"id":obj.ID});
			if(!res.success){
				alert("[spjs.siteMap]\n\n"+res.errorText);
				return false;
			}else{
				dCount += 1;
			}
		});
		alert("SPJS-SiteMap\n\nUpdated: "+uCount+"\nAdded: "+nCount+"\nRemoved: "+dCount);
		location.href = location.href;
	}
};

spjs.siteMap.showButton();
</script>
How to configure the chart

Refer the SPJS Charts for SharePoint v4 article for setup instructions, and select the list “SPJS-SiteMap” as data source. Add an option “allowHtml = true” to render the links as HTML. Here is a screenshot of the Edit Chart GUI:
IMG

Let me know what you think of this solution in the comments section below.

Alexander

Formatted auto number in NewForm.aspx or EditForm.aspx using the itemID

Change log
November 24. 2013
Updated the code examples to support lists with folders. I have also added a code example for use with DFFS (update DFFS to 3.26 or above). You must update spjs-utility to the latest version.

This solution let you use the item ID in a calculated column as part of a formatted “autonumber”.

Please note that if you apply the number in NewForm you cannot guarantee that the ID it retrieves is correct because someone other than you can “steal” the ID in a scenario where two or more users submit to the same list or library at the exact same time. In this case you can end up with a duplicated ID.

This is the price you must pay to have this number added in NewForm. If you can wait to add the number in EditForm, you are guaranteed a correct result. You can also use the code in both NewForm AND EditForm to correct any wrong ID added in NewForm.

How to set it up

Add a new column of type “Single line of text”, and the name “_ID” to the list. Add a HTML form web part to the NewForm / EditForm of the list, and add the code supplied below.

Please note that the column “_ID” must be included in all content types as it must be present in the form. The code will hide the field from view.

NewForm.aspx (list)

This code kicks in when you hit the save button, the function “PreSaveItem” queries the current list for the last item added. It gets the item ID, and increment the number by 1, before writing it to “_ID”.

This _ID column can now be used in a calculated column to create a number format of your liking.

<script type="text/javascript" src="/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">

// spjs-utility.js version check
if(spjs.utility.version < 1.178){
	alert("You must upgrade spjs-utility.js to v1.178 or above.");
}

$(document).ready(function(){
	// Hide the field
	$("input[title='_ID']").parents("tr:first").hide();
});

function PreSaveItem(){	
	var listGuid, listBaseUrl, query, res;
	listGuid = _spPageContextInfo.pageListId;
	listBaseUrl = _spPageContextInfo.siteServerRelativeUrl !== "/" ? _spPageContextInfo.siteServerRelativeUrl : "";	
	query = "<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where><OrderBy><FieldRef Name='ID' Ascending='FALSE' /></OrderBy>";
	res = spjs_QueryItems({"listName":listGuid,"listBaseUrl":listBaseUrl,"query":query,"viewFields":["ID"],"rowLimit":"1","scope":"Recursive"});
	if(res.count === 0){
		$("input[title='_ID']").val("1");
	}else{
		$("input[title='_ID']").val(parseInt(res.items[0].ID,10)+1);
	}
	return true;
}
</script>

The PreSaveItem function will automatically execute when the list item is saved, and it coexists with any instances of PreSaveAction.

Use this code with DFFS

If you want to use this code with Dynamic Forms for SharePoint you must do the following:

  • Update DFFS to v3.26 or above
  • Update spjs-utility.js to v1.178 or above
  • Replace the function PreSaveItem with this function:
    function dffs_PreSaveAction(){	
    	var listGuid, listBaseUrl, query, res;
    	listGuid = _spPageContextInfo.pageListId;
    	listBaseUrl = _spPageContextInfo.siteServerRelativeUrl !== "/" ? _spPageContextInfo.siteServerRelativeUrl : "";	
    	query = "";
    	res = spjs_QueryItems({"listName":listGuid,"listBaseUrl":listBaseUrl,"query":query,"viewFields":["ID"],"rowLimit":"1","scope":"Recursive"});
    	if(res.count === 0){
    		$("input[title='_ID']").val("1");
    	}else{
    		$("input[title='_ID']").val(parseInt(res.items[0].ID,10)+1);
    	}
    }
    

Please note that this code example is for SP2010 and 2013. If you are using SP2007 you must change the variables "listGuid" and "listBaseUrl" like this:

listGuid = "GUID or display name of the list";
listBaseUrl = L_Menu_BaseUrl;

You find jQuery here, and spjs-utility.js here.

EdiForm.aspx (list or document library)
<script type="text/javascript" src="/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	// Hide the field
	$("input[title='_ID']").parents("tr:first").hide();
});

function PreSaveItem(){	
	$("input[title='_ID']").val(GetUrlKeyValue("ID"));
	return true;
}
</script>

This code pulls the ID from the URL and writes it to "_ID".

Use this code with DFFS

If you want to use this code with Dynamic Forms for SharePoint you must update DFFS to v3.26 or above, and replace the function PreSaveItem with this function:

function dffs_PreSaveAction(){	
	$("input[title='_ID']").val(GetUrlKeyValue("ID"));
}
Hide the field in DispForm.aspx (list or document library)
<script type="text/javascript" src="/Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	// Hide the field
	$("a[name='SPBookmark__ID']").parents("tr:first").hide();
});
</script>
Example

I have a choice column named "Category", with the following options:
A_Something
B_Something
C_Something

I then add a calculated column with this formula:

=LEFT(Category,1)&"-"&IF(VALUE(_ID)<10,"000"&_ID,IF(VALUE(_ID)<100,"00"&_ID,IF(VALUE(_ID)<1000,"0"&_ID,_ID)))

This code pads the number up to a four digits with leading 0 like this:
A-0001
A-0002
...
A-0012
A-0013
...
A-0123
A-0124
...
A-1234
A-1235

Let me know if you have any questions,
Alexander

SharePoint 2013 style tiles

Change log
November 19. 2013
Updated to v1.2. Read this article for details.

IMG

If you like the “Promoted Links” tiles in SharePoint 2013, you will love this solution. It lets you create such tiles in SharePoint 2010 and 2013 from a custom list. The text, description, link and even the image can be set up with support for MUI to have it adapt to the selected language. The tiles can be positioned in multiple rows and columns to give the layout you want, and there is a separate CSS file if you want to tinker with the colors etc.

How to set it up

First you need to get the files “SPJS-tiles.css” and “SPJS-tiles.js” from here. Then download jQuery from here. Add these files to a folder created in SharePoint Designer, or to a document library where all users have READ ACCESS.

Add a HTML Form Web Part to the page where you want to have the tiles, and add this code to the source editor:

<div id="spjs_tiles_placeholder" style="margin:10px;float:left;clear:both;"></div>
<link type="text/css" href="/Scripts/Tiles/SPJS-Tiles.css" rel="stylesheet">
<script type="text/javascript" src="/Scripts/Tiles/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/Tiles/SPJS-Tiles.js"></script>
<script type="text/javascript">
spjs.tiles.init("spjs_tiles_placeholder","MyTiles");
</script>

You must changer the css file href and the script src to point to your local files. Do not refer the files from spjsfiles.com as this server is not rigged for serving scripts live.

Argument to the function “spjs.tiles.init”:
The first argument refers to the ID of the placeholder where you want the tiles to be placed. The second argument refer the the Title field in the setup list. You use this “keyword” to filter out the tiles you want to show in this instance. If you omit this argument, you will retrieve all tiles.

When you save this code, and reload the page, you should see this banner:
IMG

Click the button to create the configuration list. It will be placed in the same site as you triggered this script. You should be redirected to the list after it has been created. If this fails, you find the list in “All site content” as “SPJSTiles”.

The configuration list for my example image looks like this:
IMG

MUI support

The field description in the configuration list describes the format for enabling MUI support:

{"1033":"English value","default":"default value"}

You can add all the languages you have installed language packs for. Use “default” as a fallback if the language the user has selected has not yet been configured for the tile.

Leave questions and comment below.

Alexander

Document library: script to update Title from Filename

I got a request for a script that updates the Title field to be the same as the Name field in a document library. This to be able to use a lookup column to pick relevant documents from another list or library.

This code will insert a button that lets you search for all documents that do not already have a Title set, and update it to be the same as the file name.

Add this code to a list view in the library you want to update:

<input type="button" onclick="updateTitleFromName()" value="Update Title from Name" />

<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">

function updateTitleFromName(){
	var q, res, uRes, count;
	count = 0;
	q = "<Where><IsNull><FieldRef Name='Title' /></IsNull></Where>";
	res = spjs_QueryItems({"listName":_spPageContextInfo.pageListId,"query":q,"viewFields":["ID","FileLeafRef"]});
	if(res.count === 0){
		alert("No files without title found.");
		return;
	}
	if(!confirm("There are "+res.count+" files to update. The page will appear as frozen while the script is working.\n\nContinue?")){
		return;
	}
	$.each(res.items,function(i,item){
		uRes = spjs_updateItem({"listName":_spPageContextInfo.pageListId,"id":item.ID,"data":{"Title":item.FileLeafRef.split(";#")[1]}});
		if(!uRes.success){
			alert("Could not update the file: "+item.FileLeafRef+" due to the follwing error:\n\n"+uRes.errorText);
		}else{
			count += 1;
		}
	});
	alert("Updated "+count+" files.");
	location.href = location.href;
}
</script>

If you want to add this code directly to the page, use a HTML form web part to hold the code. You can also use a CEWP to link to the code from another location (like a document library).

You find jQuery here
And you find spjs-utility.js here

Let me know if you have any questions.

Alexander