Category Archives: SharePoint 2013

SPJS Upload for SharePoint: Custom upload page for uploading documents to various document libraries in a site collection

Change log
August 04, 2016
New version that supports opening the EditForm after upload. This can be controlled with a variable:

// Go to EditForm after upload
var showEditFormAfterUpload = true;

Set to false to skip this feature.This new feature requires a few extra fields added to the list with the upload destination – and you must update your function call with these new fields.

If you are crating the <option> manually you must add a few extra attributes – see description in the code where you specify the <option> tags.

I got a request from Gilbert Okello regarding a custom upload solution for submitting documents to various document libraries in a site collection. This solution uses the “CopyIntoItems” method to let the user select a document from the local computer and upload it to a document library / folder within the site collection.
IMG

I must start off emphasizing that this solution requires Internet Explorer 10 or another modern browser to work. There is NO WAY you can make it work in any Internet Explorer version below 10. I have tested it in SP 2010 and SP 2013, but I guess it should work in SP 2007 as well.

The code provided at the bottom of this article builds the upload control by reading a set of predefined upload locations from a custom list. This is the code that builds the dropdown select containing the predefined options:

$(document).ready(function(){
	spjs.upload.getUploadDestinations({
		"listName":"UploadDestination",
 		"listBaseUrl":"",
 		"friendlyNameField":"Title",
 		"relPathField":"RelPath",
 		"baseUrlField":"BaseUrl",
 		"guidField":"DocLibraryGUID",
 		"editFormRelUrlField":"EditFormRelUrl",
 		"orderByField":"Title"
	});
});

listName: The GUID or the display name of the list where the upload destinations are stored.
listBaseUrl: The base URL of the list. If it is in the root site, use “”. If it is in a subsite, use “/MySubsite” or “/Sites/MySubsite” depending on your setup. The list name should NOT be included in this variable.
friendlyNameField: The FieldInternalName of the field that holds the friendly name of the destination.
relPathField: The FieldInternalName of the field that holds the relative URL to the library or folder to upload the files.
BaseUrl: Holds the base URL of the SITE where the document library is located. For example “/Sites/Site1/YourSiteName”
DocLibraryGUID: The GUID of the document library you are uploading into. View source and search for “ctx.listName” to find it.
EditFormRelUrl: The relative URL to the EditForm of your library. For example “/Sites/Site1/YourSiteName/Shared documents/Forms/EditForm.aspx”.
orderByField: The FieldInternalName of the field to sort by.

How to set up this list

Create a custom list with one additional single line of text field “RelPath”. Enter the friendly name in the Title field, and the relative path to the library or folder in the field “RelPath”.
IMG
In addition to the above fields you must add the following if you like to use the new “Go to EditForm after upload” feature.
BaseUrl: Single line of text.
DocLibraryGUID: Single line of text.
EditFormRelUrl: Single line of text.

Using this list is optional. If you like, you can enter the destination directly in the code in the <select> control with id “fileUploadTo”. If you prefer to use the manual approach, ensure you comment out the function call to “getUploadDestinations” in the code example.

The script file “spjs-utility.js” is only used for the function “getUploadDestinations” an you can remove it if you enter the destinations manually.

The code

Get the file “spjs-utility.js” from here. You will also need jQuery. Put this code in a HTML Form Web part where you want the upload control to appear – change the path to the scripts in the top of the code to match you locale files:

<!-- 
/* SPJS Upload for SharePoint
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * Copyright (c) 2013-2016 Alexander Bautz (Licensed under the MIT X11 License)
 * ---------------------------------------------
 * Include reference to:
 * jquery - http://jquery.com
 * spjs-utility.js - http://spjsfiles.com
 * ---------------------------------------------
*/
 -->
 
<script type="text/javascript" src="/SPJS/DFFS/plugins/jquery.js"></script>
<script type="text/javascript" src="/SPJS/DFFS/plugins/spjs-utility.js"></script>
<script type="text/javascript">
/*
 Pull the upload destinations from this list
 If you prefer, you can add the destinations manuelly in the <select> with id "fileUploadTo".
 In that case, comment out this function call

 Ensure the list you pull the upload destination from has all the fields specified in this article: http://wp.me/p3eibN-1nr
*/
$(document).ready(function(){
 spjs.upload.getUploadDestinations({
 "listName":"UploadDestination",
 "listBaseUrl":"",
 "friendlyNameField":"Title",
 "relPathField":"RelPath",
 "baseUrlField":"BaseUrl",
 "guidField":"DocLibraryGUID",
 "editFormRelUrlField":"EditFormRelUrl",
 "orderByField":"Title"
 });
});

