Archive

Archive for the ‘development’ Category

SharePoint Apps and AngularJS – SP.WebProxy Invocation using promises

April 17th, 2014 1 comment

Recently I’ve been trying to create a SharePoint 2013 app using AngularJS and angularui-bootstrap.

It’s been going well thanks to Jeremy Thake’s (@jthake) original demo.

But I wanted more! More than just access to the local site, I wanted access to the web, but I wanted to do it in the right AngularJs way, using the service so later when I figure out how to do DI testing I can, using promises too, which of course SharePoint doesn’t return in a way we can use in AngularJS.

So this code snippet (not complete app) will give you a clue on a way of doing it, there may be a better way to do this in AngularJS Im no expert, I see references to moduile.Factory calls in other examples, but I’m sticking to Jeremy’s starter code for now.

This example uses UK police data, details of the license are here http://www.nationalarchives.gov.uk/doc/open-government-licence/version/2

'use strict';
var myApp = angular.module('myApp', []);

function myAppCtrl($scope, $myDataService) {
    $scope.getPoliceClick = function () {

        //Whoops, edited this line as it was wrong from original post
        var promise = $myDataService.getPolice($scope);
        promise.then(
            //Success callback, check the status = 200 and go mad
            function (response) {....
            },
            //Epic Fail callback
            function (response) {....
            }
        );
    }
}

//this method signature is same as Jeremy's thats why the $http is there, I use it for lists as well
//just not in this code sample
myApp.service('$myDataService) ', function ($q, $http) {
    this.getPolice = function ($scope) {
        var deferred = $q.defer();
        var context = SP.ClientContext.get_current();
        var request = new SP.WebRequestInfo();
        request.set_url("http://data.police.uk/api/bedfordshire/57");
        request.set_method("GET");
        // We need the response formatted as JSON.
        request.set_headers({
            "Accept": "application/json;odata=verbose"
        });
        var response = SP.WebProxy.invoke(context, request);
        context.executeQueryAsync(
            function () {
                //Notice the scope apply, because the async call is made from outside of angular
                //just resolving will not work
                $scope.$apply(deferred.resolve(response));
            },
            function () {
                $scope.$apply(deferred.reject(response));
            }
        );
        return deferred.promise;
    }
});
Categories: development, Sharepoint Tags:

SharePoint 2010/13 Getting the Default Disp Page in JSOM

April 10th, 2014 No comments

Being pretty new to JSOM, thought I might write this down so I don?t forget again.

JSOM is just quite a bit different to REST or SPServices or just ferreting around the old server API, so it’s going to take some time.  Give me REST any day, but today I find myself altering some one else’s code.

I needed to find the default display page Url

Well it’s pretty simple, but web examples are gathering all list information the code I had was getting a specific list, not sure that they are still not getting all lists, but hey.

Adding the paramter “Include(DefaultDisplayFormUrl)” into the getByTitle function, instructs CSM that you want this bit of info.

 

   

   <script>


 targetList = clientContext.get_web().get_lists().getByTitle("Glossary", "Include(DefaultDisplayFormUrl)");  


</script> 

 

But you can’t access it immediately.

No you have to wait until after the executeQueryAsync only then can you call the function on the targetList variable, so watch those scopes,

   <script>

 
  targetList = clientContext.get_web().get_lists().getByTitle("Glossary", "Include(DefaultDisplayFormUrl)");  
 
  
  clientContext.executeQueryAsync(
      Function.createDelegate(this, function() { alert( targetList.get_defaultDisplayFormUrl();) } ),
      Function.createDelegate(this, function() {alert("failed")})
  );	

</script> 
Technorati Tags: ,,

Categories: development, Sharepoint Tags:

Using jQuery Queue with SPServices

November 20th, 2013 3 comments

One of the problems I came across the other day is I had several hundred items in a list to process.  To make life easy I use javascript on a web part page to make an app to process the items I wanted to do. 

However when its hundreds, do them all at once and you’re in trouble.  You block the UI thread, you cant update any status values, I dare not think what would happen if you called a couple of hundred async ajax queries all at once, it might just handle them – you can try it if you want ;-)

