Friday, 29 March 2013

Animated Listbox

This example shows a nice fluid movement for items in a wrapping listbox.

Demo

Click here to open the Silverlight page and resize your browser: 

http://stevenhollidge.com/blog-source-code/animatedlistbox

Source code

SL version:  https://github.com/stevenh77/AnimatedListboxSL

WPF version:  https://github.com/stevenh77/AnimatedListboxWPF

Dynamic Layout and Transitions in Silverlight

There’s a fantastic video from Mix 10, given by speaker Kenny Young:

http://channel9.msdn.com/Events/MIX/MIX10/CL55

Here’s the Silverlight project from the video running:

The source code doesn’t seem to be available online anymore so I contacted him and managed to track down the files.

Or here’s a link to the demo: 

http://stevenhollidge.com/blog-source-code/dynamiclayoutandtransitions/

Or download the source, updated for Silverlight 5 here:

https://github.com/stevenh77/DynamicLayoutAndTransitions

Tuesday, 12 March 2013

Fiddler Extension: JsonpViewer

Here’s an example of a Fiddler Extension I started building for CORS workarounds using JsonP.

https://github.com/stevenh77/JsonpViewer

Some background, I’m currently using Jsonp for cross domain service calls.  As only GETS are allowed, and I want to pass data to my services as Json, I add a request query parameter which is URI encoded.  In order to debug and cleanly read the object I’ve added a inspector to Fiddler to extract this object, decode it and display within fiddler UI.

I’ve also wrote this blog post to remind me how to create an extension next time.

image

Here we can see a Json object being passed via a URI encoded HTTP GET request:

GET http://localhost:2626/api/dealdates?request=%7B%22strikeAbsolute%22%3A0.0%2C%22strikePips%22%3A1000.0%2C%22markupAbsolute%22%3A0.0%2C%22markupPercentage%22%3A0.0%2C%22clientPriceAbsolute%22%3A5.0%2C%22clientPricePercentage%22%3A0.1%2C%22currencyPair%22%3Anull%2C%22spotAsk%22%3A0.0%2C%22notional%22%3A0.0%2C%22expiry%22%3A%220001-01-01T00%3A00%3A00%22%7D HTTP/1.1
User-Agent: Fiddler
Host: localhost:2626

Click over into my new “Json Query Params” window and you get the Json object nicely formatted and display:

image

Notes:

This extension currently relies upon the JSON object being passed as “?request=” as this fit my pattern and needs.

The example above uses the same json for both the request and response, as I was too lazy to create another object and it’s late now so almost time for bed…

If you’re interested in building your own extension here’s some tips:

1. Grab my source code as a reference:  https://github.com/stevenh77/JsonpViewer

2. Switch on logging within Fiddler:

Alt + Q opens the ExecAction command line (lower left hand corner, the black bar)

Enter the following commands:

prefs set fiddler.debug.extensions.verbose True

prefs set fiddler.debug.extensions.showerrors True

image

To confirm your settings have been updated enter this command:    about:config

image

3. Now when you open Fiddler you can select the log tab to see your extension loaded.

Remember:  When deploying your class library, the DLLs for Inspectors go in the {program files}\Fiddler2\Inspectors folder

image

4. If your DLL isn’t loading remember to add a Fiddler.RequiredVersion attribute to the AssemblyInfo.cs file.

image

6.  Build your project as .NET Framework 2 or 4.  I dont think Framework 4.5 is not supported yet but I havent tested that.  My project was built with .NET 2.0 and later upgraded to .NET 4.0.  Both worked great the my version of Fiddler (4.4.3.0)

image

Good luck!

Sunday, 10 March 2013

JavaScript chart

Quick chart using a JavaScript library called HighChart.

Online demo:  http://stevenhollidge.com/blog-source-code/javascriptchart/

Source code

<html>
<head>
<title>JavaScript chart</title>

<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js'></script>
<script src='http://code.highcharts.com/highcharts.js'></script>
<script src='http://code.highcharts.com/modules/exporting.js'></script>

<script>
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Crystal Palace vs Millwall',
x: -20 //center
},
subtitle: {
text: 'Source: http://www.crystalpalace-mad.co.uk',
x: -20
},
xAxis: {
categories: ['83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13']
},
yAxis: {
title: {
text: 'League Position'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'
this.x +': '+ this.y +'°C';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'Crystal Palace',
data: [35, 38, 35, 29, 30, 30, 27, 15, 3, 10, 20, 21, 19, 23, 26, 20, 34, 35, 41, 30, 34, 26, 18, 26, 32, 25, 35, 41, 40, 37, 24]
}, {
name: 'Millwall',
data: [61, 53, 46, 39, 40, 25, 10, 20, 29, 39, 27, 23, 32, 42, 58, 62, 54, 49, 45, 24, 29, 30, 30, 43, 54, 61, 49, 47, 29, 36, 40]
}]
});
});

});
</script>
<head>
<body>

