Here we will explore pure Angular JS directives (without using jQuery or other frameworks) by accessing the SharePoint REST API. The example I have taken is accessing the folder and files from the library by the following two events:
- On page load, accessing all the folders from the library and storing them in a dropdown box.
- On button click event, populate the files in a table based on the selected folder from the dropdown.
So, we will make two requests to the server and render it in a page.
The following will apply a Folder collection to the Dropdown list.
HTML Snippet:
- <select id="lib-folder" ng-model="libFolders" ng-options=" fldr as fldr.Title for fldr in Folders" >
- <option value="">--Select Folder--</option>
- </select>
ng-options: This directive is an alternative to the ng-repeat directive. This is used to dynamically generate the list of <option> elements for the select element using the array “$scope.Folders” obtained as the result of the SharePoint REST API.
fldr.Title This is the retrieved folder name that is rendered as a value to the dynamically generated <option> element to the dropdown.
Note: If you have not used “<option value=””>--Select Folder--</option>” code, the empty option will be dynamically generated when populating the folders to the dropdown.
Script Snippet:
- $http({
- method: "GET", url:_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentLibrary')/items?$select=Id,Title ,FileDirRef,FileRef,FSObjType&$filter=FSObjType%20eq%201",
- headers: {"Accept":"application/json;odata=verbose"}
- }
- ).success(function(data, status, headers, config){
- $scope.Folders = data.d.results;
- $scope.libFolders = $scope.Folder[0];
- }).error(function (data, status, headers, config){
- });
_spPageContextInfo.webAbsoluteUrl :_spPageContextInfo is very useful when writing JavaScript code on the SP site. This has a webAbsoluteUrl property that returns the web URL that we use to generate the REST API request URL.
REST API URL: fetches the items with the values for the following fields filtered by folder from the “DocumentLibrary” library.
_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentLibrary')/items
View Fields:
- $select=Id,Title ,FileDirRef,FileRef,FSObjType
Filter:
- $filter=FSObjType%20eq%201
Returns the items, if the item type is 1 (folder).
- $scope.Folders = data.d.results
The successful response assigns the folder collection array to the scope variable $scope.Folders.
The ng-options directive uses this array variable and dynamically generates the options.
- $scope.libFolders = $scope.Folders[0]
Assign the first item of Folder collection array to the default value for dropdown.
Populate files based on the selected Folder:
Now we are done with the rendering of the folder list to the dropdown. To invoke the event to request the files for the selected folder, we have a button and the function “btnGetFiles()” as in the following:
<input type="button" value="Get Files" ng-click="btnGetFiles()"/>
HTML Snippet:
-
- <table width="100%" cellpadding="10" cellspacing="2" class="files-table">
- <thead>
- <tr>
- <th>Title</th>
- <th>Author</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="file in Files">
- <td><a href="{{file.ServerRelativeUrl}}">{{file.Name}}</a></td>
- <td>{{file.Author.Title}}</td>
- </tr>
- </tbody>
- </table>
Script Snippet:
- $scope.btnGetFiles = function()
- {
- var selectedFolder = $scope.libFolders.FileRef+"/";
- var resturl = _spPageContextInfo.webAbsoluteUrl+"/_api/web/getfolderbyserverrelativeurl('"+selectedFolder+"')/files?$select=Name,Author/Title&$expand=Author/Title";
- $http(
- {
- method: "GET",
- url:resturl,
- headers: {"Accept":"application/json;odata=verbose"}
- }
- ).success(function(data, status, headers, config){
- $scope.Files = data.d.results;
- }).error(function (data, status, headers, config){
- });
- }
$scope.libFolders.FileRef : Returns the dropdown's selected value.
REST API URL
$expand: this option has the ability to retrieve the related properties. This is used to retrieve the author name using a single request instead of sending multiple requests.
$expand=Author/Title: file.Author.Title is to be added in HTML to retrieve the expanded value.
The successful result is stored in the scope variable “$scope.Files” and this is used in a table element to dynamically generate the rows because of the ng-repeat directive.
ng-show
If there is no files retrieved for the folder, use the ng-show directive with the condition to show the proper message as in the following:
<p ng-show="!Files.length">There are no files available under this folder.</p>
Here is the full code:
- <style type="text/css">
- .files-table th{ background-color:#ddd; border:2px solid #fff; text-align:left}
- .files-table td{ background-color:#eee; border:2px solid #fff;}
- .web-heading{ padding:2px;}
- </style>
-
- <script type="text/javascript" src="/siteassets/angular.min.js"></script>
- <div ng-app="spng-App">
- <h2 class="web-heading">Folder and Files</h2>
- <div ng-controller="spng-WebCtrl">
- <select id="lib-folder" ng-model="libFolders" ng-options="fldr as fldr.Title for fldr in Folders" >
- <option value="">--Select Folder--</option>
- </select>
- <input type="button" value="Get Files" ng-click="btnGetFiles()"/>
-
- <table width="100%" cellpadding="10" cellspacing="2" class="files-table">
- <thead>
- <tr>
- <th>Title</th>
- <th>Author</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="file in Files">
- <td><a href="{{file.ServerRelativeUrl}}">{{file.Name}}</a></td>
- <td>{{file.Author.Title}}</td>
- </tr>
- </tbody>
- </table>
- <p ng-show="!Files.length">There are no files available under this folder.</p>
- </div>
- </div>
- <script type="text/javascript">
- var spApp= angular.module('spng-App', []);
- spApp.controller('spng-WebCtrl', function($scope, $http){
-
- //Controller load event to append the choices with folder value to the dropdown
- $http({
- method: "GET",
- url:_spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('DocumentSetLibrary')/items?$select=Id,Title,FileLeafRef,FileDirRef,FileRef,FSObjType&$filter=FSObjType%20eq%201",
- headers: {"Accept":"application/json;odata=verbose"}
- }
- ).success(function(data, status, headers, config){
- //Store the folder collections to the Folders scope variable
- $scope.Folders = data.d.results;
- //Set the default value to the dropdown
- $scope.libFolders = $scope.DocumentSets[0];
- }).error(function (data, status, headers, config){
- });
-
- //Button click event to populate the files in table
- $scope.btnGetFiles = function(){
- //Get the selected folder from the select element
- var selectedFolder = $scope.libFolders.FileRef+"/";
- var resturl = _spPageContextInfo.webAbsoluteUrl+"/_api/web/getfolderbyserverrelativeurl('"+selectedFolder+"')/files?$select=Name,Author/Title&$expand=Author/Title";
- $http({
- method: "GET",
- url:resturl,
- headers: {"Accept":"application/json;odata=verbose"}
- }
- ).success(function(data, status, headers, config){
- //Store the filecollection for the folder to the Files scope variable
- $scope.Files = data.d.results;
- }).error(function (data, status, headers, config){
- });
- }
- });
- </script>
OUTPUT:Still we have many options available in Angular JS and we will continue our exploration in this area. We will welcome the new technologies to ease the coding. Happy learning.