To get round this I thought I’d try to use jQuery queues.  So in this example I have a custom list which I get data from, I’m using promises to get the data but there was no need, I just used some code from the last example.  Once I have the data I inject it onto the screen an lose the original data array (now this is the point where I should use knockout and let the screen adjust to the observed data, but this is a demo).  Then on a click event, a big process this now button, I iterate thru each item on the page, gets its details and add a function to the queue that calls another function (just for being tidy I could embed) which makes a call to SPServices async update, phew.

Then I tell the queue to start executing the functions in it, one at a time.  At the end of each async success, it calls the next function, you might spot the mistake here, what if it doesn’t succeed (well I forgot to code it, but you need to do something with the item and the queue when you do it).

Hint: When calling functions and sub functions, make sure you “var” every variable, I forgot and it only updated the last item.

Technorati Tags: ,,

Here’s the code

 

 <script src="js/jquery.SPServices-0.7.1a.min.js"></script>  <script src="js/underscore.min.js"></script>   <div id="mainApp" > 	<div id="appStatus">Initialising</div>	<div id="appButton" style="cursor:hand;display:none">Click Me</div> 	<div id="appBody"></div>  </div>        <script>


var binaryJamQueueTest = function ($) {
   
   	//Private Members
  	var testListArray;

	function main() {
		
		$("#appStatus").text("Loading");

		//Remember that $.when is an async function also, so dont put anything after this code
		//unless you want it running immediately, in which case stick it here first.
		$.when(asyncGetTestList())
		.fail(function() {
			loadFailure();
		})
		.done(function(){
			dataReady();
		});
		
  	}
  	
  	function loadFailure() {
  		//Oh dear
	  	$("#appStatus").text("Failed to Load data");
  	}
  	
  	function dataReady() {
  		$("#appStatus").text("Processing Data");
  		
  		//Earlier versions did not queue so in cases where you will thread block
  		//use something like this to give the DOM time to update
  		setTimeout(function() {
	  		processList();
	  	}, 10);
  		
  	}
  	
  	
  	function asyncGetTestList() {
  	
  		var dfd = $.Deferred();
  		
		$().SPServices({          
			operation: "GetListItems",          
			async: true,          
			listName: "TestList", 
			CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='name' /><FieldRef Name='valueField' /></ViewFields>",

			completefunc: function(data, status) { 
				if (status== "success") {
					testListArray=$(data.responseXML).SPFilterNode("z:row").map(function() 
	                { 
							return {
								id: $(this).attr('ows_ID'), 
		                        title: $(this).attr('ows_Title') , 
		                        name: $(this).attr('ows_name') ,
		                        value: parseInt($(this).attr('ows_valueField')) 
		                    }; 
	                 }); 
					dfd.resolve("");				
				}
				else
				{
					dfd.reject();
				}
			} 
		}); 
		
		return dfd.promise();
  	}
  	
  	
  	function updateListItem(id, title, value, $item, next)
  	{
		//Notice here, if I was databinding I would only have to update the value not the html item
	  	$().SPServices({
			operation: "UpdateListItems",
			async: true,
			ID: id,
			listName: "TestList",
			valuepairs: [ ["valueField", value]],
			completefunc: function(xData, Status) {
				$item.text(title + " " + value);
				$item.attr('value', value);
				next();
			}
		});
	
  	}
  	
  	function processList()
  	{
		var $taskQueue=$({});
		
  		var htmlAdd="";
		$.each(testListArray, function(locIndex, testListRow) {
			
				htmlAdd+="<li id='" + testListRow.id + 
								"' title='" + testListRow.title + 
								"' name='" + testListRow.name + 
								"' value='" + testListRow.value + 
						  "'>" + testListRow.title + " " +
						 testListRow.value + 
						 "</li>";
								
				s="";
			
		});
		
		//Clear the original list Im going to use stuff onscreen, I know its wrong and not MVC
		//But Hey you do it the right way with a data binding library instead
		testListArray={};
  		
  		html=$("<ul id='itemsToProcess'>" + htmlAdd+ "</ul>");
		$("#appBody").html(html);
  		$("#appStatus").text("Ready");
  		$("#appButton").show();



  		$("#appButton").click(function() {
  		
			$.each($("#itemsToProcess").children(), function() {
				var $currentLi=$(this);
				$taskQueue.queue('tasks', function(next) {
	  				var id =$currentLi.attr('id');
	  				var title =$currentLi.attr('title');
	  				var value=parseInt($currentLi.attr('value'));
	  				updateListItem(id, title, value+1, $currentLi, next );
	  				
	  				
				});
			});

			$taskQueue.dequeue('tasks');
  		});
  				
  	}


	//Public Members
  	return {
   		init : main
  	}

  
}(jQuery); //binaryJamQueueTest Module


