Background
Our team had someone come to speak to us about AngularJS,
however, they only gave an
overview of the framework, with no examples.  Since I had started reprogramming our team
SharePoint site to utilize MS SharePoint REST services, I decided to see if I
could leverage AngularJS also.
I decided to start easy and create a Proof of Concept before
utilizing it on my app.  So, I decided to
create a module what would search a list on my SharePoint site and create a link to our internal scorecard and create a link to another corresponding scorecard on another SharePoint site, given a particular project ID.  
The very simple interface would look like this:
The value that will be returned will be the name of the project
and two links, one to the EPP Scorecard and one to our internal scorecard.
The Point
The first thing you do once you create your .aspx page in
SharePoint designer is to add the reference to AngularJS.  I store my plugins, frameworks and tools to
one library that I call jsandjquerystuff under our SharePoint site for easier
access:
<script type="text/javascript" src="http://xxx.sharepoint.com/.../
jsandjquerystuff/angular.min.js"></script>
Angular Part
AngularJS is a JavaScript implementation of the
Model-View-Controller architecture which is a way of separating internal representation
of data from the presentation and that is all I will say about that. Let’s get
to the good stuff.  Now the reason I
mentioned the nerdy stuff above is because it will help explain why some
AngularJS functions the way it does.  
With the added code from the AngularJS framework come
additional attributes for HTML tags, namely the following:
·       
ng-app: Defines an application in a <div/>
o   <div ng-app="myApp" ng-controller="myCtrl">
·       
ng-controller: Defines the controller (think of
them like buttons, input fields, etc on a page)
o   <div ng-app="myApp" ng-controller="myCtrl">
·       
ng-model: binds the value of a field to a value
defined in an <input/> tag
o  
<input type="text" ng-model="search">
The Angular View/Model
| 
<!-- (1) Create the controller --> 
<div ng-app="myApp" ng-controller="myCtrl"> 
<!-- (2) Serves as the model. Binds prjID
  with whatever is provided in the input variable --> 
<p>Project ID:<input type="text" ng-model="search"></p> 
<button ng-click="myFunc()">Search</button> 
</div> | 
The first <div/> ties the
  app to the controller and further binds the value typed into the textbox to
  the variable ‘search’. 
When the button is clicked it
  calls a JavaScript function called ‘myFunc()’. | 
| 
The HTML produces this textbox and
  prompt. | |
| 
<div> 
Project Name:
  {{pname}} <a target="_blank" "id="int" ng-href="{{fullLocInt}}">Internal</a> <a target="_blank" id="epp" ng-href="{{fullLocEpp}}">EPP</a> 
</div> | 
Values returned from the
  controller are placed into the ‘placeholders’ designated through the double
  braces: 
{{expression}} 
As can be seen by the example to
  the left, the expression can be displayed or used to hold data for other
  purposes. In this example, they are used to create a hyperlink. | 
| 
The HTML produces this
  placeholder. When the program is run, the returned project name will follow
  the ‘Project Name:’ and ‘Internal’ and ‘EPP’ will both be hyperlinks to the
  respective scorecards. | 