// Go to EditForm after upload
var showEditFormAfterUpload = true;

</script>
<style type="text/css">
td.spjs_fileUploadLabel{
 width:150px;
 height:25px;
 font-size:16px !important;
 font-weight:bold;
 font-family:Calibri;
 color:#ffffff;
 vertical-align:middle;
 background-color:#5B9BD5;
 border:1px #41719C solid; 
 padding:3px 3px 3px 6px;
 cursor:default;
}
td.spjs_fileUploadBody{ 
 width:350px;
 font-size:16px !important;
 border:1px #41719C solid; 
 padding:3px;
 cursor:default;
}
input.spjs_fileUploadBtn{
 width:100%;
 height:33px; 
 font-size:16px !important;
 font-weight:bold;
 font-family:Calibri;
 color:#ffffff;
 border:1px #41719C solid;
 background-color:#5B9BD5; 
 cursor:pointer;
 margin:0px;
 padding:0px;
 display:none;
}
input.spjs_fileUploadBtn:hover{
 color:#5B9BD5;
 background-color:#ffffff;
}
.spjs_fileUploadSelect{
 width:100%;
 height:25px;
 background-color:#ffffff !important;
 border:none; 
 font-size:14px;
}
.spjs_empty{
 border:1px #FF0000 dashed !important;
}
</style>
<table cellpadding="0" cellspacing="5" style="border-collapse:separate;">
 <tr>
 <td class="spjs_fileUploadLabel">File</td>
 <td class="spjs_fileUploadBody">
 <input type="file" id="filePicker" style="width:100%;padding:0px;">
 <span style="display:none;color:red;font-size:12px;">Your browser is not supported!<br>Use Internet Explorer 10 or another modern browser.</span>
 </td>
 </tr>
 <tr>
 <td class="spjs_fileUploadLabel">Upload To</td>
 <td class="spjs_fileUploadBody"> 
 <select id="fileUploadTo" class="spjs_fileUploadSelect">
 <!--
 // guid attribute must be guid of destination document library
 // baseurl attribute must be baseURL of site wher the document library is located
 // editformurl attribute must be relative url to the EditForm of this library
 <option value="">Select destination</option>
 <option guid='' baseurl='/Upload' editformurl='/Upload/Forms/EditForm.aspx' value="/Upload/Folder1">Folder 1</option>
 <option guid='' baseurl='/Upload' editformurl='/Upload/Forms/EditForm.aspx' value="/Upload/Folder2">Folder 2</option>
 --> 
 </select>
 </td>
 </tr>
 <tr>
 <td></td>
 <td class="spjs_fileUploadBtn">
 <input id="uploadFileBtn" type="button" class="spjs_fileUploadBtn" onclick="spjs.upload.submitFile();" value="Submit" />
 <span id="uploadError" style="display:none;color:red;"></span>
 </td>
 </tr>
</table>
<script type="text/javascript">

/******************************************************
 Do not change anything below this line
*******************************************************/
var spjs = spjs || {};