jQuery(function () {

    binaryJamQueueTest.init();
});


</script>  
Categories: development, Sharepoint Tags:

Error When talking to SharePoint Web Services in code

January 4th, 2012 1 comment

I’ve been trying to talk to SharePoint’s web services in C# for a couple of hours now. Something I do in JS all the time, but rarely in a clients C# app.

I’ve been getting the same error over and over again, but keep getting an error when trying to do anything.

Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).

I had dutifully copied the example code from the MSDN site and got a web reference to the Lists Web Service of course

and commented out the URL code in the example because that points at their site, not mine, which is pointed to by my web reference.

/*Set the Url property of the service for the path to a subsite.*/ listService.Url = http://MyServer/sites/MySiteCollection/_vti_bin/Lists.asmx;

WRONG!!!!!

If you are getting this error then it is because you commented out the URL.

When you add a web reference you are adding a WSDL file which is then compiled.  The WSDL is not specific to your site location,

if you open up the WSDL XML the section right at the bottom is pointing to elsewhere, the root of the WebApplciation not the RootWeb / Site you are interested in.

<wsdl:service name="Lists">     <wsdl:port name="ListsSoap" binding="tns:ListsSoap">       <soap:address location="http://my.binaryjam.com/_vti_bin/lists.asmx" />     </wsdl:port>     <wsdl:port name="ListsSoap12" binding="tns:ListsSoap12">       <soap12:address location="http://my.binaryjam.com/_vti_bin/lists.asmx" />     </wsdl:port>
</wsdl:service>

You need that line in the code that sets the listService.Url value, without it you are going to go mad trying to track down this bug, cos I didn’t find the answer online, I had to use fiddler.  Of course this article will now exist. :-)

 

Categories: development, Sharepoint Tags:

Creating TFS task Items from Powershell – From SPDisposeCheck Output

May 27th, 2011 Comments off

Now one for the SharePoint people.  You have ran SPDisposeCheck on the dire piece of code your lackey wrote (or youself for that matter) and forgot to run the SPDisposeCheck.  Whoosh loads of entries to validate and change the code for. 

Being good people using TFS for source code and task management you want an entry for each item to check.

Using the built in XML handling facilities from PowerShell this is an easy task.

First run SPDisposeCheck with the output set to XML You will get something like this

<?xml version=”1.0″ encoding=”ibm850″?>
<ArrayOfProblem xmlns:xsi=”
http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
  <Problem>
    <ID>SPDisposeCheckID_110</ID>
    <Module>BinaryJam.CrappyCode.dll</Module>
    <Method>BinaryJam.CrappyCode.ApplicationPages.EditSiteProperties.GetPortalRootWeb</Method>
    <Assignment>local2 := new Microsoft.SharePoint.SPSite(local0).{Microsoft.SharePoint.SPSite}get_RootWeb()</Assignment>
    <Line>0</Line>
    <Notes>Constructor called for Microsoft.SharePoint.SPSite but not assigned. This type should be assigned and subsequently disposed</Notes>
  </Problem>
</ArrayOfProblem>

 

You can Easily read XML files in PowerShell with a simple statement

$xmldata = 1(Get-Content c:\test\out.xml)

Accessing the Elements is then just object notation

$xmldata.ArrayOfProblem.Problem

Will return an array of problem items that can be accessed in a foreach $problem and with $problem.ID

So the full code to do this is

Read more…

Categories: development, Sharepoint Tags:

jQuery autocomplete for SharePoint Search Box

December 6th, 2010 3 comments

Whether or not SharePoint actually needs an autocomplete for it’s search box could be debated, and the manner in which I’m about to implement it, well that could be debated also. 

