Sunday, May 3, 2015

Angular JS on SharePoint 2013

Now-a-days Angular JS has become popular and certainly there is reason for that. If you search in Internet you can find really good examples of Angular JS.
Since SharePoint is my bread and butter for some time, I thought of using it on SharePoint, I have found few examples in the internet but none of them was working correctly for me. I had to make few modifications and it worked on SharePoint. The main reason it was incorrect angular tags. So I’ll explain this as a first thing.

Relation between Angular JS and HTML page

I’ll not give you details of how Angular JS works; I assume you must have some sort of idea about it. But I found below relation was working in all of my SharePoint pages. Note the DIV tags ng-app=”myApp”, ng-controller=”ConactController” in the HTML side and their relation with the JavaScript in the below diagram

Preparation

Before you start development you need to prepare the environment, i.e. getting the necessary JS files I have used Angular JS, JQuery and Bootstrap CSS for the examples, but bootstrap is not essential.
I have downloaded most of the files and placed them inside “SiteAssets” library; you may want to put it in a more orderly folder structure.

Sometimes I have used CDN also e.g.: http://getbootstrap.com/2.3.2/assets/css/bootstrap.css . Similarly you can use Google CDN for jQuery and Angular JS. You can download Angular JS from https://angularjs.org/ and bootstrap from here: http://getbootstrap.com/
Below is a screenshot of the Site Assets library in my SharePoint.




Page1-Page6 JS files are specific for the SharePoint examples shown in Page1 to 6 (see them in thleft navigation). All other files are common.

For some reason the JS was not working until I activated SharePoint Publishing feature on the site.I’m not sure if that’s really needed though. But for a better looking site you might want to use publishing pages rather than wiki pages.


I have added all HTML script in a script editor on each page.
Create a page named Page1„ Edit the page„³Add a script editor in the page


Once you add the script editor, go to Edit Snippet and paste the HTML there. A sample screenshot is given below.


I have created a custom list name Employee which has been used in many examples below. Notice the EmpImage column. The Images are stored in the Images library, this library should be already created when you activate SharePoint publishing feature. You can use some other library too.


I have created a custom list name Employee which has been used in many examples below. Notice the EmpImage column. The Images are stored in the Images library, this library should be already created when you activate SharePoint publishing feature. You can use some other library too.



Page1 Example

Now to the actual examples, this is a really simple example, just to give you an idea. You enter some data and a popup shows your answer.


I have created a page name Page1.aspx, added a script editor and pasted below HTML into the script editor. Same technique used for all the examples.