spjs.upload = {
 "version":"1.1",
 "versionDate":"August 04, 2016",
 "data":{"fileDataStr":""},
 "handleFileSelect":function(evt){
 // Modified from http://jsfiddle.net/eliseosoto/JHQnk/
 var files = evt.target.files, file = files[0], reader;
 if(files && file){
 reader = new FileReader();
 reader.onload = function(readerEvt) {
 var binaryString = readerEvt.target.result;
 spjs.upload.data.fileDataStr = binaryString.substring(binaryString.indexOf(",")+1);
 $("#uploadFileBtn").show();
 };
 reader.readAsDataURL(file);
 }
 },
 "submitFile":function() {
 if($("#fileUploadTo").val() === ""){
 $("#fileUploadTo").addClass("spjs_empty");
 return;
 }else{
 $("#fileUploadTo").removeClass("spjs_empty");
 }
 var filePath, fileName, destination, b;
 filePath = $("#filePicker").val();
 fileName = filePath.substring(filePath.lastIndexOf("\\")+1);
 destination = location.protocol+"//"+location.host+$("#fileUploadTo").val()+"/"+fileName;
 b = [];
 b.push("<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>");
 b.push("<soap:Body>");
 b.push("<CopyIntoItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>");
 b.push("<SourceUrl>" + fileName + "</SourceUrl>");
 b.push("<DestinationUrls>");
 b.push("<string>"+destination+"</string>");
 b.push("</DestinationUrls>");
 b.push("<Fields>");
 b.push("<FieldInformation Type='Text' DisplayName='Title' InternalName='Title' Value='"+fileName+"' />");
 b.push("</Fields>");
 b.push("<Stream>"+spjs.upload.data.fileDataStr+"</Stream>");
 b.push("</CopyIntoItems>");
 b.push("</soap:Body>");
 b.push("</soap:Envelope>");
 $.ajax({
 url: "/_vti_bin/copy.asmx",
 beforeSend: function (xhr) { xhr.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/sharepoint/soap/CopyIntoItems"); },
 type: "POST",
 dataType: "xml",
 data: b.join(""),
 complete: spjs.upload.processResult,
 contentType: "text/xml; charset=\"utf-8\""
 });
 },
 "processResult":function(data, status) {
 var errorCode, errorMessage;
 errorCode = $(data.responseText).find("CopyResult").attr("ErrorCode");
 errorMessage = $(data.responseText).find("CopyResult").attr("ErrorMessage");
 if(errorCode !== "Success"){
 $("#uploadFileBtn").fadeOut(400,function(){
 $("#uploadError").html("Ensure the selected destination exists!<br><br>Error message: "+errorMessage).show();
 setTimeout(function(){
 $("#uploadError").fadeOut();
 $("#fileUploadTo").val("");
 $("#uploadFileBtn").fadeIn();
 },10000);
 }); 
 }else{
 $("#uploadFileBtn").attr("disabled","disabled").val("File successfully uploaded");
 if(typeof showEditFormAfterUpload !== "undefined" && showEditFormAfterUpload){
 var fileDir = $(data.responseText).find("CopyResult").attr("DestinationUrl");
 var docLibBaseUrl = $("#fileUploadTo option:selected").attr('baseurl');
 var docLibGuid = $("#fileUploadTo option:selected").attr('guid');
 var docLibEditFormUrl = $("#fileUploadTo option:selected").attr('editformurl')
 var fileMetadata = spjs.utility.queryItems({"listName":docLibGuid,"listBaseUrl":docLibBaseUrl,"query":"<Where><Eq><FieldRef Name='EncodedAbsUrl' /><Value Type='Text'>"+fileDir+"</Value></Eq></Where>","scope":"RecursiveAll","viewFields":["FileLeafRef","FileDirRef"]})
 if(fileMetadata.count > 0){
 var id = fileMetadata.items[0].ID;
 SP.UI.ModalDialog.showModalDialog({"url":makeAbsUrl(docLibEditFormUrl+"?ID="+id+"&Mode=Upload")});
 }
 }
 setTimeout(function(){
 $("#uploadFileBtn").fadeOut(400,function(){
 $(this).removeAttr("disabled").val("Submit");
 $("#fileUploadTo").val("");
 })
 },3000);
 $("#filePicker").val("");
 }
 },
 "getUploadDestinations":function(args){
 var res, q, b;
 b = ["<option value=''>Select destination</option>"];
 q = "<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where><OrderBy><FieldRef Name='"+args.orderByField+"' /></OrderBy>";
 res = spjs_QueryItems({"listName":args.listName,"listBaseUrl":args.listBaseUrl,"query":q,"viewFields":[args.friendlyNameField,args.relPathField,args.baseUrlField,args.guidField,args.editFormRelUrlField]});
 $.each(res.items,function(i,item){
 b.push("<option editformurl='"+item.EditFormRelUrl+"' baseurl='"+item.BaseUrl+"' guid='"+item.DocLibraryGUID+"' value='"+item[args.relPathField]+"'>"+item[args.friendlyNameField]+"</option>")
 });
 $("#fileUploadTo").html(b.join(""));
 }
};

if(window.File && window.FileReader && window.FileList && window.Blob){
 document.getElementById('filePicker').addEventListener('change', spjs.upload.handleFileSelect, false);
}else{
 $("#filePicker").hide().next().show();
 $("#fileUploadTo").hide(); 
}
</script>

Post questions and feedback in the comments section below, and if you use this solution, please consider sending me a few beers by clicking the “beer button” in the top right corner of this page.

Enjoy,
Alexander

List view: Preview item on hover

Change log
June 1, 2014
Updated to v1.38:

  • Added “URL” and “Image” as “type” in the fieldData section of the configuration (for use with field of type Hyperlink or Image).
  • Tidied up a few unused variables.
  • Added id attribute “spjs_previewTable” to the main preview table for easier styling. Add style tag to the CEWP code and target the table like this:
    #spjs_previewTable{
    /* your css here */
    }

