Experimenting with AngularJS inside a SharePoint Visual Web Part
One day, I was having breakfast with a JavaScript guru buddy of mine and I asked him, what is the latest development trend on the web these days? One of the things he mentioned was AngularJS by Google. That got me thinking... can I use this in SharePoint some how? Well, outlined below is my little experiment with AngularJS inside a SharePoint Visual Web Part.
Start a new Visual Web Part project
I'll be deploying my project to SharePoint 2013, so here is a screenshot of the Visual Studio 2012 New Project wizard. I'll be deploying the project as a farm solution because I'll need to deploy some JavaScript files to the LAYOUTS directory.
Once the project is ready, there should a file called VisualWebPart1.ascx created. This is where all the magic happens. Lets add 'Hello World' to it, and deploy.
VisualWebPart1.ascx Hello World
[code lang="csharp"]
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="VisualWebPart1.ascx.cs" Inherits="MyFirstVisualWebPart.VisualWebPart1.VisualWebPart1" %>
Hello World
[/code]
Add Web Part to Page
Add the Visual Web Part to a Page. If you see Hello World, then we are ready to begin the real experiment.
Beginning of the AngularJS experiment
My Web Part is going to be a simple form with a few questions and a text box for entering the answers. Answers get saved to a SharePoint list via JavaScript Object Model (JSOM).
The HTML
[code lang="html"]
<h1>My First Visual WebPart featuring Angular.js</h1>
<div ng-app>
<div ng-controller="QuestionnaireCtrl">
<ol>
<li ng-repeat="question in questions">
<span>{{question.text}}</span>
<br />
<input type="text" ng-model="question.answer"/>
</li>
</ol>
<input type="submit" value="Submit" ng-click="addAnswers($event)"/>
</div>
</div>
[/code]
Here I am initializing the AngularJS App on a div with the ng-app tag. Then I have a ng-controller called QuestionnaireCtrl which contains a bunch of questions that I loop through using ng-repeat.
The JavaScript
[code lang="javascript"]
var siteUrl = "<%= SPContext.Current.Web.Url %>";
function QuestionnaireCtrl($scope) {
$scope.questions = [
{ text: 'How would you like your eggs done?', answer: "" },
{ text: 'What kind of bread would you like?', answer: "" },
{ text: 'What kind of drink would you like?', answer: "" }
];
$scope.addAnswers = function ($event) {
$event.preventDefault();
var clientContext = new SP.ClientContext(siteUrl);
var web = clientContext.get_web();
var list = web.get_lists().getByTitle('FoodQuestions');
_.each($scope.questions, function (question, i) {
// create the ListItemInformational object
var listItemInfo = new SP.ListItemCreationInformation();
// add the item to the list
var listItem = list.addItem(listItemInfo);
// Assign Values for fields
listItem.set_item('Question', question.text);
listItem.set_item('Answer', question.answer);
listItem.set_item('Title', 'Question ' + (++i));
listItem.update();
});
clientContext.executeQueryAsync(
Function.createDelegate(this, onQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);
};
onQuerySucceeded = function () {
alert('Thank you, have a nice day.');
var questions = $scope.questions;
_.each(questions, function (question) {
question.answer = "";
});
$scope.$apply();
}
onQueryFailed = function (sender, args) {
alert('Request failed. ' + args.get_message() + 'n' + args.get_stackTrace());
}
}
[/code]
In the JavaScript, I hard coded 3 questions. Then I have a click event handler that triggers $scope.addAnswers, which will save the answers to my questions into a SharePoint list.
VisualWebPart1.ascx final product
[code lang="html"]
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="VisualWebPart1.ascx.cs" Inherits="MyFirstVisualWebPart.VisualWebPart1.VisualWebPart1" %>
<script src="/_layouts/15/MyFirstVisualWebPart/underscore-min.js"></script>
<script src="/_layouts/15/MyFirstVisualWebPart/angular.min.js"></script>
<script>
var siteUrl = "<%= SPContext.Current.Web.Url %>";
function QuestionnaireCtrl($scope) {
$scope.questions = [
{ text: 'How would you like your eggs done?', answer: "" },
{ text: 'What kind of bread would you like?', answer: "" },
{ text: 'What kind of drink would you like?', answer: "" }
];
$scope.addAnswers = function ($event) {
$event.preventDefault();
var clientContext = new SP.ClientContext(siteUrl);
var web = clientContext.get_web();
var list = web.get_lists().getByTitle('FoodQuestions');
_.each($scope.questions, function (question, i) {
// create the ListItemInformational object
var listItemInfo = new SP.ListItemCreationInformation();
// add the item to the list
var listItem = list.addItem(listItemInfo);
// Assign Values for fields
listItem.set_item('Question', question.text);
listItem.set_item('Answer', question.answer);
listItem.set_item('Title', 'Question ' + (++i));
listItem.update();
});
clientContext.executeQueryAsync(
Function.createDelegate(this, onQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);
};
onQuerySucceeded = function () {
alert('Thank you, have a nice day.');
var questions = $scope.questions;
_.each(questions, function (question) {
question.answer = "";
});
$scope.$apply();
}
onQueryFailed = function (sender, args) {
alert('Request failed. ' + args.get_message() + 'n' + args.get_stackTrace());
}
}
</script>
<h1>My First Visual WebPart featuring Angular.js</h1>
<div ng-app>
<div ng-controller="QuestionnaireCtrl">
<ol>
<li ng-repeat="question in questions">
<span>{{question.text}}</span>
<br />
<input type="text" ng-model="question.answer"/>
</li>
</ol>
<input type="submit" value="Submit" ng-click="addAnswers($event)"/>
</div>
</div>
[/code]
Congrats if you were able to follow along. I know I left out quite a bit of detail, so please let me know. As this is an experiment, pointers would be great too. I can post my whole Visual Studio project on github or somewhere if anybody is interested.
Thanks for reading.
![](https://www.bonzai-intranet.com/wp-content/uploads/2020/01/time_to_upgrade@2x.png)
It’s Time To Transform
Let us show you how much easier your work life can be with Bonzai Intranet on your team.