The Angular Controller/SharePoint REST Services
Now for the meat of the matter, how do we get the scorecards?  Well, honestly that part is rather easy. Once
I have the scorecard from our internal site, I can easily create the link to
the EPP scorecard.  So, I’m really just
searching one list.  That is accomplished
this way:
| 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.controller('myCtrl',  
        function($scope, $http)
  //$scope binds HTML and
  JavaScript | $http: makes request to server and returns response. 
        { 
        $scope.myFunc=function()  
        { 
            $http({ 
                method: "GET", 
                url:  
"
  http://xxx.sharepoint.com/.../
  _api/web/lists/getbytitle('PotentialProjectsLOE')/items?$filter=ProjectID eq
  '" +
  $scope.search + "'", 
                headers: { "accept":"application/json;odata=verbose"}  
                })//end http 
                .then( 
                function mysuccess(data,
  status, xhr) 
                {  
                        if (data.data.d.results.length==0) 
                        { 
                            alert("Please enter a VALID
  Project ID."); 
                        } 
                        else 
                        { 
                        $scope.pname=data.data.d.results[0].Title; 
                        $scope.intid=data.data.d.results[0].ID; 
                        $scope.eppid=data.data.d.results[0].EPPID; 
                        $scope.fullLocInt="https://bcbsnc.sharepoint.com/sites/global/ISBA_ProductDelivery/claimacq/Lists/PotentialProjectsLOE/Item/displayifs.aspx?ID=" + $scope.intid;                         
                        $scope.fullLocEpp="
  http://xxx.sharepoint.com/.../
  Project/Lists/Project%20Status/item/displayifs.aspx?ID=" + $scope.eppid; 
                        } 
                }, 
                function epicfail(data,
  status, xhr) 
                { 
                    alert("Well...that
  sucked.  It didn't work."); 
                }); 
        } 
        });//end controller 
</script> | 
As I stated before, the
  variable ‘search’ holds the value typed in by the user into the Project
  ID.  This is where we put that variable
  to work. 
The SharePoint service
  I used for this effort was the ‘getbyTitle’ service.  You simply pass the name of the list and
  optionally any values you wish to use to filter the results: 
"
  http://xxx.sharepoint.com/.../
  _api/web/lists/getbytitle('PotentialProjectsLOE')/items?$filter=ProjectID eq
  '" +
  $scope.search + "'" 
This tells the service
  to search the PotentialProjecsLOE list and return any item that has the
  project ID entered by the user in the ‘search’ variable. If it finds the
  item, it places the Title, ID and EPPID into variables in the $Scope object.
  The project name is placed in pname. I also created the variables fullLocInt to represent the link to the internal scorecard and fullLocEPP to represent the link to the EPP scorecard. | 
| 
<div> 
Project Name:
  {{pname}} <a target="_blank" "id="int" ng-href="{{fullLocInt}}">Internal</a> <a target="_blank" id="epp" ng-href="{{fullLocEpp}}">EPP</a> 
</div> | 
Pname, fullLocInt and
  fullLocEPP are then returned to the View. | 
|  | 
$Scope is a double
  agent. $Scope binds the HTML and the JavaScript and is available to both the
  controller and the view.  Basically, it
  is the Oracle of the app, it knows all. It holds the information returned by
  the controller.   
Let’s take a peek behind
  the scenes, I’ve turned on the developer tools to see what happens when we
  enter data into the textbox and hit ‘Search’. 
$Scope holds the value
  that was entered: 
As well as the result
  returned by the SharePoint web service: 
It also holds the
  variables that were created and placed into the fullLocEpp and fullLocINT
  variables. | 
Full Code
Here is the full code in all of its ‘copy and paste’-able
glory.  AngularJS does not have much of a
learning curve and if you really want to learn it, W3Schools introduction and
coverage is very good. One thing to mention is that AngularJS 1.0 is very
different from AngularJS 2.0.  I made the
mistake of following some information from a forum on how to build my
controller call only to have it repeatedly blow up.  After reverting back to W3Schools example, I
realized that the version represented on the forum was version 1.0 not version
2.0, so be careful of that and stick with the W3Schools stuff, it is most up to
date.
| 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML
  1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<%@ Page
  Language="C#" %> 
<%@ Register
  tagprefix="SharePoint"
  namespace="Microsoft.SharePoint.WebControls" assembly="Microsoft.SharePoint,
  Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<html> 
<head runat="server"> 
<meta name="WebPartPageExpansion" content="full" /> 
<script type="text/javascript" src="http://xxx.sharepoint.com/.../
  jsandjquerystuff/angular.min.js"></script> 
<script src=" http://xxx.sharepoint.com/.../
  jsandjquerystuff/jquery.js" type="text/javascript"></script> 
<!--script
  type="text/javascript"
  src="welcomeBanner.js"></script--> 
<title>Claims Acquisition Level Of Effort Tool 3.0</title> 
</head> 
<body> 
<!-- (1) Create the controller --> 
<div ng-app="myApp" ng-controller="myCtrl"> 
<!-- (2) Serves as the model. Binds prjID
  with whatever is provided in the input variable --> 
<p>Project ID:<input type="text" ng-model="search"></p> 
<button ng-click="myFunc()">Search</button> 
<div> 
Project Name:
  {{pname}} <a target="_blank" "id="int" ng-href="{{fullLocInt}}">Internal</a> <a target="_blank" id="epp" ng-href="{{fullLocEpp}}">EPP</a> 
</div> 
</div> 
<script type="text/javascript"> 
var app = angular.module('myApp', []); 
app.controller('myCtrl',  
        function($scope, $http)
  //$scope binds HTML and
  JavaScript | $http: makes request to server and returns response. 
        { 
        $scope.myFunc=function()  
        { 
            $http({ 
                method: "GET", 
                url:  
"
  http://xxx.sharepoint.com/.../
  _api/web/lists/getbytitle('PotentialProjectsLOE')/items?$filter=ProjectID eq
  '" +
  $scope.search + "'", 
                headers: { "accept":"application/json;odata=verbose"}  
                })//end http 
                .then( 
                function mysuccess(data,
  status, xhr) 
                {  
                        if (data.data.d.results.length==0) 
                        { 
                            alert("Please enter a VALID
  Project ID."); 
                        } 
                        else 
                        { 
                        $scope.pname=data.data.d.results[0].Title; 
                        $scope.intid=data.data.d.results[0].ID; 
                        $scope.eppid=data.data.d.results[0].EPPID; 
                        $scope.fullLocInt="https://bcbsnc.sharepoint.com/sites/global/ISBA_ProductDelivery/claimacq/Lists/PotentialProjectsLOE/Item/displayifs.aspx?ID=" + $scope.intid;                         
                        $scope.fullLocEpp="
  http://xxx.sharepoint.com/.../
  Project/Lists/Project%20Status/item/displayifs.aspx?ID=" + $scope.eppid; 
                        } 
                }, 
                function epicfail(data,
  status, xhr) 
                { 
                    alert("Well...that
  sucked.  It didn't work."); 
                }); 
        } 
        });//end controller 
</script> 
</body> 
</html> | 





 
No comments:
Post a Comment