April 21. 2014
Updated to v1.37:

  • Fixed error when using in list with folders by adding “scope=RecursiveAll” to the query. Please note that you must also update spjs-utility.js to v1.182 or above.
  • Added option to turn on or off the edit item button in the top right corner of the dialog by adding “showEditBtn”:[true or false] to the configuration. See details in the configuration details below.

April 1. 2014
Updated to v1.36:
Fixed an issue with having multiple lists in a web part page. Let me know if there are still issues as I cannot test every possible combination.

March 30. 2014
Updated to v1.35:
Fixed a type in the script that affected IE8 when using the cross list functionality.

March 12. 2014
Updated to v1.32:

  • Removed String;# prefix when previewing calculated columns.
  • Added option to use other columns than ID to identify which item to preview when using the “advanced option” to pull information from another list. See details at the bottom of this article.

January 29. 2014
Updated to v1.31:
Fixed a bug when using in a calendar view on a web part page.
You must add a new variable to the CEWP code alongside the “spjs_listItemPreviewFIN” like this:

var spjs_listItemPreviewFIN = "HoverMe";
var spjs_listItemPreviewList = "{2b6961fc-2e5d-420e-b6d9-3ce7d1bb88b2}";

January 16. 2014
Updated to v1.3:
Fixed a bug that slowed the loading significantly due to a query being executed for each list item in stead of only once per list view.

December 15. 2013
Updated to v1.2 with these changes:

  • Fixed linefeed in multiline plain text fields.
  • Added option to use the value from any field in the form as dialog title. The standard value is “Title”. You find this as a new option in the config object “dlgTitleField”.
  • Added support for showing attachments in the preview. To enable showing attachments, configure it as any other field you want to include in the fields array – use “icon” to show or hide the document icon:
    {"fin":"Attachments","label":true,"icon":true}
    

December 09. 2013
v1.1: Updated the code for the file “PreviewItem.js” and the code example for the calculated column to support list view web parts in web part pages. The change to the calculated column is that the list GUID must be included. This is necessary only if you plan to use a list view web part, and not if you use the code in a proper list view. See details in the code for the calculated column below.

I have previously made several solutions for previewing information for list items by hovering over them in a list view. This is one supports SP2010 and SP2013 – and possibly SP2007 as well. I no longer have access to a SP2007 site and cannot test it there, but I have made an effort to adapt the code to (hopefully) work in SP2007 as well. If you find any problems with the SP2007 support, please post a comment below, and I’ll try my best to fix it.

IMG

This solution uses the well known trick of inserting an image tag in a calculated column, and selecting “number” as the format for the calculated column. This is the code that triggers the solution in a list view (see separate section for calendar view):

="<img src='/_layouts/images/loadingcirclests16.gif' fin='Preview' list='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' configindescription='1' onload='spjs.listItemPreview.init(this)'>"
New in v1.1:

The attribute “list” must be added if you want to use the solution in a list view web part outside the list itself. This attribute is the GUID of the list. You must change the string xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx to match your list. You can find the GUID in SP 2010 or SP 2013 by right clicking a list view in the list > view source > search for “pageListId”. In SP 2007 you must search for “ctx.Listname”.

