SharePoint with Angular

I have been working on a SharePoint Intranet project that uses AngularJS. Here is some code sample for using Angular with SharePoint.  The sample code below basically is:

  • Getting a items from a list
  • Searching for items with Title containing "Test"
  • Display the results from the list and search onto the page


I have the following files

  • appFactory.js - for handling the services call to SharePoint using both JSOM and REST
  • app.js - the main application logic (including a custom directive)
  • list.html - the html template for my directive

The files contain are pasted below.

***appFactory.js*********************************
var spServices = angular.module('spServices', []);

//Factory with SharePoint call using JSOM
spServices.factory('SPRestSearchFactory', ['$resource',
  function ($resource) {
      return $resource(_spPageContextInfo.siteAbsoluteUrl + "/_api/search/query/:searchtext", { searchtext: '@querytext' }, {
          query: {
              method: 'GET', isArray: false,
              headers: { "Accept": "application/json; odata=verbose", 'Content-Type': 'application/json;odata=verbose;' }
          }
      });
  }]);

spServices.factory('SPRestServicesFactory', function ($q) {

    var getListItems = function (url, listName, params) {
        var deferred = $q.defer();

        $.ajax({
            url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function (data) {
                // Returning the results
                deferred.resolve(data);
            },
            error: function (data) {
                //deferred.reject(sender, args);
            }
        });

        return deferred.promise
    };

    return {
        GetListItems: getListItems
    };
});


spServices.factory('SPServicesFactory', function ($q) {

    var getSearchResults = function (searchQuery, props, rowLimit) {
        var deferred = $q.defer();
        var clientContext = SP.ClientContext.get_current();

        var keywordQuery = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(clientContext);
        var queryText = searchQuery;

        keywordQuery.set_queryText(queryText);

        var properties = keywordQuery.get_selectProperties();
        for (i = 0; i < props.length; i++) {
            properties.add(props[i]);
        }
        keywordQuery.set_rowLimit(rowLimit);

        var searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(clientContext);
        searchResults = searchExecutor.executeQuery(keywordQuery);

        clientContext.executeQueryAsync(
        Function.createDelegate(this,
        function () { deferred.resolve(searchResults); }),
        Function.createDelegate(this,
        function (sender, args) { deferred.reject(sender, args); }));
        return deferred.promise;
    };
 
//Since client object model doesn't support update to user profile properties, we'll need to use the old //web services to get that done.
    var setUserProfile = function (accountName, propertyName, propertyValue) {
        var newData = '<?xml version="1.0" encoding="utf-8"?>'
                        + '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
                        + '<soap:Body>' + ' <ModifyUserPropertyByAccountName xmlns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService">'
                        + '  <accountName>' + accountName + '</accountName>'
                        + '  <newData>'
                       + '  <PropertyData>'
                       + '  <IsPrivacyChanged>false</IsPrivacyChanged>'
                       + '  <IsValueChanged>true</IsValueChanged>'
                       + '  <Name>' + propertyName + '</Name>'
                       + '  <Privacy>Public</Privacy>'
                       + '  <Values><ValueData><Value xsi:type="xsd:string">'
                            + propertyValue + '</Value></ValueData></Values>'
                       + '  </PropertyData>'
                        + '  </newData>'
                        + ' </ModifyUserPropertyByAccountName>'
                        + ' </soap:Body>'
                        + '</soap:Envelope>'
var deferred = $q.defer();

        $.ajax({
            url: '/_vti_bin/UserProfileService.asmx',
            beforeSend: function (xhr) {
                xhr.setRequestHeader("SOAPAction", "http://microsoft.com/webservices/SharePointPortalServer/UserProfileService/ModifyUserPropertyByAccountName")
            },
            type: "POST",
            async: false,
            dataType: "xml",
            data: newData,
            contentType: "text/xml; charset=\"utf-8\"",
            complete: function (xmlHttpRequest, status) {
                //do nothing
                deferred.resolve();
            },
            error: function (jqXHR, textStatus, errorThrown) {
                //deferred.reject(sender, args);
            }
        });

        return deferred.promise;
    };

//Get current user login name
    var getCurrentUser = function () {
        var deferred = $q.defer();
        var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + _spPageContextInfo.userId + ")";
        var requestHeaders = { "accept": "application/json;odata=verbose" };
        var loginName = "";

        $.ajax({
            url: requestUri,
            async: false,
            contentType: "application/json;odata=verbose",
            headers: requestHeaders,
            success: function (data, request) {
                try {
                    loginName = data.d.LoginName.split('|')[1].toString();
                    deferred.resolve(loginName);
                }
                catch (err) {
                    deferred.reject(sender, args);
                }

            },
            error: function (jqXHR, textStatus, errorThrown) { deferred.reject(sender, args); }
        });

        return deferred.promise;
    };

    return {
        getSearchResults: getSearchResults,
        GetCurrentUser: getCurrentUser,
        SetUserProfile: setUserProfile
    };
});

//Getting list items using REST
spServices.factory('SPRestServicesFactory', function ($q) {

    var getListItems = function (url, listName, params) {
        var deferred = $q.defer();

        $.ajax({
            url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function (data) {
                // Returning the results
                deferred.resolve(data);
            },
            error: function (data) {
                //deferred.reject(sender, args);
            }
        });

        return deferred.promise
    };

    return {
        GetListItems: getListItems
    };
});



****** app.js ********************************
var spApp = angular.module('spApp', ['spServices']);
spApp.directive('aymhiList', ['SPRestServicesFactory', function ($spRestServices) {
    return {
        restrict: 'E',
        transclude: true, // make parent scope available
        templateUrl: 'list.html',
        replace: true,
        link: function (scope, element, attributes) {          

            scope.getList = function () {

                $spRestServices.GetListItems(_spPageContextInfo.siteAbsoluteUrl, "Custom List", "?$orderby=Order").then(function (data) {
                    scope.items = data.d.results;
                });

                var props = ["Title", "Path"];
                $spSearch.getSearchResults("Title:Test", props, 30).then(function (data) {
                    scope.results = data.m_value.ResultTables[0].ResultRows;
                });
            };

            scope.getList();
        }
    };
}]);

***list.html***********************************************************
<div>
        <ul>
            <li ng-repeat="item in items" id="{{item.Id}}">{{item.Title}}</li>
        </ul>

        <div id="searchResultDiv">
            <ul>
                <li ng-repeat="result in results"><a href="{{result.Path}}">{{result.Title}}</a></li>
            </ul>
        </div>
</div>
       

Comments

Popular posts from this blog

SharePoint 2013 - Working with Display Template for Content Search Web Part

How to Customize MOSS Site Manager (Site Content and Structure Page)

Add spell check dictionary in SharePoint 2010, SharePoint 2013, and Office 365