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 App Details Page Error

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

SharePoint 2013 Features Information List