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