HTML
This few lines of HTML render the questions and popup answers too.
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/angular.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/Page1.js"></script>
<link rel="stylesheet" type="text/css" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css">
<style type="text/css"> .auto-style1 { color: #339933;}</style>
<div ng-app="myApp">
<div ng-controller="ContactController">
<div id="PutYourContentInside">
<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></div> 


JavaScript:
The JavaScript used here is saved as Page1.js in the site asserts library. So this script just passes the questions to the 'ContactController'module and gets back the answers. This JavaScript was saved as Page1.js in the Site Assets library.
var myApp = angular.module('myApp', []);
var uid = (function () {
var id = 1;
return function () {
if (arguments[0] === 0)
id = 1;
return id++; }})();
var siteUrl = GetSiteUrl();
myApp.controller('ContactController', function ($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 ans = "";
for (i in $scope.questions) {
ans = ans + $scope.questions[i].answer + ", ";
$scope.questions[i].answer = "";
}
$scope.$apply();
alert("Thank you for your answers : " + ans);
}});
function GetSiteUrl() {
var urlParts = document.location.href.split("/");
return urlParts[0] + "//" + urlParts[2] + "/" + urlParts[3] + "/" + urlParts[4];


Page2 Example
This is a simple data grid operation.
HTML
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/angular.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/Page2.js"></script>
<link rel="stylesheet" type="text/css" href="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/bootstrap.css">
<style type="text/css">
.auto-style1 { color: #339933; }
</style>
<div ng-app="myApp">
<div ng-controller="ContactController">
<label><span class="auto-style1"><strong>Enter data.</strong></span><br />
<br /> Name</label>
<input type="text" name="name" ng-model="newcontact.name"/>
<label>Email</label>
<input type="text" name="email" ng-model="newcontact.email"/>
<label>Phone</label>
<input type="text" name="phone" ng-model="newcontact.phone"/>
<br/>
<input type="hidden" ng-model="newcontact.id"/>
<br>
<input type="button" value="Save It" ng-click="saveContact()" class="btn btn-primary" /><br />
&nbsp;<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="contact in contacts">
<td>{{ contact.name }}</td>
<td>{{ contact.email }}</td>
<td>{{ contact.phone }}</td>
<td>
<a href="javascript:void(0)" ng-click="edit(contact.id)">edit</a> |
<a href="javascript:void(0)" ng-click="delete(contact.id)">delete</a>
</td>
</tr>
</tbody>
</table></div></div>
JavaScript:
var myApp = angular.module('myApp', []);
var uid = (function () {
var id = 1;
return function () {
if (arguments[0] === 0)
id = 1;
return id++;
}
})();
myApp.controller('ContactController', function ($scope) {
$scope.contacts = [{ id: 0, 'name': 'Arindam', 'email': 'Arindam@myemail.com', 'phone': '123-2343-44' }];
$scope.saveContact = function () {
if ($scope.newcontact.id == null) {
$scope.newcontact.id = uid();
$scope.contacts.push($scope.newcontact);
}
else {
for (i in $scope.contacts) {
if ($scope.contacts[i].id == $scope.newcontact.id) {
$scope.contacts[i] = $scope.newcontact;
}
}
}
$scope.newcontact = {};
}
$scope.delete = function (id) {
for (i in $scope.contacts) {
if ($scope.contacts[i].id == id) {
$scope.contacts.splice(i, 1); $scope.newcontact = {};
}
}
}


$scope.edit = function (id) {
for (i in $scope.contacts) {
if ($scope.contacts[i].id == id) {
$scope.newcontact = angular.copy($scope.contacts[i]);
}
}
}
});

Page3 Example

In this example I have done some real SharePoint operations, I have created a custom list named Employee and then read the list items in a tabular mode. Now there is more than one way of doing list operation in client side coding. Here I have used the list service but this is not just normal list service call, I have used Angula JS’s capability of calling a http method and parse data. Latter I have another example with async client calling.
Check how small amount of coding was required for this. You must have noticed that bootstrap CSS was used for the table formatting. 

<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/jquery-2.1.3.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/angular.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/bootstrap.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/Page3.js"></script>
<link rel="stylesheet" type="text/css" href="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/bootstrap.min.css">
<style type="text/css">
.auto-style1 {
color: #339933;
}
</style>
<div ng-app="SharePointAngApp" class="row">
<div ng-controller="spCustomerController" class="span10">
<table class="table table-striped table-bordered">
<tr>
<th>Employee ID</th>
<th>Employee Name</th>
<th>City</th>
</tr>
<tr ng-repeat="customer in customers">
<td>{{customer.Id}}</td>
<td>{{customer.EmpName}}</td>
<td>{{customer.EmpCity}}</td>
</tr>
</table>
</div>
</div>
JavaScript:
var webSiteURL = GetSiteUrl();
//alert(webSiteURL);
var myAngApp = angular.module('SharePointAngApp', []);
myAngApp.controller('spCustomerController', function ($scope, $http) {
$http({
method: 'GET',
url: webSiteURL + "/_api/web/lists/getByTitle('Employee')/items?$select=Id,EmpName,EmpCity",
headers: { "Accept": "application/json;odata=verbose" }
}).success(function (d, s, h, c) {
$scope.customers = d.d.results;
});
});
function GetSiteUrl() {
var urlParts = document.location.href.split("/");
return urlParts[0] + "//" + urlParts[2] + "/" + urlParts[3] + "/" + urlParts[4] + "/" + urlParts[5];
}



Page4 Example
In this example I’m adding a new item to the Employee list, client site async call have been used for this.
HTML
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/angular.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/Page4.js"></script>
<link rel="stylesheet" type="text/css" href="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/bootstrap.css">
<style type="text/css">
.auto-style1 {
color: #339933;
}
</style>
<div ng-app="myApp">
<div ng-controller="ContactController">
<div id="PutYourContentInside">
<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>
</div>

JavaScript:
var myApp = angular.module('myApp', []);
var uid = (function () {
var id = 1;
return function () {
if (arguments[0] === 0)
id = 1;
return id++;
}
})();
var siteUrl = GetSiteUrl();
//alert(siteUrl);
myApp.controller('ContactController', function ($scope) {
$scope.questions = [
{ text: 'What is the new Employee name?', answer: "" },
{ text: 'Where does he live?', answer: "" }
];
$scope.addAnswers = function ($event) {
$event.preventDefault();
var clientContext = new SP.ClientContext(siteUrl);
var web = clientContext.get_web();
var list = web.get_lists().getByTitle('Employee');
// 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('EmpName', $scope.questions[0].answer);
listItem.set_item('EmpCity', $scope.questions[1].answer);


listItem.update();
clientContext.executeQueryAsync(
Function.createDelegate(this, onQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);
};
onQuerySucceeded = function () {
alert('Thank you, one record added to Employee list.');
}
onQueryFailed = function (sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
});


function GetSiteUrl() {
var urlParts = document.location.href.split("/");
return urlParts[0] + "//" + urlParts[2] + "/" + urlParts[3] + "/" + urlParts[4] + "/" + urlParts[5];
}


Page5 Example
Here I’m reading data again from Employee list; I have used JQury’s capability of calling a service and get the response in JSON format, for Image parsing we need to do some special coding pls note that in the JS file.
HTML
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/jquery-2.1.3.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/angular.min.js"></script>
<script src="http://SERVERNAME/sites/arindamc/Subsite1/SiteAssets/Page5.js"></script>
<div ng-app="myApp">
<div ng-controller="ContactController">
<div ng-repeat="p in Products">
<table style="background-color:#f07432">
<tr><td align = "center"><b>Employee Name: {{p.EmpName}}</b> </td></tr>
<tr><td align = "center"><img ng-src={{p.EmpImage}} /> </td></tr>
<tr><td align = "center"><b> Employee City:{{p.EmpCity}}.</b></td></tr>
</table>
<hr />
</div></div></div>


JavaScript:
var myApp = angular.module('myApp', []);
var webSiteURL = GetSiteUrl();
myApp.controller('ContactController', function ($scope) {
$scope.loadREST = function () {
jQuery.ajax({
url: webSiteURL + "/_vti_bin/listdata.svc/Employee?$select=EmpName,EmpCity,EmpImage",
type: "GET",
dataType: "json",
async: "true",
headers: { "Accept": "application/json;odata=verbose" },
success: function (data) {
var newData = [];
jQuery.each(data.d.results, function (index, value) {
//alert(value.EmpImage);
var pImage = value.EmpImage;
if (pImage != null) {
prImage = pImage.substring(0, pImage.indexOf(','));


newData.push({ EmpName: value.EmpName, EmpCity: value.EmpCity, EmpImage: prImage });
}
});
$scope.$apply(function () {
$scope.Products = newData;
});
},
error: function () {
alert("error");
}
});


};
$scope.loadREST();
});
function GetSiteUrl() {
var urlParts = document.location.href.split("/");
return urlParts[0] + "//" + urlParts[2] + "/" + urlParts[3] + "/" + urlParts[4] + "/" + urlParts[5];
}
Page6 Example
This example is adopted from this awesome article: Chart SharePoint Hosted App with AngularJs and JqPlot
Please go ahead and check the details there. The scenario here is to have data inside SharePoint List (custom list, one column for title and one column for value), to access that data, to use angular (http://angularjs.org) for data-binding part and jqPlot (http://www.jqplot.com ) for chart rendering. Also, one chart in this example is using ui-chart directive (http://angular-ui.github.io/ui-chart/), the directive that lets you use jqPlot with Angular

Note: The original article was written as an App on SharePoint 2013, I have converted it to fully client side coding, no Visual studio was used. For that I have provided the HTML below, also I had to make some changes the App.JS which is the main JS file for this (like Page1.Js for Page1.aspx in previous articles).
I have also copied the whole script folder as SiteAsset\ChartApp in the SharePoint portal. The content was copied from the Your Download path \ChartApp\Scripts folder. This has duplicate angular.js/JQuey-min.js etc. which you need to take care in actual scenario.
I also copied App.Css from ChartApp\Content folder to SiteAsset\ChartApp in the SharePoint portal. The site assets now look like below

HTML
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/angular/angular.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/jquery.jqplot.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/plugins/jqplot.pieRenderer.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/plugins/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/plugins/jqplot.pointLabels.min.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/chart.js"></script>
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/Common.js"></script>
<link rel="stylesheet" type="text/css" href="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/lib/jqplot/jquery.jqplot.css"/>
<!-- Add your CSS styles to the following file -->
<link rel="Stylesheet" type="text/css" href="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/App.css" />
<!-- Add your JavaScript to the following file -->
<script type="text/javascript" src="http://inbaghpc00156/sites/arindamc/Subsite1/SiteAssets/ChartApp/App.js"></script>
<div>
<p id="message">
</p>
</div>
<div ng-app="myChartingApp" ng-controller="DemoCtrl">
<div ui-chart="someData" chart-options="myChartOpts" style="width:600px; height:300px;" ></div>
<div id="barchart" style="width:600px; height:300px;"></div>
<div id="linechart" style="width:600px; height:300px;"></div>
</div>

JavaScript
The below script is the App.js, I did not have to modify any other JS file. I also have commented the original code so that you can understand my changes.
'use strict';
// The allAnnouncements variable is used by more than one
// function to retrieve and process the results.
var allData;
var hostweburl;
var appweburl;
//alert('inside');
var myChartingApp = angular.module('myChartingApp', ['ui.chart'])
.value('charting', {
pieChartOptions: {
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
// By default, labels show the percentage of the slice.
showDataLabels: true
}
},
legend: { show: true, location: 'e' }
}
});
myChartingApp.service('$SharePointJSOMService', function ($q, $http) {
this.getData = function ($scope, listTitle) {
var deferred = $q.defer();
hostweburl = 'http://inbaghpc00156/sites/arindamc/Subsite1';
// decodeURIComponent(
// getQueryStringParameter("SPHostUrl")
// );
appweburl = 'http://inbaghpc00156/sites/arindamc/Subsite1';
// decodeURIComponent(
// getQueryStringParameter("SPAppWebUrl")
// );
//alert(hostweburl);
//alert(appweburl);
// resources are in URLs in the form:
// web_url/_layouts/15/resource
var scriptbase = hostweburl + "/_layouts/15/";
// Load the js files and continue to the successHandler
$.getScript(scriptbase + "SP.Runtime.js",
function () {
$.getScript(scriptbase + "SP.js",
function () {
$.getScript(scriptbase + "SP.RequestExecutor.js",
function () {
// var clientContext = new SP.ClientContext(siteUrl);
// var web = clientContext.get_web();
// var list = web.get_lists().getByTitle('Employee');
var context = new SP.ClientContext(appweburl);
//var factory = new SP.ProxyWebRequestExecutorFactory(appweburl);
// context.set_webRequestExecutorFactory(factory);
// var appContextSite = new SP.AppContextSite(context, hostweburl);
//var web = appContextSite.get_web();
var web = context.get_web();
context.load(web);
var list = web.get_lists().getByTitle(listTitle);
var camlQuery = SP.CamlQuery.createAllItemsQuery();
this.listItems = list.getItems(camlQuery);
context.load(this.listItems);
context.executeQueryAsync(
Function.createDelegate(this, function () {
var ListEnumerator = this.listItems.getEnumerator();
while (ListEnumerator.moveNext()) {
var currentItem = ListEnumerator.get_current();
console.info(currentItem.get_item('Title') + currentItem.get_item('ID'));
var Title = currentItem.get_item("Title");
var Value = currentItem.get_item("Value");
var b = [Title, Value];
$scope.someData[0].push(b);
$scope.ticks.push(Title);
$scope.barvalues.push(Value);
//$scope is not updating so force with this command
$scope.$apply();
}
$scope.setBarChart();
$scope.setLineChart();
}),
Function.createDelegate(this, function (sender, args) {
deferred.reject('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
})
);
}
);
}
);
}
);
return deferred.promise;
};
});
myChartingApp.controller('DemoCtrl', function ($scope, charting, $SharePointJSOMService) {
//alert('controller');
$scope.someData = [[]];
$scope.ticks = [];
$scope.barvalues = [];
var promise = $SharePointJSOMService.getData($scope, 'PieChartData');
promise.then(
function (message) {
alert(message);
},
function (reason) {
alert(reason);
}
);
$scope.myChartOpts = charting.pieChartOptions;
$scope.setBarChart = function () {
//alert('setBarChart');
var plot2 = $.jqplot('barchart', [$scope.barvalues], {
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
pointLabels: { show: true, location: 'e', edgeTolerance: -15 },
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: $scope.ticks
}
}
});
}
$scope.setLineChart = function () {
//alert('setLineChart');
var plot = $.jqplot('linechart', [$scope.barvalues], {
title: 'Sales 2014',
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}, seriesDefaults: {
rendererOptions: {
smooth: true
}
},
axes: {
yaxis: {
label: 'Sales', min: 0
},
xaxis: {
label: 'Months', min: 1, max: $scope.barvalues.length
}
}
,
series: [{ color: '#5FAB78' }]
});
}
});

Output

POINTS TO BE NOTED
 I have masked the actual server name with SERVERNAME is all JS references, you need to use correct URL.
 If you are using CDN, make sure internet is available in your server
function GetSiteUrl()- is a very basic method, you need to modify it based on the depth of the SharePoint portal URL you are using, for me the URL is http://SERVRNAME/arindamc/Subsite1, so I used until urlParts[4] in the return statement. 

I Hope its help for learning. 


Thursday, March 12, 2015

Some farm products and patches were not detected in sharepoint CA product and patch installation status


Issue : While running psconfig , ask SharePoint Products Configuration Wizard  getting below error below patch were missing in your farm.  

All  patches installed without error in all servers.

verified these patches were installed in Programs and Features, recently installed updates.  Restarted each SharePoint server after the updates. Still SharePoint thought we hadn't patched one of the servers.

Solution :

Get-SpProduct -Local
(Get-SpServer $env:ComputerName).NeedsUpgrade

Thursday, February 19, 2015

The server was unable to save the form at this error in SP 2013 Site

While working with SharePoint 2013 list, saving the data I got an error saying that “The server was unable to save at this time. Please try again.” As shown the image below.

By checking the logs I have found following error

Event errors :

“Memory gates checking failed because the free memory is less than 5% of total memory. As a result, the service will not be available for incoming requests. To resolve this, either reduce the load on the machine or adjust the value of minFreeMemoryPercentageToActivateService on the serviceHostingEnvironment config element"

Solution :

To fix this error we have to restart “SharePoint Search Host Control” and “SharePoint Administration service”. By refreshing this error we can have a lot of memory will be freed. We have same error when custom application deployed without disposing object. In that case we need to reset the IIS. By resetting the IIS We can save the list data without error.

Refernce: msdn

Monday, July 14, 2014

SharePoint error: This service instance 'Microsoft SharePoint Foundation Usage' cannot be provisioned on server 'WFE1' because it is mapped to server 'WEF2'.


While working with Configure web analytics and health data collection
,got an error saying that “This service instance 'Microsoft SharePoint Foundation Usage' cannot be provisioned on server 'WFE1' because it is mapped to server 'WEF2'.




ULS Logs : Microsoft.SharePoint.SPException: This service instance 'Microsoft SharePoint Foundation Usage' cannot be provisioned on server 'WFE1' because it is mapped to server 'WFE2"

Troubleshooting steps:
1) Stop All web analytical Services in all servers
2) Went to Manage Services on the Server, switched the view to WFE1 and WFE2, noticed the services were Stopped. I started them so now they are running on all server in Farm  but no luck
3)     Next actions would be  Deleted both services (Usage and Health Data Collection Service  and Web Analytics Service Application) and recreated.
4) Started services again but no results
 5) After long research and found another way to achieve this issue.
6) Stop web analytics service in all Servers using services.msc
7) Restarted the service again
8) Checked all Sharepoint services are running or not on a farm using stsadm -o enumservices
9) Observed Microsoft.SharePoint.Administration.SPUsageService Provision service was disabled in one of the WFE server()
10) Start service using  below command
11) stsadm -o provisionservice -action start -servicetype Microsoft.SharePoint.Administration.SPUsageService
12) Again stop all services in both services as well application server
13) Recreate services (Web Analytics Service Application) and configured
14) After that ,Configured events in usage and health data collection
15) Started Web Analytics Web Service  services in all the servers using  CA .
16) After that web analytics reports has been working in all prod Sites.
 


 







Thursday, June 5, 2014

Hiding 'Top Visitors' Web Analytics report from users in SharePoint 2010




Addd  the Java script below the tag line in report page under layout 

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\WebAnalytics\reports.aspx

  asp:Content ID="Content1" runat="server" ContentPlaceHolderID="PlaceHolderLeftNavBar" 



</SharePoint:VersionedPlaceHolder>

      <script type="text/javascript">
if (window.location.href.indexOf("/_layouts/WebAnalytics/Report.aspx?t=TopVisitorsReport") != -1)
{
alert ("This function is not allowed");

url = window.location.href;
url = url.replace(/TopVisitorsReport/g, "SummaryReport");

window.location.href = url;
}

        var cc = document.getElementsByTagName("a");

        for (var i = 0; i < cc.length; i++)
{
        var link = cc[i];


  if (link.href.indexOf("/_layouts/WebAnalytics/Report.aspx?t=TopVisitorsReport") != -1)
           //link.parentNode.style.display = "none";
                    link.parentNode.removeChild(link);
               
        }
     </script>

</asp:Content>