Please note the FieldInternalName of the field in the “fin” attribute, and the “configindescription” set to “1” indicating that the configuration should be read from the field description. Set “configindescription=’0′” to configure the setup in the HTML Form Web Part (required for SP 2007, optional for SP 2010 and SP 2013).

Ensure you use the “Number” format to trick SharePoint into rendering it as proper HTML:
IMG

When you set “configindescription=’1′” in the calculated column, the configuration is read from the description of the calculated column itself. This way you do not need to edit the setup in a separate file. Please note that you still need to refer the code in the list views where you want to use this solution – or you could put it in the master page to access it in the entire site or site collection. When this is done, the actual configuration for this particular field is done in the list settings!

I’ll get back to the configuration later, but first the general setup.

Setup the scripts
Step 1:

I have used a “icon font” called Font Awesome for all the icons in this solution. Go get it here: Font Awesome.

Here is how Dave Gandy describes Font Awesome:

Font Awesome gives you scalable vector icons that can instantly be customized — size, color, drop shadow, and anything that can be done with the power of CSS.

In my example code I have linked the font awesome css file from bootstrapcdn, but you can download it locally if you like.

Step 2:

Download the file “spjs-utility.js” from here. Ensure you get the latest version.

Step 3:

Get jQuery from here. Use v1.10.x as the 2.x series in not compatible with IE below 9.

Step 4:

Get the code for the file “PreviewItem.js” from here. Ensure you get the latest version.

Step 5:

Add this code to a HTML form web part in the list view where you want the solution activated. Please note that you must insert it ABOVE the list view for the code to be accessible during page load.

<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<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" src="/Scripts/PreviewListItem3/PreviewItem.js"></script>

Now the initial setup is completed and you can configure the calculated column.

Setting up the configuration in the calculated column
Instructions for SP 2010 and 2013

First start by creating a calculated column with this formula:

="<img src='/_layouts/images/loadingcirclests16.gif' fin='Preview' list='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' configindescription='1' onload='spjs.listItemPreview.init(this)'>"
New in v1.1:

The attribute “list” must be added if you want to use the solution in a list view web part outside the list itself. This attribute is the GUID of the list. You must change the string xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx to match your list. You can find the GUID in SP 2010 or SP 2013 by right clicking a list view in the list > view source > search for “pageListId”. In SP 2007 you must search for “ctx.Listname”.

Insert the FieldInternalName of the newly created field in the attribute “fin” in the formula.

This is the settings you have access to when storing the setup in a the description of the calculated column:

{"headerCss":"",	
"clickToView":false,
"hoverDelay":200,
"showEditBtn":true,
"editInDlg":true,
"hoverIcon":{
	"off":"fa-arrow-circle-o-right",
	"on":"fa-arrow-circle-down",
	"css":"color:#FF6103;"
},
"dlgTitleField":"Title",
"maxHeight":400,
"maxWidth":600,
"dateFormat":"dd.MM.yyyy",
"fields":[
	{"fin":"Title","label":true},
	{"fin":"DateAndTime","label":true},
	{"fin":"Multiline","label":true},
	{"fin":"MyChoiceCol","label":true},
	{"fin":"MultiUser","label":true},
	{"fin":"Lookup","label":true},
	{"fin":"Attachments","label":true,"icon":true}
],
"footer":{
	"show":true,
	"css":"",
	"dateFormat":"dd.MM.yyyy hh:mm",
	"strings":{
		"default":["Created at","by","Last modified at","by"],
		"1044":["Opprettet","av","Sist endret","av"]
	}
},
"editFormUrl":null,
"listGuid":null,
"listBaseUrl":null
}
Instructions for SP 2007

First start by creating a calculated column with this formula:

="<img src='[Path to image]' fin='Preview' configindescription='0' iid='"&_ID&"' onload='spjs.listItemPreview.init(this)'>"

Insert the FieldInternalName of the newly created field in the attribute “fin” in the formula. You must also provide the URL to an image you want to show while the solution is loading. The image used in the SP2010 and SP2013 setup is not available in SP2007.

Please note the reference to the _ID field. To use this solution in a list view you must provide the item ID in the calculated column as this is not accessible in the list view table in SP 2007. You cannot use the ID directly in a calculated column as new items will get “0” for ID.

