SharePoint Custom UI Widgets
SPWidgets is a jQuery plugin that provides SharePoint Widgets that can be used for creating customized User Interfaces (UI) on the SharePoint platform using Client Side scripting (javascript).
For the latest information on this plugin, see the project page on GIT.
SPWidgets has the following dependencies:
The following is an example that loads the required libraries from CDN's, the SPWidgets from the local site and then initiates the People Picker plugin on an input field inside a jQuery UI dialog.
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css" />
<script type="text/javascript" src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>
<script type="text/javascript" src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js'></script>
<script type="text/javascript" src='http://cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/0.7.1a/jquery.SPServices-0.7.1a.min.js'></script>
<script type="text/javascript" src='yoursite/path/to/SPWidgets.js'></script>
<script type="text/javascript">
$(document).ready(function(){
$("<div> <input name="users" value="" /> </div>")
.appendTo("body")
.find("input")
.pickSPUser()
.end()
.dialog();
});
</script>
Dual License support
User can pick whichever one applies best for their project and does'nt not have to contact me.
Paul Tavares @purtuga
Follow me at Twitter @paul_tavares
Given an input field, this method will display an interface that allows the users to select one or more users from SharePoint and stores the selected user information into the input field in the format expected when making an update via webservices.
The input field will be hidden in its current position and a UI will displayed instead. As the user picks or removes users, the input field will be updated at the same time, thus it will always be ready to be submitted as part of an update to the server.
$("input[name='users']").pickSPUser();
This method takes as input an object containing the following options
allowMultiples : Boolean. Optional. Default=true.
Determine whether multiple users can be picked.
maxSearchResults : Integer. Optional. Default=50.
The max number of results to be returned from the
server.
onPickUser : Function. Optional. Default=null.
Function that is called when user makes a selection.
Function will have a context (this keyword) of the
input field to which this plugin was bound, and
will be given one input param; an object containing
information about the selection made by the user. This
object will contain data returned by the SharePoint's
webservice.
This plugin will return a jQuery object that contains the initially selected set of node, thus maintaining chainability.
Bind people picker and allow only 1 person to be selected/stored.
$("input[name='users']").pickSPUser({
allowMultiples: false
});
When user makes a selection, show alert with person's info.
$("input[name='users']").pickSPUser({
onPickUser: function(person){
alert("User selected: \n displayName: " +
person.displayName + "\n accountId: " +
person.accountId + "\n accountName: " +
person.accountName + "\n accountType:" +
person.accountType);
}
});
jQuery plugin that inserts a widget into page for uploading a file to a SharePoint location (library) without having to leave the page that the user is currently on. This plugin provides a behavior similar to an async ajax call.
At its core, this plugin is simply uses the default SharePoint upload.aspx page inside an iframe, but manipulating it from the hosted page, so that the user is shown only a minimalist UI. Code hooks are provided for allowing a developer to further manipulate the page(s) that may be shown after the initial upload (ex. some libraries require users to fill in additional information and then check in the document. This can all be automated without user input.)
In a normal flow, the upload process follows this sequence:
$("input[name='users']").SPControlUpload({
listName: "Shared Documents",
onPageChange: function(ev){
if (ev.state === 3) {
ev.hideOverlay = false;
alert("Upload Done!");
}
}
});
This method takes as input an object containing the following options
listName : String. REQUIRED.
The name or UID of the list.
Example 'Shared Documents' or '{67587-89284-93884-78827-78823}'
folderPath : String. Optional. Default="/"
The path to the folder inside of the Document Library where
the document should be uploaded to. Value can be either relative to the
document library root or absolute. Default is to place the
document at the root of the Document Library
Examples 'http://yourdomain.com/sites/site1/Shared Documents' or
'/sites/site1/Shared Documents'
uploadDonePage : String. Optional. Default="/_layouts/viewlsts.aspx".
The url of the page that should be loaded after the
file has been uploaded successful. Value MUTST start with http.
Default is 'http://yourdomain.com/sites/site1/_layouts/viewlsts.aspx'
onPageChange : Function. Optional. Default=null.
Function that is called each time the form in the
iFrame is changed. The function 'this' keyword points to the
element that was used when this method was called.
The function is given one param - the event object created
by this plugin that includes information about the state
of the upload. See Event Object below for more information.
Return value of this function will control flow of plugin.
Returning true (boolean), will allow processing to continue
at different stages (see the event object below), while
returning false (boolean) will stop flow from continuing. The
check is strict; meaning that it has to be a boolean false in
order for flow to stop.
onPageChange: function(ev){
// this=original $(selector)
// so some processing
return true; // allow form to proceed.
}
uploadUrlOpt : String. Optional. Default="".
String of data that should be appended to the upload page url,
following this '?".
This string value is assumed to have already been properly
escaped for use in the url.
NOTE: The option "MultipleUpload=1" is NOT SUPPORTED.
overwrite : Boolean. Optional. Default=False.
True or False indicating if document being uploaded should
overwrite any existing one. Default is False (don't overwrite)
uploadPage : String. Optional. Default="/_layouts/Upload.aspx".
The relative URL from the WebSite root to the upload page.
Default is "/_layouts/Upload.aspx". This value is appended to
to the website full url, which is retrieved using SPServices
utility.
overlayClass : String. Optional. Default="".
A css class to be associated with the overlay that is displayed
over the iframe while loading of the page is going on.
overlayBgColor : String. Optional. Default="white".
A color to be used for the overlay area that is displayed over
the iframe wile loading of the page is going on. Default is
white. Set this to null if wanting only to use a class.
overlayMessage : String|HTMLElement|jQuery. Optional. Default="Loading...".
String or object/element to be displayed inside of the overlay
when it is displayed.
The function defined for the onPageChange input parameter will receive as input an event object generated by this plugin. The object will contain information about the state of the upload process.
The following attributes can be found in the event object:
ev.state : Integer. 1|2|3
A value from 1 through 3 that represents the state of
the phisical file. This value, along with the
ev.action value can be used to validate user input
and if appropriate, cancel the send request to the
server.
No File uploaded. Upload form is ready for user input. This is set when the form is initially loaded and the File html element is ready for the user to attach the file.
No File uploaded. User has defined a file for upload and form is now ready to be submitted to the server. This state could be used in the onPageChange to (for example) prevent the upload of certain file types.
File has been uploaded and is now available on the server (note that it may not be checked in yet). This state is set when the user has successfully uploaded the file to the server and no errors were encountered (example invalid file characters). This state will remain through subsequent pages if the file requires check in.
ev.action : String. preLoad|postLoad
The event action as it pertains to this plugin. Use this value in
conjuction with the ev.state to do additional validations on user
input.
ev.hideOverlay : Boolean. Default=true.
Used when action=postLoad. Can be set by a callback function to false,
so that the busy overlay remains displayed and is not automatically
hidden.
ev.pageUrl : String.
The url of the page currently loaded in the iframe.
ev.page : jQuery Object.
An object representing the page loaded inside the iFrame. This can be
used to further manipulate the iframe's page content.
ev.isUploadDone : Boolean.
Indicates if the upload process is done. Basically, this means that
the processes has reached the page defined in the updatePageDone
parameter.
This plugin will return a jQuery object that contains the initially selected set of node, thus maintaining chainability.
The following example creates a jQuery UI dialog to display the upload interface to the user. The dialog closes after the file is sucessfuly uploaded. It demostrates the use of the event object's state and isUploadDone attributes.
$('<div style="height:350px;width;100%;padding:.5em;"></div>')
.appendTo("body")
.dialog()
.SPControlUpload({
listName: "Shared Documents",
onPageChange: function(ev){
// If we're done with the upload, then continue to show the
// overlay, and fade out the area that contained the upload control.
if (ev.state == 3 && ev.isUploadDone) {
ev.hideOverlay = false;
setTimeout(function(){
$(this).dialog("close").dialog("destroy");
alert("Upload Done!");
}, 1000);
// If file was uploaded, but we have required fields to fill out,
// then adjust page to only show the required data...
} else if (ev.state == 3 && !ev.isUploadDone) {
// Because we're coming from the same domain, we
// have full access to the content of the page,
// and thus we can manipulate it. In this example
// I hide all chrome and show only the form fields
// the user should be filling in.
// Note that this works because in this very simple
// example, I assume that the required fields form
// does not have any special fields, like people pickers,
// etc.
ev.page.find("form")
.children(":visible")
.css("display", "none")
.addClass("ptWasVisible")
.end()
.find("input[title='Name']")
.closest("div[id^='WebPart']")
.appendTo(ev.page.find("form"));
}
}//end: onPageChange()
});
In this example the file that the user is attempting to upload will be checked and if not a PDF file, then an error is displayed and the file is not uploaded.
$('<div style="height:350px;width;100%;padding:.5em;"></div>')
.appendTo("body")
.dialog()
.SPControlUpload({
listName: "Shared Documents",
onPageChange: function(ev){
// If we're done with the upload, then continue to show the
// overlay, and fade out the area that contained the upload control.
if (ev.state == 3 && ev.isUploadDone) {
ev.hideOverlay = false;
setTimeout(function(){
$(this).dialog("close").dialog("destroy");
alert("Upload Done!");
}, 1000);
// If file was uploaded, but we have required fields to fill out,
// then adjust page to only show the required data...
} else if (ev.state == 3 && !ev.isUploadDone) {
ev.page.find("form")
.children(":visible")
.css("display", "none")
.addClass("ptWasVisible")
.end()
.find("input[title='Name']")
.closest("div[id^='WebPart']")
.appendTo(ev.page.find("form"));
}
// User has clicked UPLOAD. If file type not pdf, error
} else if (ev.state == 2 && ev.action === "preLoad") {
var uploadFileName = String(ev.page.find("input[type='file']").val());
if (uploadFileName.match(/\.pdf$/i) === null) {
alert("Only PDF file are allowed!!");
return false; // Cancel upload
}
}
}//end: onPageChange()
});
Given a selector (an html element), this method will insert a Kan-Ban board inside of it based on one of the columns from the desired List. The column must be of type Lookup or Choice, and whose values will be used by this widget to build the Board columns. The widget support both columns set as Required or Optional and has input parameters available to filter the list of columns created.
$("#board").SPShowBoard({
list: "Tasks",
field: "Status"
});
This method takes as input an object containing the supported options:
$("#board").SPShowBoard({
list: '',
field: '',
CAMLQuery: '<Query></Query>',
CAMLViewFields: '',
fieldFilter: null,
optionalLabel: '(none)',
template: null,
webURL: $().SPServices.SPGetCurrentSite(),
onGetListItems: null,
onPreUpdate: null,
onBoardCreate: null
});
The default options for this widget can be manipulated/set via the following object:
$.SPWidgets.defaults.board = {}
list : String. Required.
The list name or UID.
field : String. Required.
The field from the List from where the board should
be built from. This field should be either of type
CHOICE or LOOKUP.
CAMLQuery : String|Function. Optional. Default=<Query></Query> String with CAML query to be used against the list to filter what is displayed or a function that will provide the list of items (an array). If defining a Function, it will be given two input parameter:
a function that must be called and be given the array of items.
The options defined on input to this widget. The user defined function will be given a scope (this keyword) of the html element it was bound to.
Example:
options.CAMLQuery = '<Query><Where>' + '<FieldRef Name="Project" />' + '<Value Type="Text">Latin America</Value>' + '</Where></Query>';
--or--
options.CAMLQuery = function(sendResults) { //get items from DB sendResults([...]); }
CAMLViewFields : String. Optional. Default="" String in CAML format with list of fields to be returned from the list when retrieving the rows to be displayed on the board.
fieldFilter : String. Optional. Default="" A string with either a comma delimetered list of column values to show if field is of CHOICE type; or a string with a CAML query to filter field values, if field is of type Lookup
optionalLabel : String. Optional. Default="(none)" The string to be used as the State column header when field from where Board was built is optional in the List.
template : String|Function|Element|jQuery. Optional. Default="<div/>" The HTML template that will be used to for displaying items on the board. The HTML will be used with jQuery's .wrapInner() method and will use the Title field to populate the inner nodes. When defining a Function, it will be called with a context of the item container on board that should receive the content and be given two input parameters: an object with the list item and the original element that the board was bound to. Example:
function(listItem, boardItemEle){
// this = jQuery - List Item container within the board.
}
webURL : String. Optional. Default=current site The WebURL for the list.
onGetListItems : Function. Optional. Default=null Callback function to be called after data has been retrieved from the 'list'. Function will be given a scope (this) of the selection they used on input to this method and two input parameters: An Array of Objects with the list of rows returned from the List, and A jQuery object representing the entire xml document response. Example:
onGetListItems: function(items, xmlResponse){
//this = jQuery element container selction
}
onPreUpdate : Function. Optional. Default=null Callback function to be called just prior to a List Item update. The function should return a boolean indicating whether the update should be canceled. True will cancel the update. The callback will have a scope of the item being updated and be given 3 parameters:
the event object
the item (DOM element) that triggered the event and
a data object with information/methods for the current item/widget binding. The object will include two attributes that will impact the updates that will be done: data.updates An array of updates that will be made. The array will have, to start, the update to the state that was triggered by the move in the board. Additional updates can be added. Format will be identical to what SPServices uses: ["field", "value"]. Example:
data.updates.push(["Title", "New title here"]);
data.updatePromise A jQuery.Promise that represents the update that will be made. This can be used to bind on additional functionality. The queued functions will be given the List Item object as well as the xml resposne returned from the update. The context of object will be the HTML element from where the update was triggered.
The function should return a boolean indicating whether the update should be canceled. True will cancel the update. Example:
onPreUpdate: function(ev, item, data){ //this = jQuery element container selction
data.updates.push(["Title", "Update was made!"]);
data.updatePromise.done(function(){ alert("udpate done!"); });
}
onBoardCreate : Function. Optional. Default=null Function triggered after board is initially created. See spwidget:boardcreate event for parameters that will be given to function.
This plugin will return a jQuery object that contains the initially selected set of nodes (selector), thus maintaining chainability.
refresh Refreshes the data in the Board by retrieving the data from the list again. During a refresh, existing board items (the html element in DOM) is not actually deleted and recreated if it already exists, but re-used. It is important to note this specially if a custom template function was defined as an input param. Usage:
$("#board").SPShowBoard("refresh");
redraw Redraws the board without pulling in data from the list. Column heights will be normalized and jQuery UI's sortable widget will be refreshed.
$("#board").SPShowBoard("redraw");
This widget triggers several events that can be used to perform additional actions from those experienced in the board. In addition to the events below specific to this widget, events are also fired by the jQuery UI sortable interaction.
spwidget:boardchange Event is triggered anytime a change happens in the board The function scope (this variable) will point to the column element that received the new item and is given 3 input parameters:
A jQuery event object - the one generated by the jQuery UI's sortable interaction
the item (DOM element) that triggered the event
A data object with information/methods for the current item/widget binding. The objects updates attribute will contain an array of array's with the updates that will be made to the item.
Example:
$("body").on("spwidget:boardchange", function(ev, item, data){
// this = column that received item;
})
spwidget:boardcreate Event is triggered when the board is first created. It has the same scope and input elements as teh spwidget:boardchange event, above.
spwidget:boarditemadd Event triggered when new items are added to the board (ex. from a refresh). Event will be given the following input params:
the event object (jquery)
the item (DOM element) that triggered the event
a data object with information/methods for the current item/widget binding. The objects's .itemsModified attribute will contain an array of Objects that were added.
spwidget:boarditemremove Event triggered when items are removed from the board (ex. from a refresh). Event will be given the following input params:
the event object (jquery)
the board container (DOM element)
a data object with information/methods for the current item/widget binding. The objects's .itemsModified attribute will contain an array of Objects that were removed.
$("<div/>").append("body")
.SPShowBoard({
list: "Tasks",
field: "Status"
});
The following is a list of common utilities created internally for the widgets, but built generically and accessible externally.
A simple templating engine. Meant primarily for use internally by the widgets provided in this library. It simply replaces tokens in a string having a format of {{tokenName}} with the tokeName found in the data to be used to fill out the template. (Since v. 2.0)
The method accepts as input an Object containing the options below.
tmplt : String|jQuery|Selector. Required.
The template to be used for the data.
data : Object|Array. Required.
The object containing the data to be used in populating the template. This value can also be an Array of object, in which case, each array item will be used to build the return string.
This method will return a String with the template filled out with the data.
$.SPWidgets.fillTemplate({
tmplt: '<div>{{Title}}</div>',
data: [
{ Title: "Record number 1" },
{ Title: "Record number 2" },
{ Title: "Record number 3" },
{ Title: "Record number 4" }
]
});
Given an array of individual CAML filters, this method will wrap them all in a Logical condition (<And></And> or a <Or></Or>). The result (a string) will be returned to the caller. This method takes care of building the proper format required by the CAML conditional aggregates. (Since v. 2.0)
The method accepts as input an Object containing the options below.
values : Array. Required
The array of String elements that will be join into caml Logical condition.
type : String. Optional. Default="AND"
Static String. The type of logical condition that the values should be wrapped in. Possible values are AND or OR. Default is 'AND'.
onEachValue : Function. Optional. Default=null
A function to process each items in the values array. Function must return the value that should be used in the logial concatenation.
Function is given 1 input param - the item currently being processed (from the values input param).
This method return a String containing the concatenated filter values in the appropriate AND or OR logical aggregate.
$.SPWidgets.getCamlLogical({
type: "or",
values: [
"<Eq><FieldRef Name='Title' /><Value Type='Text'>Test</Value></Eq>",
"<Eq><FieldRef Name='Title' /><Value Type='Text'>Test1</Value></Eq>",
"<Eq><FieldRef Name='Title' /><Value Type='Text'>Test2</Value></Eq>",
"<Eq><FieldRef Name='Title' /><Value Type='Text'>Test3</Value></Eq>",
"<Eq><FieldRef Name='Title' /><Value Type='Text'>Test4</Value></Eq>"
]
})
$.SPWidgets.getCamlLogical({
type: "and",
values: [
"west",
"east"
],
onEachValue: function(loc){
return "<Neq><FieldRef Name='Region'/>" +
"<Value Type='Text'>" + loc + "</Value></Neq>";
}
})
Given a group of elements, this plugin will set their css height attribute to be at least equal to the tallest item among them. (Since v. 2.0)
ele : HTMLElement|Selector|jQuery. Required.
The set of elements whose height will be adjusted.
pad : Integer. Optional. Default=0
Number of pixels to add on to the height. Value will be added to the calculated height of the tallest element.
The ele input parameters is returned to the caller.
Given the following html markup:
<div class="spwidgets-demo" style="height: 30px;" />
<div class="spwidgets-demo" style="height: 100px;" />
<div class="spwidgets-demo" style="height: 50px;" />
<div class="spwidgets-demo" style="height: 102px;" />
The above elements height would be set to 102px by the following:
$.SPWidgets.makeSameHeight( $("div.spwidgets-demo") );
Parses a SharePoint lookup values as returned by webservices (id;#title;#id;#Title) into an array of objects where each object contains the lookup item data (ID and TITLE). (Since v. 2.0)
An array of objects will be returned where each object has two keys; title and id of the lookup item that was parsed. Example:
[
{
id: "1",
title: "Title of lookup item 1"
},
{
id: "2",
title: "Title of lookup item 2"
},
{
id: "3",
title: "Title of lookup item 3"
}
]
$.SPWidgets.parseLookupFieldValue("1;#Title of lookup item 1;#2;#Title of lookup item 2");
Returns a date string in the format expected by SharePoint Date/time fields. Useful when wanting to obtain a date/time string for use in CAML Queries. (Since v. 2.0)
Credit: Matt twitter @iOnline247 in this SPServices post
dateObj : Date. Optional. Default=Date()
The date object to use in generating the Date string.
formatType : String. Optional. Default="local"
What format to use in creating the date string. Supported values are local for local time and utc for UTC time.
A string is returned with the date formatted in the appropriate locale.
// Return today's date formatted in local time
// Result example: 2013-05-06T13:08:10
$.SPWidgets.SPGetDateString();
// Return date formatted in UTC time
// Result example: 2013-05-06T17:09:19Z
$.SPWidgets.SPGetDateString(null, "utc");
A jQuery method (extension of $.fn) that given a SharePoint webservices response object, will look to see if it contains an error and return that error formatted as a string. The XML response object will be checked for errors that might be returned in the following XML elements:
<ErrorCode />
<faultcode />
(Since v. 2.0)
None.
A string with the first error found in the XML message.
alert( $(xData.responseXML).SPGetMsgError() );
A jQuery method (extension of $.fn) that given a SharePoint webservices response object, that given an XML message as returned by the SharePoint WebServices API, will check if it contains an error and return a Boolean indicating that. The XML response object will be checked for errors that might be returned in the following XML elements:
<ErrorCode />
<faultcode />
(Since v. 2.0)
None.
A Boolean will be returned indicating whether the XML message has an error (true) or not (false).
if ( $(xData.responseXML).SPMsgHasError() ) {
alert("error in xml message.");
}