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