You can use the method described in this article to get the _ID column populated, or you can create a workflow that inserts the ID into the _ID field.

The configuration options for SP2007 can be found below in the section “Setting up the configuration in the HTML form web part”.

Explanation of the various keys
  • headerCss = css to override the dialog header
  • clickToView = true or false to determine whether you must click to open the preview.
  • hoverDelay = number of milliseconds to delay the preview. Used to prevent flickering when moving the mouse over the icons.
  • showEditBtn = true or false to determine whether or not to show the edit item button in the top right corner of the dialog.
  • editInDlg = true or false to determine whether or not to open the EditForm in a dialog. This setting does not apply to SP 2007.
  • hoverIcon = the icon to use for “on” and “off”. These icons must be selected among the font awesome css classes (icons). You can set the icon style using the css setting.
  • maxHeight and maxWidth = number to set the max dialog height and width. You will get a vertical scrollbar if the contents exceed the height setting.
  • dateFormat = a string representing the date format to use. These are the codes representing the various date and time parts:
    yyyy = for digit year.
    yy = two digit year.
    MM = month.
    dd = day.
    hh = hours.
    mm = minutes.
    ss = seconds
  • fields = array of object with the fieldinternal name of the field, and whether or not to render the field label.
  • footer = determine whether or not to show the footer with created and modified.
  • editFormUrl = null by default. Insert the Relative URL of another list to preview items form another location [advanced]
  • listGuid = null by default. Insert the guid of another list to preview items form another location [advanced]
  • listBaseUrl = null by default. Insert the listBaseUrl of another list to preview items form another location [advanced]
Setting up the configuration in the HTML form web part

This section describes how you can set up the configuration in the HTML Form Web Part and not in the calculated columns description field. This is a requirement for SP 2007 and optional for SP 2010 and SP 2013.

var spjs_listItemPreviewConfig = {
	"Preview":{
		"headerCss":"",	
		"clickToView":false,
		"hoverDelay":200,
		"showEditBtn":true,
		"editInDlg":true,
		"hoverIcon":{
			"off":"fa-arrow-circle-o-right",
			"on":"fa-arrow-circle-down",
			"css":"color:#FF6103;"
		},
		"dlgTitleField":"Title",
		"maxHeight":400,
		"maxWidth":600,
		"dateFormat":"dd.MM.yyyy",
		"fields":[
			{"fin":"Title","label":true},
			{"fin":"DateAndTime","label":true},
			{"fin":"Multiline","label":true},
			{"fin":"MyChoiceCol","label":true},
			{"fin":"MultiUser","label":true},
			{"fin":"Lookup","label":true},
			{"fin":"Attachments","label":true,"icon":true}
		],
		"fieldData":{
			"Title":{"disp":{"default":"Title","1044":"Tittel"},"type":"Text"},
			"DateAndTime":{"disp":{"default":"Date / time","1044":"Dato / klokkeslett"},"type":"DateTime"},
			"Multiline":{"disp":{"default":"Multiline","1044":"Flerlinje tekst"},"type":"Text"},
			"MyChoiceCol":{"disp":{"default":"Choice column","1044":"Valgkolonne"},"type":"MultiChoice"},
			"MultiUser":{"disp":{"default":"Multi select people picker","1044":"Flervalgs personvelgerfelt"},"type":"UserMulti"},
			"Lookup":{"disp":{"default":"Lookup","1044":"Oppslag"},"type":"Lookup"},
			"Attachments":{"disp":{"default":"Attachments","1044":"Vedlegg"},"type":"Attachments"}
		},
		"footer":{
			"show":true,
			"css":"",
			"dateFormat":"dd.MM.yyyy hh:mm",
			"strings":{
				"default":["Created at","by","Last modified at","by"],
				"1044":["Opprettet","av","Sist endret","av"]
			}
		},
		"editFormUrl":"/Lists/ListItemPreview3/EditForm.aspx",
		"listGuid":null,
		"listBaseUrl":null
	}
};

As you see, the configuration is mostly the same, but it is defined as an object named “spjs_listItemPreviewConfig” with the configuration for each of the separate calculated columns in it. In this example the FieldInternalName is “Preview”.

When setting up the configuration in the HTML From Web Part you must add the label and the field type for the fields you want to include in the preview. See the “fieldData” key in the code above. As you can see, the text values can be configured for MUI setup, but this will not affect SP 2007 – use the “default” key for the values.

You must provide the relative URL for the EditForm in the “editFormUrl” key. For SP2007 you have to provide the listGuid and the listBaseUrl as well.

Calendar view

In a calendar view you cannot rely on the calculated column to initiate the code for us. For SP 2010 and SP 2013 I have added support for automatically initiating the code, but you must insert two variables in the HTML Form Web Part like this:

var spjs_listItemPreviewFIN = "Preview";
var spjs_listItemPreviewList = "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}";

“Preview” is the FieldInternalName of the calculated column where the configuration is stored. Change the GUID to the one from your list.

Regarding SP 2007 support for calendar views

I do not have access to a SP 2007 site and cannot ensure it works. If anyone wants to test it and possibly fix it, I’m sure many will be happy. Look at the function “calendar” in the file “PreviewItem.js” to see how I have tried to support month view of a calendar in SP 2007.

In a SP 2007 calendar view, you will have to call the code “manually” from the HTML Form Web Part like this:

<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<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" src="/Scripts/PreviewListItem3/PreviewItem.js"></script>
<script type="text/javascript">
$(document).ready(function(){
   spjs.listItemPreview.calendar();
});
</script>
Cross list preview

To be able to do a cross list “preview” you must add the configuration to the HTML Form Web part / CEWP in the “spjs_listItemPreviewConfig” object, and set the “editFormUrl”, “listGuid” and “listBaseUrl” to address the list you want to pull the information from.

You must also supply the ID or another identifier of the item you want to pull the info from in the calculated column in the “iid” attribute in the calculated column.
The default is to lookup an item using the ID for that item. In this case you must have the parent item ID in a column you can use in a calculated column:

="<img iid='"&[TheColumnNameWhereTheIDIsFound]&"' src='/_layouts/images/blank.gif' fin='CrossList' configindescription='0' onload='spjs.listItemPreview.init(this)'>"

* “CrossList” is the FieldInternalName of my calculated column.
* “[TheColumnNameWhereTheIDIsFound]” is the name of the column in the current list item where the ID of the linked item is found.

You can also match the item you want to preview in another column – like the “Standard” column in this example:

="<img iid='Standard:"&Standard&"' src='/_layouts/images/blank.gif' fin='CrossList' configindescription='0' onload='spjs.listItemPreview.init(this)'>"

In the iid attribute in this example I pull the value from the column “Standard” from the current list item, and will match this with the column with the same name in the “lookup list”.

When using this cross list preview you cannot know if the target list will contain an item to preview. If there are no items, the icon will turn gray when you hover over it.

Let me know if you like the solution, have trouble, or find any bugs! – use the comment section below.

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 the size and color of the tiles

Change log
June 8. 2014
Updated to v1.2.4 with these changes:

  • Fixed reversed TileHeight and TileWidth in the description for TileSize. Se below for instruction on how to update the list with the correct description.
  • Added ALT attribute top the image (if you use images for the tiles and not fontawesome).
  • Tidied up the code with JSLint and compressed it using packer by Dean Edwards.

December 7. 2013
Updated to v1.2.2 with these changes:
Added support for FontAwesome.io icons. Either go to the FontAwesome.io site and download the appropriate CSS file, or link it from bootstrapcdn like I have in this example:

<div id="spjs_tiles_placeholder" style="margin:10px;float:left;clear:both;"></div>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<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>

The setup list is automatically updated when you load the updated code. Refer the setup list field description for details on the setup and use of the FontAwesome icons.

November 23. 2013
Updated to v1.2.1 to support SP2013 publishing pages.

This post describes the updated version that has these new features
  • Variable tile size.
  • Custom tile color.
  • Option to refresh parent page when the dialog closes.
Variable tile size

IMG

Variable tile size with headings

IMG

Configuration list

IMG

No tiles configured

IMG

Upgrading from previous version

IMG

Update the configuration list

To force an update of the configuration list, add this to the URL in a page where you have the solution set up

…/site/default.aspx?SPJSTiles:UpdateList=1

*********************************************************************
Let me know if you like the solution, or you have feature requests.

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

