I am writing this post to help myself and other fellows who are developers like me and are interested in developing SharePoint 2013 Apps.
In this post I am going to explain how I developed my BillTracker App for SharePoint 2013 using Javascript/CSOM for accessing SharePoint List Items using Repository and Knockout JS for displaying bills using MVVM patterns.
I am starting by showing high level architecture so it will make it easier to understand at first glance then project structure and code snippets.In this post I am going to explain how I developed my BillTracker App for SharePoint 2013 using Javascript/CSOM for accessing SharePoint List Items using Repository and Knockout JS for displaying bills using MVVM patterns.
Below is high level architecture:
And here is my project structure:
and here is repository implementation in javascript using CSOM:
window.Masood = window.Masood || {}; window.Masood.BillTracker = window.Masood.BillTracker || {}; window.Masood.BillTracker.Repositories = window.Masood.BillTracker.Repositories || {}; window.Masood.BillTracker.Repositories.SharePointRepository = function (context, web, listName) { //properties this.context = context; this.web = web; this.listName = listName; var listItems; var listItem; var dateFormat = 'dd-MMM-yyyy'; //collection for getAllItems this.Results = []; this.ErrorMessage; //result for getBill method this.Result; var clientSuccessCallback; var clientFailureCallback; this.getAllItems = function (sucCallback, failCallback) { //save the client's callback to variables //that will be used in getAllItemsSuccessCallback event clientSuccessCallback = sucCallback; clientFailureCallback = failCallback; //use CSOM to grab SharePoint items listItems = null; var oList = web.get_lists().getByTitle(listName); var camlQuery = new SP.CamlQuery(); //ste your CAML to filter items listItems = oList.getItems(camlQuery); context.load(listItems); context.executeQueryAsync(Function.createDelegate(this, getAllItemsSuccessCallback), Function.createDelegate(this, failureCallback)); }; function getAllItemsSuccessCallback() { var listItemInfo = ''; var listItemEnumerator = listItems.getEnumerator(); this.Result = null; this.Results = []; paymentDate = ''; while (listItemEnumerator.moveNext()) { var oListItem = listItemEnumerator.get_current(); //push your Item/Model to Results array } //call client's success callback clientSuccessCallback(); } }and here is the ViewModel that calls the repository to get all/filtered items:
window.Masood = window.Masood || {}; window.Masood.BillTracker = window.Masood.BillTracker || {}; window.Masood.BillTracker.ViewModels = window.Masood.BillTracker.ViewModels || {}; window.Masood.BillTracker.ViewModels.AllBillsViewModel = function (context, web) { //private variables var self = this; var repository = new window.Masood.BillTracker.Repositories.SharePointRepository(context, web, 'MyBills'); helper = new Helper(); var _totalAmount = 0; //observable properties those are bind to UI elements self.Items = ko.observableArray(); self.message = ko.observable(""); self.totalAmount = ko.observable(""); self.load = function () { self.message("Please wait, loading all your bills..."); repository.getAllItems(onSuccess, onFailure); }; function onSuccess() { //clear all items from observable collection self.Items.removeAll(); var allBills = repository.Results; //populate observable collection _totalAmount = 0; for (i = 0; i < allBills.length; i++) { var item = allBills[i]; self.Items.push(item); _totalAmount += parseFloat(item.Amount); } self.totalAmount(_totalAmount.toFixed(2)); self.message(""); } function onFailure() { alert('Something went wrong while fetching all your bills. Please contact administrator or email at mmasood@gmail.com'); self.message("Something went wrong while fetching all your bills. Please contact administrator or email at mmasood@gmail.com"); } }
And each .aspx or .html file has got its codebehind .js file
that glue ViewModel instance as shown below:
var context; var web; //this function is called when page is loaded and DOM //is ready function sharePointReady() { context = new SP.ClientContext.get_current(); web = context.get_web(); //create instance of AllBills ViewModel //and rest is taken care by KnockoutJs var viewModel = new window.Masood.BillTracker.ViewModels.AllBillsViewModel(context, web); //call load to fetch items from SharePoint //and populate all observable property and collection viewModel.load(); ko.applyBindings(viewModel); }
One last thing, before packaging, you need to minify all .js
files using Micrsoft Ajax Minifier tool.
That’s it. Hope it would help you to understand and
will help you to write better apps.