<div id='container' style='min-width: 400px; height: 400px; margin: 0 auto'></div>

</body>
</html>

Responsive design main menu

Responsive design main menu to window resizing.

image

image

image

image

Online demo:  http://stevenhollidge.com/blog-source-code/responsivedesignmenu/index.html

Same HTML, responsive design using CSS media queries.

Tuesday, 5 March 2013

Move labels in CSS depending on view size

On a small device I’d like my labels above my textboxes:

On a larger device I’d like my labels to be on the left of my input boxes:

Here’s how:

<html>
<head>
<style>

@media (max-width: 400px) {
#content {
margin: 50px;
}
#labelContainer {
width: 0px;
}
#content label {
display:inline-block;
}
}

@media (max-width: 5000px) {
#content {
margin: 50px;
}
#content label {
display:inline-block;
}
}
</style>
<body>
<div id="content">
<div id="labelContainer">
<label>First name:
<input type="text" />
</label>
</div>
<div id="labelContainer">
<label>
Last name:
<input type="text" />
</label>
</div>
</div>
</body>
</html>

Saturday, 2 March 2013

Calling cross domain without Jsonp

Thanks to Simon Cropp @simoncropp (creator of NotifyPropertyWeaver project amongst other great projects) for pointing out that you shouldn’t need to jump through the hoops of using Jsonp.

http://enable-cors.org

http://www.html5rocks.com/en/tutorials/cors/

http://stevenhollidge.com/blog-source-code/cors   (using Javascript XMLHttpRequest rather than jQuery)

My example was taken from html5rocks website, then stripped back to contain only the cors code

Use this page to test CORS requests:  http://client.cors-api.appspot.com/client

Initially, I had been using jQuery to make my requests but their lack of support for cors with IE had led me down the wrong path:  http://bugs.jquery.com/ticket/8283

To enable CORS on your ASP.NET web server, for example for Web API, you need to add the following to your web.config:

<system.webServer>

<!-- enable cors -->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>

How to return Jsonp from WebApi

This allows you to make service requests from jQuery to a different domain (cross site scripting).

1. Add a Formatters folder to your WebApi project and add the following class:

public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private readonly HttpRequestMessage _request;
private string _callbackQueryParameter;

public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));

MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", "application/json"));
}

public JsonpMediaTypeFormatter(HttpRequestMessage request)
: this()
{
_request = request;
}

public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}

public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
if (type == null)
throw new ArgumentNullException("type");
if (request == null)
throw new ArgumentNullException("request");

return new JsonpMediaTypeFormatter(request) { SerializerSettings = SerializerSettings };
}

public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(_request, out callback))
{

var writer = new StreamWriter(stream);
writer.Write(callback + "(");
writer.Flush();

return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith(_ =>
{

//TODO: Inspecting the task status and acting on that is better
writer.Write(")");
writer.Flush();
});
}

return base.WriteToStreamAsync(type, value, stream, content, transportContext);
}

private bool IsJsonpRequest(HttpRequestMessage request, out string callback)
{
callback = null;

if (request == null || request.Method != HttpMethod.Get)
{
return false;
}

var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
callback = query[CallbackQueryParameter];

return !string.IsNullOrEmpty(callback);
}
}
image

2. Add a FormatterConfig class to your App_Start folder

public class FormatterConfig
{
public static void RegisterFormatters(MediaTypeFormatterCollection formatters)
{
formatters.Remove(formatters.JsonFormatter);
formatters.Insert(0, new JsonpMediaTypeFormatter
{
SerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}
});
}
}
image

3. Update your Global.asax.cs file to register the FormatterConfig

public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
FormatterConfig.RegisterFormatters(GlobalConfiguration.Configuration.Formatters);
}
}

That's it!


How to test your service call


Now your services can be called for Json or Jsonp.


Json


You can continue to get your Json response in the normal way:  http://localhost:2626/api/underlyings


image



image


image


Jsonp


You can now call your service passing in the callback to receive Jsonp:

$.getJSON("http://localhost:2626/api/underlyings/jsonp?callback=?", function (result) {
// process response
});

You’ll see here that the response wraps the data in a jQuery function.


image


image


image


Here’s the HTML code I used in this example:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Jsonp test</title>
<script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
</head>
<body>
<button id="getjsonp">Get JSONP</button>
<h4>Request result:</h4>
<div id="jsonp"></div>

<script type="text/javascript">
$(document).ready(function () {
$("#getjsonp").click(function () {
$.getJSON("http://localhost:2626/api/underlyings/jsonp?callback=?", function (result) {
$(result).each(function(index, item) {
$('#jsonp').append('<p>' + item.currencyPair + '</p>');
});
});
});
})
</script>
</body>
</html>





For a working downloadable example I recommend downloading the WebApiContrib solution for Jsonp:


https://github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp