Search

Binary Jam

Simon's blog, SharePoint, Arduino type things.

Set Fiddlers Icon based on Connected or Not

Thanks to @ericlaw for the info on this, since version 2.4.7.2 of fiddler you can set the Tray Icon to whatever you want.

I like to know at a glance whether fiddler is connected or not, I leave mine running al the time, I have various issues with proxy servers and virtuals, sometimes it’s just easier to manage the hosts file in fiddler perhaps cos I?’m too lazy to go into admin mode and edit the real one.

fiddlerOff fiddlerOn

I used a simple red / green system you can guess which is which 🙂

To do this copy the images to your system somewhere.

Then in Fiddler open the Rules Editor (CTRL-R) and make these changes, just point at your path not mine.

static function OnAttach() {
// MessageBox.Show("Fiddler is now the system proxy");
FiddlerApplication.UI.SetTrayIcon("D:\dev\fiddlerOn.png")
}

static function OnDetach() {
// MessageBox.Show("Fiddler is no longer the system proxy");
FiddlerApplication.UI.SetTrayIcon("D:\dev\fiddlerOff.png")
}

Save it and that’s it.

If they would just give me the option now so a left click on the tray toggles between connected or not and a dbl click open fiddler. Because for me its more than just a debugger now.

Whilst I’m talking changes some more tray options (right mouse menu) that I would love, hope your listening 🙂

  •     Toggle Https decryption
  • Select Gateway option (something I have to do all the time, stupid pac file wont work in fiddler)
  • Autoresponder toggle
Advertisements

God Ted, I love fiddler – or using fiddler to address individual servers on a HNSC)

This tool just gets better for me with every little bit more I learn about it. I use it as a proxy server for my VM’s to keep them of the main network, but have internet access. I use it for speed tests, I use it for dynamic debugging of javascript of sites I have no access too.  It’s wonders do not cease.

Yesterday I had an problem with a Host Named Site Collection, or rather it appears that one of the servers appeared to be slow.  But being a HNSC no AAM’s were created for it and with four front ends to test how the hell do you hit each one sseperately.

Chap running the servers was kind enough to give me the IP addresses and of course I can then edit the hosts file and test each one from the main address.

Well that sucks.

Enter Fiddler, did I say how much I love fiddler ?

In fiddler is a rules file,   CTRL-R will get you there. In that we can do marvelous things, in this case I wanted to handle my HNSC problem by having 4 separate urls I could hit and test each server in a load test script.

My host was something like

http://hnsc.binaryjam.com

and I wanted to hit

http://hnsc1.binaryjam.com

http://hnsc2.binaryjam.com

http://hnsc3.binaryjam.com

http://hnsc4.binaryjam.com

 

Here’s how to do it in fiddler.  Edit the rules file and find the function OnBeforeRequest, its all javascript dontcha know.

Add this bit of code at the bottom of the function

if (oSession.hostname == "hnsc1.binaryjam.com") {
	oSession.hostname = "hnsc.binaryjam.com";
	oSession["x-overrideHost"] = "192.168.1.10"; // <– Server IP here!
}
if (oSession.hostname == "hnsc2.binaryjam.com") {
	oSession.hostname = "hnsc.binaryjam.com";
	oSession["x-overrideHost"] = "192.168.1.11"; // <– Server IP here!
} 
if (oSession.hostname == "hnsc3.binaryjam.com") {
	oSession.hostname = "hnsc.binaryjam.com";
	oSession["x-overrideHost"] = "192.168.1.12"; // <– Server IP here!
} 
if (oSession.hostname == "hnsc4.binaryjam.com") {
	oSession.hostname = "hnsc.binaryjam.com";
	oSession["x-overrideHost"] = "192.168.1.13"; // <– Server IP here!
}

Save it and do a test.

I even ran WireShark to see what was actually happening on the network stack, and it works, it was routing requests for specific servers to each individual server, and because we set the hostname to what it should be any code JS or server using the server name works fine too.

Makes me really want to crack open the fiddler manual and find out what other voodoo I can do.

SharePoint Apps and AngularJS – SP.WebProxy Invocation using promises

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 module.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;
	};
});

Angular Google Maps Example

I’m trying to get my head around angular and using it for writing SharePoint Apps, but one of the first things I wanted to write used google maps.

Luckily (or not depending on how much pain you want to know this caused me) there is a directive library for google maps.

After far too many save and refresh and crash cycles I have a simple example working that has markers and info windows.

Here it is

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>angular-google-maps example</title>
<style>
        .angular-google-map-container {
            height: 800px;
        }
    </style>