The point of this post was to use jQuery techniques to query a list via its web services and do something flash.  I’m doing it SharePoint 2007 as that is what I have handy and working. 

I will be upfront and honest right now, the code for this is a Mashup from two sources, Jan Tielens and the jQueryUI demo itself, both needed tweaking to come up with something new, but just so you know it’s not been rocket science, hard work was done for me, cheers Jan. 

Read more…

WSS3 – ItemAdded – deadlocked on lock

February 12th, 2010 3 comments

I’ve been having a problem with an app I wrote.  It works great, 99% of the time, but sometimes the ItemAdded event appears not to fire.

Now this is using a list with over 20,000 entries in it and its growing all the time.  An associated list that references this list as a lookup has over 144,000 entries in it.

The event firing problem is becoming more frequent now as more users start using the system, there are at least 20 occurances in that 20,000 items, so it has to be fixed.

Managed to track down an error in the log

System.Data.SqlClient.SqlException: Transaction (Process ID 61) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

It’s stack trace was similar too this (I cut it down a bit and changed some names, my naming is not this bad)

at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData()
   at Microsoft.SharePoint.SPListItemCollection.get_Item(Guid uniqueId)
   at BinaryJam.Core.Code.TicketListReceiver.ItemReceiver.ItemAddedActual(Guid SiteId, Guid ListItemId, String UserDisplayName)
   at BinaryJam.Core.Code.TicketListReceiver.ItemReceiver.<>c__DisplayClass11.<ItemAdded>b__e()
   at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)
   at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
   at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
   at BinaryJam.Core.Code.ItemListReceiver.ItemReceiver.ItemAdded(SPItemEventProperties properties)

So as you can see, it explodes on the GetItem.

This was my stupid mistake, a mistake I bet many of you are making every day.

SPListItem item = List.Items[listItemId];

This I believe is the primary cause of the problem as this statement loads the complete List before returning the specific item I needed and as this list grows, remember 20,000 items already, its going to get worse.  Now for most of you this won’t be a problem as you will be just getting the ListItem from the parameters, in my case I have to run as elevated as Im doing lots of stuff with Security Groups, that the entering user may not be in, hence my needing to re-get the List Item in the right security context.

So if your having a problem like this remember, Always use the

List.GetItemByID(id); //Or
List.GetItemByUniqueId(guid);

This may or may not solve my problem I believe it will, if it doesn’t it’s still going to improve the performance of my application.  If your wondering, this is the only time I use this and don’t know why I did, the rest of the App uses getby id or SPQueries.

A Good Article on Performance I did actually read, hence the app performs pretty well, except for this one bug, which is now hopefully fixed.

 

 

 

 

WSS, Workflow, Who Actually approved this ?

November 5th, 2009 Comments off

So I like many have a workflow that takes requests for Sites with a bunch of details for costing etc.  Then when approved those Sites are created and permissions allocated.

What we did not have was a record of who actually approved the sites.  Whilst this info is in the workflow history after a while that information gets purged, leaving us with Sites that were approved but by whom we know not.

So this is a simple case of changing the workflow and recording all of the approvers in the SPWeb properties, except that the approvers as we can tell happen to be Sharepoint Groups or AD groups, neither of which contain a history of membership, if AD does none I know how to access and certainly not easy for the customer and in a large membership we still would not know who actually did the deed.

I dug and dug for this and eventually found the User Login that actually did the change and here is how.

In your workflow you need a “Workflow Action” of EventName “OnTaskChanged”, this object in the code behind, when Invoked contains AfterProperties,

string user = OnApprovalTaskChanged.AfterProperties.ExtendedProperties[new Guid("d31655d1-1d5b-4511-95a1-7a09e9b75bf2")].ToString();

The above statement gets the User Login frmo the ExtendedProperties Collection.  It Stores the User under the key of that Guid in a User type field that refers to the Editor.

A list of fields can be found here .

So that’s it, took a lot of debugging and poking about but next time your looking for the actual approving user, take a look here.

Categories: development, Sharepoint Tags:

Sharepoint and ResX and a little tool

October 14th, 2009 1 comment