SPJS Charts for SharePoint: date range filter

In this article I will show you how to add a date range filter to a chart created using SPJS Charts for SharePoint v4. The code demonstrated below will query the list and get the highest and lowest date in the field specified in the query. It will then create the filter dropdowns based on the interval you select. Currently you can use “m” for month, or “y” for year.

IMG

How to set it up

To use this method for filtering a chart, you must set the variable “allowEval” to true in the CEWP code like this:

// Set this to true to allow for the use of variables in the "Filter setup textarea"
var allowEval = true;

Then you add this code to the same CEWP:

function spjs_getDateRangeFilter(list,field,interval,format){
	var q, res, start, end, split, startDate, endDate, b, d, m, y;
	// Find the start date
	q = "<Where><IsNotNull><FieldRef Name='"+field+"' /></IsNotNull></Where><OrderBy><FieldRef Name='"+field+"' Ascending='TRUE' /></OrderBy>";
	res = spjs.charts.qItems({"listName":list,"query":q,"viewFields":[field],"rowLimit":1});
	start = res.items[0][field];
	// Find the end date
	q = "<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where><OrderBy><FieldRef Name='"+field+"' Ascending='FALSE' /></OrderBy>";
	res = spjs.charts.qItems({"listName":list,"query":q,"viewFields":[field],"rowLimit":1});
	end = res.items[0][field];
	split = start.split(/-| |:/);
	startDate = new Date(split[0],parseInt(split[1],10)-1,split[2]);	
	split = end.split(/-| |:/);
	endDate = new Date(split[0],parseInt(split[1],10)-1,split[2]);
	b = [];
	switch(interval){
		case "m":	
			endDate.setMonth(endDate.getMonth()+1);					
		break;		
		case "y":
			endDate.setFullYear(endDate.getFullYear()+1);
		break;
		default:
			alert("The interval \""+interval+"\" is not supported. Use \"m\" for month or \"y\" for year.");
			return [{"f":"","v":""}];	
	}
	while(startDate<=endDate){
		d = startDate.getDate();
		d = d < 10 ? "0"+d : d;
		m = startDate.getMonth()+1;
		m = m < 10 ? "0"+m : m;
		y = startDate.getFullYear();
		b.push({"f":format.replace("yyyy",y).replace("MM",m).replace("dd",d),"v":String(startDate.getFullYear()+"-"+(startDate.getMonth()+1)+"-"+startDate.getDate()+" 12:00:00")});
		switch(interval){
			case "m":					
				startDate.setMonth(startDate.getMonth()+1);				
			break;		
			case "y":
				startDate.setFullYear(startDate.getFullYear()+1);
			break;		
		}
	}
	return b;
}

var myCustomFilterOptions = spjs_getDateRangeFilter("ListNameOrListGuid","FieldInternalName","m","MM/dd/yyyy");

The variable “myCustomFilterOptions” is used in the filter textarea in the chart. You can name it anything you like, preferably something that identifies the filter.

The arguments to the function “spjs_getDateRangeFilter” is as follows:
list: The DisplayName or the list GUID of the list you are querying.
field: The field internal name of the field – must be type “Date and time”.
interval: The date interval for the filter. Use “m” for month, or “y” for year.
format: The format of the visible date in the dropdown. Use any combination of dd (for day), MM (for month) and yyyy (for year).

Look her to learn how to find the list GUID and the FieldInternaleName.

This is the setup for the chart shown in the top of this article:
IMGIMG

The text in the filter textare is this:

[{"label":"Date from","urlKey":"date1","multiselect":false,"size":5,"options":myCustomFilterOptions},{"label":"Date to","urlKey":"date2","multiselect":false,"size":5,"options":myCustomFilterOptions}]

Please note the name of the variable “myCustomFilterOptions” from the CEWP code.

And the text from the Custom CAML-query textarea is this:

<Where><And><Geq><FieldRef Name='Date' /><Value Type='DateTime'>{filter:date1}</Value></Geq><Leq><FieldRef Name='Date' /><Value Type='DateTime'>{filter:date2}</Value></Leq></And></Where>

You must change the name of the filed to match the FieldInternalName of the field in your list.

Leave a comment below if you like it, or you need help setting it up.

Alexander