<!-- Google Maps API v3 -->
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&amp;language=en"></script>
<!--  v1.0.8 -->
<script src="angular.min.js"></script>
<!-- http://underscorejs.org/ -->
<script src="underscore-1.6.0.min.js"></script>
<!-- http://angular-google-maps.org -->
<script src="angular-google-maps.min.js"></script>
</head>
<body>
     <div ng-app="BinaryJamApp">
         <div ng-controller="MappingController">
 		<google-map  center="map.center" zoom="map.zoom" draggable="true" events="map.events"  options="map.options" pan="true"  control="map.control">
			<markers models="sites" coords="'self'" click="'onClicked'">
 				<windows show="'showWindow'" closeClick="'closeClick'" ng-cloak>
 					<p ng-non-bindable style="width:200px">{{ options.title }}</p>
 					<p ng-non-bindable>{{ latitude | number:4 }}, {{ longitude | number:4 }}!</p>
				</windows>
 			</markers>
 		</google-map>
         </div>
     </div>
     <script>
        var BinaryJamApp = angular.module('BinaryJamApp', ['google-maps']);

        function MappingController($scope) {
			$scope.sites=[];

			$scope.map = {
				control: {},
				options: {
					streetViewControl: false,
					panControl: false,
					maxZoom: 20,
					minZoom: 3
				},
				center: {
					latitude: 52,
					longitude: 0
				},
				zoom: 6
			};

			var onMarkerClicked = function (marker) {
				marker.showWindow = true;
				$scope.$apply();
			}; 

			$scope.sites.push({latitude:52, longitude:0, options: { title: "Southerners" } });
			$scope.sites.push({latitude:52.5, longitude:1, options: { title: "Turkeys" } });

			_.each($scope.sites, function (site) {
				site.closeClick = function () {
					site.showWindow = false;
					$scope.$apply();
				};
				site.onClicked = function () {
					onMarkerClicked(site);
				};
			});

        }

    </script>
  </body>
 </html>

SharePoint 2010/2013 Open a Form on the browse tab

This is something I regularly search for and more and more often I’m finding people posting code versions when all I really want is the URL parameter to force it. So luckily I stumbled across SharePoint Den page that posts the following

http://site/List1/Forms/DispForm.aspx/&InitialTabID=Ribbon.Read

 

So cheers chap, the more places this version is shown I hope helps someone else find the way correct for them

Technorati Tags:

SharePoint 2010/13 Getting the Default Disp Page in JSOM

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: ,,

Using jQuery Queue with SPServices

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>  

Using jQuery promises with SPServices

I had reason to pull in data from three separate lists in SharePoint recently. Data in list three was dependant on lists one and two.

So I created an admin app page to manage problems with list three.  Having to pull data from all three lists, left me with some options

  • load them synchronously
  • nest the calls in successive succeeded function
  • Use jQuery promises

Perhaps someone has done this and there is a good example out there, but I couldn’t find it so I figured this out for me and am posting it because, well you can’t have enough examples.

This code is just enough of the original to demonstrate promises, I tested the original but had to change some details here which of course I havent had time to check, so I hope this works (it should with the lists in place) and give you enough insight.

In this code look at the $.when statement, the way I’m using it means that it will execute each function in turn and only continue if all functions suceed, if one fails it will execute the loadfailure function instead.

EDIT:As Marc comments below, SPServices returns a promise now so no need to build your own, see Marcs link
for more details. This code is still handy for seeing how to use promises with an async call, but this is not how to do it any more. This is quite messy code too.  When you start to use more structured code, SPA frameworks, then this method doesn’t really fit and the returned promise fits better with service or provider patterns unlike this jumble pattern here ;-).

http://js/jquery-1.7.min.js
http://js/jquery.SPServices-0.7.1a.min.js
http://js/underscore.min.js
Initialising
</div> var binaryJamPromisesTest = function ($) { //Private Members var listOne, listTwo, listThree; function main() { $("#appStatus").text("Loading"); $.when(asyncGetListOne(), asyncGetListTwo()) .fail(function () { loadFailure(); }) .done(function () { dataReady(); }); } function loadFailure() { $("#appStatus").text("Failed to Load data"); } function dataReady() { $("#appStatus").text("Processing Data"); //processLists(); //Do the main thread work here ! } function asyncGetListOne() { var dfd = $.Deferred(); $().SPServices({ operation: "GetListItems", async: true, listName: "ListOne", completefunc: function (data, status) { if (status == "success") { _listOne = $(data.responseXML).SPFilterNode("z:row").map(function () { return { id: $(this).attr("ows_ID"), title: $(this).attr("ows_Title") }; }); dfd.resolve(""); } else { dfd.reject(); } } }); return dfd.promise(); } function asyncGetListTwo() { var dfd = $.Deferred(); $().SPServices({ operation: "GetListItems", async: true, listName: "ListTwo", completefunc: function (data, status) { if (status == "success") { _listTwo = $(data.responseXML).SPFilterNode("z:row").map(function () { return { id: $(this).attr("ows_ID"), title: $(this).attr("ows_Title") }; }); dfd.resolve(""); } else { dfd.reject(); } } }); return dfd.promise(); } //Public Members return { init: main } } (jQuery); jQuery(function () { binaryJamPromisesTest.init(); });

jQuery mobile – Multi Pages

 

We have been playing about with jQuery mobile at the office and its a great way to deliver specific mobile content and of course it works with PhoneGap for compiling those apps to (near native).

But we had a couple of teething issues due to the documentation being a little all over the place and the examples being a little too simple from the recommended approaches, and the voodoo it does.

First Glossary, in jQuery mobile each page is a screen displayed in the browser that is transistioned (sometimes in a fancy way) to or from.  These pages are essentially (ootb)

sections with an attribute of data-role=”page”.  Now in the demos and examples you will find in the docs and other sites these “Multi-Page” demos are seperate pages displayed on the phone, but in terms of files on the file system they are all in the same htm page.

See demo MultiPage-Template

Now this is great for a couple of pages all based on ajax filled content, but where there are many pages then thats the time to split those pages out onto the file system into seperate documents.

The documentation recommends this approach because as the new page is loaded the last page is removed from the DOM thus saving memory (there are techniques to force caching of pages).  This is where the some of the confusion can arise as there are so few examples explaining whats happening.

The default behavior for jQuery mobile when navigating about these separate htm files that are defined as pages of the app is that it uses ajax to load them. It can then take that content and inject it into the DOM and then transition between the two. 

The problem we encountered due to the lack of demos and not reading docs is that where did we put the scripts the css what happens on page load etc.  Well it’s actually been made really simple and the thing to remember is this –

Taken from the documentation

Scripting pages->Scripts and styles in the head

http://jquerymobile.com/demos/1.2.0/#/demos/1.2.0/docs/pages/page-scripting.html

When the user clicks a link in a jQuery Mobile-driven site, the default behavior of the navigation system is to use that link’s href to formulate an Ajax request (instead of allowing the browser’s default link behavior of requesting that href with full page load). When that Ajax request goes out, the framework will receive its entire text content, but it will only inject the contents of the response’s body element (or more specifically the data-role="page" element, if it’s provided), meaning nothing in the head of the page will be used (with the exception of the page title, which is fetched specifically). Please note that scripts loaded dynamically in this fashion do not guarantee a load order in the same way they would if the page was loaded via a normal http request.

This means that any scripts and styles referenced in the head of a page won’t have any effect when a page is loaded via Ajax, but they will execute if the page is requested normally via HTTP. When scripting jQuery Mobile sites, both scenarios need to be considered. The reason that the head of a page is ignored when requested via Ajax is that the potential of re-executing the same JavaScript is very high (it’s common to reference the same scripts in every page of a site). Due to the complexity of attempting to work around that issue, we leave the task of executing page-specific scripts to the developer, and assume head scripts are only expected to execute once per browsing session.

This is the key to how it all works under the hood.

So when coding a simple app in jQuery mobile in multiple pages then a simple layout might be this.  This is a simplification of the jquery mobile multi-page boiler template split across two files.

The second file does not need any of the jquery, css, or other js files.  As the navigation system looks for a div of data-role page and squirts it in.  NOTE multi-page/Multiple Page combos are not allowed it will likely fall on its face, so dont stick more than one date-role=”page” into these Multiple Page designed apps.

 

Main.html

Multi-page template
http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css&#8221; />
http://ahref=
http://ahref=

   $(‘#home’).on(‘pageinit’, function () { 
       console.log(‘home page-init’);
   });

 

function Yay() {
    console.log(‘Yay’);
}

   

   
       

One

       

I have an id of “home” on my page container. I’m first in the source order so I’m shown when the page loads.

   

       

Link to Other Page:

       

Show page “two”

    
   

</div>

</body>
</html>

Page2.html

<!DOCTYPE html>
<html>
<head>

<title>Page Two</title>
</head>

<body>

$(‘#two).on(‘pageinit’, function () {

    console.log(‘page two pageinit’);

    Yay();  //Call a function in the parent container, cos Im just injected

});

   

   
       

Two

       

I have an id of “two” on my page container. I’m the second page container in this multi-page template.

   
       

Notice that the theme is different for this page because we’ve added a few data-theme swatch assignments here to show off how flexible it is. You can add any content or widget to these pages, but we’re keeping these simple.

   
       

Back to page “one”

   
   

</div>

</body>
</html>

 

So that being the case where do I stick the code.  Well consider it like this if its a library code stick it in the home page as that outer page is always there and loaded, however when you need stuff to happen that script should be in the page <div> as it will be loaded and injected into the main page container and executed at that point.

There are lots of other things to learn about events and injections but if you can get this bit right then the rest should just follow.

I strongly urge you to read all of the docs on jquery mobile especially around pages as understanding this navigation and the weird vood0o it does with the navigation is key to writing your code in the right place.