I am doing lots of work in Sharepoint that requires resource files in english and german.

With a variety of developers before me different styles of editing the foreign language files emerged.

I think that much better tool support for managing resx’s is required,  and I recently found one that is a great help to us with a vareity of resx’s in various states of translation and existence.

http://resxtranslator.codeplex.com/

This resx tool allows you to pick a file and it displays the nuetral and foreign side by side along with comments and allows you to edit them all at once.  Corking piece of work, some polish would go amiss but Im hard pushed to say where as it does exactly what I need it to do and I can pass it to a non-techie developer.  It still down to me to edit the comments first to identify what needs translating and what definately needs leaving alone.

If you doing multi-language work go and check this tool out it might just help.

WSS and PowerShell 2

July 31st, 2009 Comments off

If you were one of the two people who read my last post on WSS and PowerShell I updated it a bit and it’s worth checking out the changes.

I thought this time I would just point out some of the very simple statements in PowerShell that differ from your usual C# so that you can quickly make a transition from one to another.

One of the first things any programmer might need to do in a script is conditions so here is a PowerShell condition and how it differs to c#

if ($i -eq 10)
{
    write "It's ten you know"
}

The comparison operator for equals is not "=" or "==" but a scripting style operator of -eq. So this is the first thing you’re going to have to remember.  Other operators are

-gt greater than,  -lt less than,  -ge greater than or equal to,  -ne not equal

There are more I found a simple table of them here.

When dealing with boolean responses its important to know that they are represented by $true and $false so a condition to test this would look like

if ($kidding -eq $false)

{

    write "How strange"

}

Now being good little programmers you’re bound to want to structure your scripts, so functions!  PowerShell has functions, but remember this is not a compiled language but a scripting language, this means you have to declare your functions before you can call them, this is not VBScript where you could have your main at the top and functions below, your execution code starts at the bottom after you declared your functions. 

So declaring a function can be as simple as (there are other ways but I’m sticking with this one for now)

function GoGetMyList($name)
{
    $list=$lists["MyList"]
    return $list
}

The function has a parameter of $name and returns $list.  Now the observant of you will have noticed that I created my $list on the fly giving it a scope of function level, but I access $lists whose scope is outside of the function, ok bad coding perhaps, but it’s to prove a point.

Variable scopes.  There are I believe three scopes  Global, Script, Stack (function) level.

Global scope is used in the PowerShell environment mostly you can set something of Global level in a script and it will be available on completion of the script in the scripting "Shell/Command Prompt" environment, if you are chaining scripts together this could be useful.

Script scope.  This is like a global or module level variable to your script code, once declared it’s accessible inside and outside all your functions

Stack/Function scope.   Declare a variable inside a function it’s scope and life-span are inside that function.

The weird thing is how you declare and reference these variables.  So here is how to define 3 scopes within a function

function GetBaseObjects($SiteUrl)
{

    $script:site = New-Object Microsoft.SharePoint.SPSite $SiteUrl
    $script:web = $site.RootWeb
    $script:lists=$web.Lists
    $script:list=$lists["MyList"]
    $item=$list.GetItemById(1)
    $Global:DispName=$item.DisplayName
    return $item
}

Now this is a thoroughly useless function but it demonstrates the differing levels.

$script:site = New-Object Microsoft.SharePoint.SPSite $SiteUrl

The $scipt:site  declares the variable at a script level accessible from another function or the script "main body", there is no need to pre-declare these variables because at EVERY assignment you make it sets the scope, this is a valid set of statements

function dave()
{
    $script:tellme="Script"
    write $tellme
    $tellme="function"
    write $tellme
}
dave
write $tellme

This will display "Script", "function" and "Script".  This is because PowerShell with search each scope for a variable and if not there it looks up the inherited variable scope tree, for want of better words.  The first time referenced we have a script level but the second time we have a function level and the third time the function itself is out of scope along with its variables so we access the script level one again.

So remember the order of your functions when setting scope level variables and ALWAYS when setting a variable to define the scope.

That’s all for this post, I’ll try and do another one encompassing error handling and arguments in a complete script that changes SharePoint settings.

Technorati Tags: ,,,

Categories: development, Sharepoint Tags: