Custom Widget: SP Sites List - akumina/AkuminaTraining GitHub Wiki
Version: Akumina Foundation 3.3.0.0+
The SP Sites List widget displays a list of SharePoint sites to an end user based upon their permissions. The SP Sites List widget does this by querying SharePoint for sites that a user has access to and displays them within an unordered list. A link is provided to each individual site, allowing the end user to navigate directly from there from the widget output. This widget uses the current user context to determine the appropriate sites to display, and allows configuration of the number of sites to display. By default, this value is set to “5”.
Below is the custom JavaScript which encapsulates and renders the widget using the configured properties and views. This custom JavaScript is stored within digitalworkplace.custom.js, a file located in the “/Style Library/DigitalWorkplace/JS” folder.
// Begin SP Sites Widget
if ((typeof Akumina.AddIn.SPSites) === 'undefined') {
Akumina.AddIn.SPSites = function () {
var _cur = this;
this.GetPropertyValue = function (requestIn, key, defaultValue) {
var propertyValue = "";
for (var prop in requestIn) {
if (key.toLowerCase() == prop.toLowerCase()) {
propertyValue = requestIn[prop];
break;
}
}
return (propertyValue == undefined || propertyValue.toString().trim() == "") ? defaultValue : propertyValue;
};
//sets the default properties on the widget.
this.SetDefaultsProperties = function (requestIn) {
var requestOut = requestIn
requestOut.SenderId = _cur.GetPropertyValue(requestIn, "id", "");
requestOut.DisplayTemplateUrl = _cur.GetPropertyValue(requestIn,
"displaytemplateurl", "");
requestOut.PageSize = _cur.GetPropertyValue(requestIn, "pagesize", "");
return requestOut;
};
//"Init" is the main function called from the framework, everything else is specific to this widget
this.Init = function (SiteRequest) {
_cur.SiteRequest = _cur.SetDefaultsProperties(SiteRequest);
_cur.SiteRequest.EditMode = Akumina.AddIn.Utilities.getEditMode();
//Widget Framework
var widgetName = "SP Sites";
Akumina.Digispace.WidgetPropertyViews.AddViewForProperty(widgetName, "DisplayTemplateUrl", "TemplatePicker");
_cur.Prerender();
};
this.Prerender = function () {
var targetDiv = this.SiteRequest.SenderId;
$("#" + targetDiv).html(Akumina.Digispace.ConfigurationContext.LoadingTemplateHtml);
//subscribe to loader completed event, this is fired at the end of the DWP page lifecycle
Akumina.Digispace.AppPart.Eventing.Subscribe('/loader/completed/', _cur.Render);
//subscribe to refresh event, called by Widget Manager on DWP
Akumina.Digispace.AppPart.Eventing.Subscribe('/widget/updated/', _cur.RefreshWidget);
};
this.Render = function () {
var data = {}
data.PageSize = _cur.SiteRequest.PageSize;
data.Items = [];
//retrieve site list
_cur.RetrieveListItems();
};
this.RefreshWidget = function (newProps) {
if (newProps["id"] == _cur.SiteRequest.SenderId) {
_cur.SiteRequest = _cur.SetDefaultsProperties(newProps);
_cur.Render();
}
};
this.BindTemplate = function (templateUri, data, targetDiv) {
new Akumina.Digispace.AppPart.Data().Templates.ParseTemplate(templateUri, data).done(function (html) {
$("#" + targetDiv).html(html);
});
};
//Queries SharePoint and retrieves a list of SharePoint sites based on user context and pagesize
this.RetrieveListItems = function () {
var siteurl = Akumina.Digispace.SiteContext.SiteAbsoluteUrl;
var pagesize = _cur.SiteRequest.PageSize;
$.ajax({
url: siteurl + "/_api/search/query?querytext=%27*%27&rowlimit="+pagesize+"&querytemplate=%27modifiedby:{User}%27&selectproperties=%27sitetitle%2cspsiteurl%2c%27&sortlist=%27lastmodifiedtime:descending%27&collapsespecification=%27spsiteurl%27",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
//pass reponse data to Success Handler
_cur.onQuerySucceeded(data);
},
error: function (error) {
_cur.onQueryFailed(error.sender, error.args);
}
});
}
//upon successful completion of the Ajax call, bind the result set to individual items array for display
this.onQuerySucceeded = function (sender, args) {
var results = sender.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
var data = {};
data.Items = [];
data.HasItems = true;
if(results.length > 0){
$.each(results, function(index, item){
var listItemInfo =
{
"Title": item.Cells.results[2].Value, //gets the sitetitle from the result set
"Link": item.Cells.results[3].Value //gets the url from the result set
};
debugger;
data.Items.push(listItemInfo);
} );
} else {
Akumina.AddIn.Logger.WriteInfoLog('No Results Returned');
data.HasItems = false;
}
//bind data to output
if (!_cur.SiteRequest.EditMode) {
_cur.BindTemplate(_cur.SiteRequest.DisplayTemplateUrl, data, _cur.SiteRequest.SenderId);
}
}
this.onQueryFailed = function (sender, args) {
Akumina.AddIn.Logger.WriteErrorLog('SP Site List Request Failed\n' + args.get_message() + '\n' + args.get_stackTrace());
}
}
}
//end SP Sites Widget
Function | Description |
---|---|
Akumina.AddIn.SPSites | Defines the Widget SPSites Addin and functions. |
this.GetPropertyValue | Retrieves the property value for a defined property. |
this.SetDefaultsProperties | Sets the default properties for the widget. |
this.Init | Called by the framework to instantiate the widget, passing in properties from the site. Binds view and widget name for this widget. |
this.Prerender | What is displayed while widget is rendering. We use subscriptions to call the this.Render function when loading is complete and this.RefreshWidget when the widget is updated. |
this.Render | Calls the method to retrieve the list of sites from SharePoint. |
this.RefreshWidget | Refreshes the widget display when updated. |
this.BindTemplate | Binds the template to the widget. |
this.RetrieveListItems | Performs the Ajax call to SharePoint passing in the user context and & of items to return. On Success, it will call onQuerySucceeded function passing in response data, otherwise it will call onQueryFailed passing in error information. |
this.onQuerySucceeded | If the previous Ajax call succeeded, this function will get called and will be passed the list of SharePoint sites. |
this.onQueryFailed | If the previous Ajax call failed, this function will get called and will be passed the corresponding error. We log it to the Akumina Log. |
The most important part of this widget JavaScript is its ability to execute an Ajax call to SharePoint. The JSON response will include a list of SharePoint sites specific to the logged in user. The querystring parameters can be changed to tune your results. In the RetrieveListItems function, we find the following Ajax call using the following parameters below:
url: siteurl + "/_api/search/query?querytext=%27*%27&rowlimit="+pagesize+"&querytemplate=%27modifiedby:{User}%27&selectproperties=%27sitetitle%2cspsiteurl%2c%27&sortlist=%27lastmodifiedtime:descending%27&collapsespecification=%27spsiteurl%27"
The following are parameters passed to SharePoint via the querystring:
Parameter | Description |
---|---|
querytext | string containing our search, in this case it is * |
rowlimit | the number of results to pass, configured by the widget property |
querytemplate | modifiedby: {User} - only results modified by our currently logged in user |
selectproperties | what properties we want to retrieve from SharePoint - defaults are sitetitle & spsiteurl |
sortlist | sort list by last modified |
collapsespecification | collapse results based upon spsiteurl |
Widget Property | Description |
---|---|
pagesize | determines the number of results to show in the list |
displaytemplateurl | overrides display template via a url |
The view markup displays the result set in an unordered list, iterating over each item in the result set and displaying the title and a link to that SharePoint website.
{{#if HasItems}}
<div class="ia-announcements">
<ul>
{{#Items}}
<li>
<h4 class="ia-announcement-title"><a href="{{Link}}">{{Title}}</a></h4>
</li>
{{/Items}}
</ul>
</div>
{{else}}
<h2>No Items</h2>
{{/if}}
Next we will focus on deploying our custom widget to Akumina.
Follow the steps below to create the widget definition, widget view, and then upload and utilize your new widget in the system.
- Download digitalworkplace.custom.js from the “/Style Library/DigitalWorkplace/JS” folder within SharePoint
- Paste the Widget Definition within digitalworkplace.custom.js
- Upload the updated digitalworkplace.custom.js to the “/Style Library/DigitalWorkplace/JS” folder within SharePoint
- Create a new HTML file in your editor of choice. Copy-and-paste the Widget View HTML into the file and save as sites-list.html.
- Copy the sites-list.html file to /Style Library/DigitalWorkplace/Content/Templates/SPSites
- In the Management Apps tab of Interchange, click on the View Manager. Click “Add New”. In the left pane navigate to “/DigitalWorkplace/Content/Templates/SPSites” for the folder path. Click “Choose File”, navigate to your custom template (sites-list.html). Click “Save”.
- In the Management Apps tab of Interchange, click on the Widget Manager app. Then click on Add Widget. Create your widget with the values in the Widget Definition – Object Model section. Click Save & Exit
- In the Manage Widgets window, find SPSitesList and click its ‘View Widget Definitions’ button. Then click on ‘Add New’. Create your widget instance with the values in the Widget Manager – Widget Instance section. Click Save & Exit
- Copy the Widget Snippet of your Widget Instance for use later when adding to a page
- Create a new Page in SharePoint or edit an existing Page.
- Paste the snippet into a Content Editor Web Part on a page within the site. Publish the page.
- Flush your cache by clicking on the Akumina icon in the left rail, clicking the refresh icon, then clicking “Refresh All Cache”
- Refresh the page. You will see your Flickr Widget