SharePoint 2013: Use a List Template Model with the REST API
Introduction
This article describes how to use the List Template model with the REST API. The article's aim is to save you considerable time and effort when building a solution that uses the List Template model.
Please leave a comment if you have feedback on how to improve this article.
Model
TemplateModel = {
element: '',
listname: '',
url: '',
addurl: '',
editurl: '',
displayurl: '',
filtervalue: '',
filteronly: '&$filter=',
selectonly: '&$select=',
orderby: '',
orderbyonly: '&$orderby=',
toponly: '&$top=',
topandskip: '',
topcount: 7,
skipcount: 0,
typeofdata: '',
result_set: undefined,
callbackhandler: undefined,
pageelement: '',
listpageindex: new Array,
resettotalcount: false,
totalcount: 0,
init: function (pelement, cbhandler, pcountelement) {
TemplateModel.element = pelement;
TemplateModel.callbackhandler = cbhandler;
TemplateModel.pageelement = pcountelement;
TemplateModel.resettopandskip();
TemplateModel.resetfiltervalue();
},
load: function () {
TemplateModel.url = TemplateModel.listpageindex[TemplateModel.skipcount];
TemplateModel.getdatafromlist();
},
additem: function (dialogResult, returnValue) {
if (dialogResult == SP.UI.DialogResult.OK) {
TemplateModel.url = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'";
var rqheaders = {
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
}
var setdata = {
__metadata: { "type": TemplateModel.typeofdata },
Title: returnValue.Title
};
var senddata = JSON.stringify(setdata);
TemplateModel.createorupdateitem(senddata, rqheaders);
}
},
getbyId: function (id, phandler) {
TemplateModel.url = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items(" + id + ")?@target='" + hostweburl + "'";
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: TemplateModel.url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: phandler,
error: TemplateModel.errorHandler
}
);
},
updatebyId: function (dialogResult, returnValue) {
if (dialogResult == SP.UI.DialogResult.OK) {
var getetag = returnValue.etag;
TemplateModel.url = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items(" + returnValue.Id + ")?@target='" + hostweburl + "'";
var rqheaders = {
"content-type": "application/json;odata=verbose",
"Accept": "application/json; odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "MERGE",
"If-Match": getetag
}
var setdata = {
__metadata: { "type": TemplateModel.typeofdata },
Title: returnValue.Title
};
var senddata = JSON.stringify(setdata);
TemplateModel.createorupdateitem(dataString, rqheaders);
}
},
deletebyId: function (id) {
TemplateModel.url = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items(" + id + ")?@target='" + hostweburl + "'";
var requestHeaders = {
"Accept": "application/json; odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "DELETE",
"If-Match": "*"
};
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: TemplateModel.url,
contentType: "application/json; odata=verbose",
method: "POST",
headers: requestHeaders,
success: TemplateModel.reload,
error: TemplateModel.errorHandler
}
);
},
getdatafromlist: function () {
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: TemplateModel.url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: TemplateModel.onSuccess,
error: TemplateModel.errorHandler
}
);
},
createorupdateitem: function (data, rqheaders) {
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: TemplateModel.url,
contentType: "application/json;odata=verbose",
method: "POST",
body: data,
headers: rqheaders,
success: TemplateModel.reload,
error: TemplateModel.errorHandler
}
);
},
onSuccess: function (data) {
var jsonObject = JSON.parse(data.body);
if (TemplateModel.resettotalcount && TemplateModel.pageelement != null) {
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1) + 'f').hide();
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1) + 'b').hide();
$(TemplateModel.pageelement).text('1');
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1)).text('1');
}
if (jsonObject.d.results != undefined) {
TemplateModel.result_set = jsonObject.d.results;
if (jsonObject.d.__next != null) {
TemplateModel.listpageindex[TemplateModel.skipcount + 1] = jsonObject.d.__next;
if (TemplateModel.resettotalcount) {
var removPage = TemplateModel.listpageindex[TemplateModel.skipcount];
removPage = removPage.replace(TemplateModel.topandskip, "");
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url: removPage,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: TemplateModel.onFilterCountSuccess,
error: TemplateModel.errorCountHandler
}
);
TemplateModel.resettotalcount = false;
}
}
}
else if (jsonObject.d != undefined) {
TemplateModel.result_set = jsonObject.d;
}
TemplateModel.callbackhandler(TemplateModel);
},
errorHandler: function (data, errorCode, errorMessage) {
alert("Unable to load model: " + errorMessage);
},
errorCountHandler: function (data, errorCode, errorMessage) {
alert("Unable to get count for model: " + errorMessage);
},
onFilterCountSuccess: function (data) {
var jsonObject = JSON.parse(data.body);
if (jsonObject.d.results != undefined) {
TemplateModel.totalcount = jsonObject.d.results.length;
var pagenum = Math.floor(TemplateModel.totalcount / TemplateModel.topcount);
if (TemplateModel.totalcount % TemplateModel.topcount > 0) {
pagenum += 1
}
if (pagenum > 1) {
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1) + 'f').show();
}
else {
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1) + 'f').hide();
}
$(TemplateModel.pageelement).text(pagenum == 0 ? 1 : pagenum);
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1)).text('1');
$(TemplateModel.pageelement.substring(0, TemplateModel.pageelement.length - 1) + 'b').hide();
}
},
reload: function (data) {
TemplateModel.resettopandskip();
TemplateModel.resettotalcount = true;
TemplateModel.load();
},
settopandskip: function (ptop) {
TemplateModel.topandskip = TemplateModel.toponly + (TemplateModel.topcount);
TemplateModel.skipcount = ptop - 1;
},
seteqfilter: function (column, data) {
TemplateModel.filtervalue = TemplateModel.filteronly + column + " eq '" + data + "'";
TemplateModel.skipcount = 0;
TemplateModel.resettotalcount = true;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
setmultiplefilter: function (data) {
TemplateModel.filtervalue = TemplateModel.filteronly + data;
TemplateModel.skipcount = 0;
TemplateModel.resettotalcount = true;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
setorderby: function (column) {
TemplateModel.orderby = TemplateModel.orderbyonly + column;
TemplateModel.skipcount = 0;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
resetorderby: function (column) {
TemplateModel.orderby = TemplateModel.orderbyonly + 'Title';
TemplateModel.skipcount = 0;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
resettopandskip: function () {
TemplateModel.topandskip = TemplateModel.toponly + TemplateModel.topcount;
TemplateModel.skipcount = 0;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
resetfiltervalue: function () {
TemplateModel.filtervalue = '';
TemplateModel.orderby = TemplateModel.orderbyonly + 'Title';
TemplateModel.skipcount = 0;
TemplateModel.resettotalcount = true;
TemplateModel.listpageindex[TemplateModel.skipcount] = appweburl + svc_apiurl + svc_sitecollurl + "lists/getByTitle('" + TemplateModel.listname + "')/items?@target='" + hostweburl + "'" + TemplateModel.orderby + TemplateModel.topandskip + TemplateModel.filtervalue;
},
displayaddform: function (pclientid) {
var args1 = {
command: 'add'
};
var options = {
url: TemplateModel.addurl,
showClose: true,
title: 'Title',
dialogReturnValueCallback: TemplateModel.additem,
args: args1
};
SP.UI.ModalDialog.showModalDialog(options);
},
displayeditform: function (id) {
TemplateModel.displayobjbyid(id, 'edit');
},
displayviewform: function (id) {
TemplateModel.displayobjbyid(id, 'view');
},
displayobjbyid: function (id, pcommand) {
var objtosend = null;
if (TemplateModel.result_set != undefined) {
objtosend = $.grep(TemplateModel.result_set, function (item, i) {
return item.Id == id;
});
}
if (objtosend != null) {
var args1 = {
command: pcommand,
sendobjinfo: objtosend
};
var options = {
url: TemplateModel.editurl,
showClose: true,
title: 'Title',
dialogReturnValueCallback: TemplateModel.updatebyId,
args: args1
};
SP.UI.ModalDialog.showModalDialog(options);
}
}
};
Setting the Page Elements
<a href="javascript:refreshModel(TemplateModel);">Refresh</a>
<a id="splistpageb" href="javascript:pagebackGrid(TemplateModel);">Page Down</a>
<span id="splistpage">1</span> of <span id="splistpaget">1</span>
<a id="splistpagef" href="javascript:pageupGrid(TemplateModel);">Page Up</a></li>
<div id="divlist"></div>
Accessing the Model
Before we can access the model, we need to set a few variables and add scripts to our page. If you have created a separate .js file for the model, then include the link.
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.8.1.min.js"></script>
<script type="text/javascript" src="/_layouts/15/SP.UI.Dialog.js"></script>
<script type="text/javascript" src="../Scripts/templatemodel.js"></script>
<script type="text/javascript" src="../Scripts/jsrender.min.js"></script>
var hostweburl;
var appweburl;
var scriptbase;
var svc_apiurl = "/_api/SP.AppContextSite(@target)/";
var svc_sitecollurl = "web/"; //"site/rootweb/";
var temp_list;
var sortUp = false;
$(function () {
hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
temp_list = TemplateModel;
temp_list.init("#divlist", loadtemplatedataingrid, "#splistpaget");
temp_list.load();
});
function getQueryStringParameter(paramToRetrieve) {
var params = document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
function loadtemplatedataingrid(model) {
$(model.element).empty();
var tableHeader = "<thead><tr><td width=\"40%\"><a href=\"javascript:sortResults('Title');\">Title</a></td></thead>";
var ntable = $("<table>", { id: "customTable", width: "100%", border: "0", cellspacing: "0", cellpadding: "0" }).append(tableHeader);
var templ = "<tr><td>{{>Title}}</td></tr>";
$.templates({ "tmplTable": templ });
ntable.append($.render.tmplTable(model.result_set));
$(model.element).append(ntable);
}
Passing and Retrieving Items to Modal Pop-up
The model allows passing the item to another page and show it in a modal pop-up window. When accessing value on the page and passing value back from the page:
var getpassedargs;
var etagvalue = 0;
var itemid = 0;
$(function () {
getpassedargs = window.frameElement.dialogArgs;
if (getpassedargs.command == 'add') {
$('#cmdedit').attr('disabled', true);
$('#cmdedit').removeClass('popup-edit').addClass('popup-edit-nohover');
}
else {
if (getpassedargs.command == 'edit') {
$('#cmdedit').attr('disabled', true);
$('#cmdedit').removeClass('popup-edit').addClass('popup-edit-nohover');
}
else{
$('.unlock').attr('disabled', true);
}
var setobj = getpassedargs.sendobjinfo;
etagvalue = setobj[0].__metadata.etag;
itemid = setobj[0].Id;
$('#textboxtitle').val(setobj[0].Title);
}
$('#cmdedit').click(function () {
$('#cmdedit').attr('disabled', true);
$('#cmdedit').removeClass('popup-edit').addClass('popup-edit-nohover');
$('.unlock').removeAttr('disabled');
});
document.onsubmit = function () {
var result = SP.UI.DialogResult.OK;
var value = {
Id: itemid,
Title: 'Title',
etag: etagvalue
};
SP.UI.ModalDialog.commonModalDialogClose(result, value)
};
$('#cmdcancel').click(function () {
var result = SP.UI.DialogResult.cancel;
var value = '';
SP.UI.ModalDialog.commonModalDialogClose(result, value)
});
});
<input type="submit" id="cmdsave" value="Save" />
<input type="button" id="cmdcancel" value="Cancel"/>
Paging the Model
function pagebackGrid(model) {
var pcurrent = $(model.pageelement.substring(0, model.pageelement.length - 1)).text();
var pmax = $(model.pageelement).text();
pcurrent--;
$(model.pageelement.substring(0, model.pageelement.length - 1)).text(pcurrent);
model.settopandskip(pcurrent);
model.load();
if (pcurrent == 1) {
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'b').hide();
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'f').show();
}
else {
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'b').show();
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'f').show();
}
}
function refreshModel(model) {
model.resettopandskip();
model.load();
$(model.pageelement.substring(0, model.pageelement.length - 1)).text('1');
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'b').hide();
}
function pageupGrid(model) {
var pcurrent = $(model.pageelement.substring(0, model.pageelement.length - 1)).text();
var pmax = $(model.pageelement).text();
pcurrent++;
$(model.pageelement.substring(0, model.pageelement.length - 1)).text(pcurrent);
model.settopandskip(pcurrent);
model.load();
if (pcurrent == pmax) {
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'f').hide();
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'b').show();
}
else {
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'b').show();
$(model.pageelement.substring(0, model.pageelement.length - 1) + 'f').show();
}
}
Sorting the Model
function sortResults(pcolumn) {
if (sortUp) {
temp_list.setorderby(pcolumn);
sortUp = false;
}
else {
temp_list.setorderby(pcolumn + ' desc');
sortUp = true;
}
temp_list.load();
}
See Also
- How to: Complete basic operations using JavaScript library code in SharePoint 2013
- Use OData query operations in SharePoint REST requests
- Publish apps for SharePoint
- Boris Moore - JSRender (GitHub)