Getting typed JSon in TypeScript using Weld

1. juni 2013 20:32 by admin in .net, DRY, jQuery, MVC, typescript, Weld
Imagine you have a MVC controller exposing a Person as following: 

public JsonResult GetPerson(int id)
{
return Json(new Person
{
First = "Barack",
Last = "Obama"
},JsonRequestBehavior.AllowGet);
}
Now I want to use this client side. I want to update my "first" span with the First property of the person I get back from the server. After messing around I came up with the following: 
$(document).ready(function() {
$.getJSON("/Person/GetPerson/", { id: 4 }, function(data) {
$("#first").text(data.First);
});
});
This took me five minutes to get right (which JQuery method? -> Google, how to pass data? -> find example, plus a typo in the first/First member). Five minutes of stupid getting right what should be trivial. Why not let the compiler help? So using Weld I change my server side method to this :
[AjaxMethod]
public JsonResult<Person> GetPerson(int id)
{
return new JsonResult<Person>(Json(new Person
{
First = "Barack",
Last = "Obama"
}, JsonRequestBehavior.AllowGet)); ;
}
Basically I wrap my JsonResult in a generic wrapper JSonResult<T> (included with Weld) so that Weld knows what type to expect. Next I add the AjaxMethod Weld attribute. Client side I use TypeScript and use the generated proxy class.  
/// <reference path="Weld/PersonController.ts" />/// <reference path="typings/jquery/jquery.d.ts" />
$(document).ready(function () {
PersonController.prototype.GetPerson(2, (person) => {
$("#first").text(person.First)
});
});
Now person is a JavaScript object or a TypeScript 'any' type. No, Person is a fully defined TypeScript interface with a First and Last member just like my C# class. Here's the generated code:
/// <reference path="../typings/jquery/jquery.d.ts" />
class PersonController
{
GetPerson(id: number, callback: (data: Person) => any)
{
var url = "/Person/GetPerson";var data = { id: id };
$.ajax({
url: url,
type : "POST",
data: data,
success: callback,
});
}
}
interface Person
{
First: string;
Last: string;
}
As always in the end there is still JavaScript code generated which you can easily debug. Weld code is simple and clean. Easy huh? And there are more benefits:
  1. If I remove or rename my action-method the TypeScript compiler will detect my breaking client side code at compile time. If you just use javascript you will (hopefully) find out at runtime.
  2. If I add or remove properties from my Person class my changes will cascade to the clientside immediately. 
  3. I get a nice interface clientside making code completion really work 
  4. No more Googling JQuery methods
  5. This is more DRY (Don't Repeat Yourself). For example if you don't like JQuery you can build a Weld template using a different method. Regenate and you are ready
Weld is fully open source and can be found at weld.codeplex.com

Generating TypeScript proxy classes for Ajax Methods using Weld

1. juni 2013 19:30 by martijn in .net, jQuery, MVC, typescript, Weld

In this post I want to talk about a little tool called Weld I wrote to make integrating client-side TypeScript and server side MVC C# easy. 

Imagine you have a server-side method that calculates some value you want to use client side. In this sample project I want to calculate the sum of two values I have in input fields.

image

image

Server-side I have this action-method in my home controller.

public int Sum(int x,int y)
{
return x + y;
}
Now to access this method client I just need to add a Weld attribute. For this I first install Weld using NuGet. 
Just “Install-Package Weld” in your NuGet package manager console. This will install Weld as well a TypeScript.Compile and JQuery typings into your project. 
TypeScript.Compile auto compiles all your typescript files post-build. This enables you to detect any problems caused by server side changes. 
The basic process :
  1. Normal compilation
  2. Weld generates TypeScript code for the classes your decorated with Weld attributes
  3. TypeScript compiles all files in your project with build actions 'TypeScriptCompile'
For this sample I add the AjaxMethod (Weld.Attributes.AjaxMethod) attribute to the ‘Sum’ action. 
Compile the project. Weld now has generated a proxy class for my home controller. I just need to include it and used it in the project. It is located in the /Scripts/Weld folder. 
I add the generated homecontroller.ts to my project. I my main TypeScript file I write the following to hook it all up:
/// <reference path="Weld/HomeController.ts" />/// <reference path="typings/jquery/jquery.d.ts" />
$(document).ready(function () {
$("#btnSum").click(function () {
HomeController.prototype.Sum($("#number1").val(), $("#number2").val(), (result) => {
$("#result").text(result);
});
});    
});
As you can see the details of the Ajax communication are handled by weld and you get a nice interface to your server side API :)
 

Creating a Yes/No toggle switch for a boolean property in ASP.MVC

11. mei 2013 13:20 by admin in .net, jQuery, JQuery UI, MVC

When editing boolean values in MVC the default option is to use a checkbox. This results in the following Create page when using the default scaffolding

image

This is fine and works OK but sometimes you want something more..’fancy’. ASP.NET MVC ships with Jquery.UI so why no use the slider of JQuery.UI to create a nice toggle switch?

In this post I will use and modify a JQuery.UI plugin that will result in the following. The plugin is based on http://taitems.github.io/UX-Lab/ToggleSwitch/ which had some errors in my opinion.

image 

There are a two parts to this:

  1. Create a HTMLHelper extension method that renders a <select> element for the boolean property with <option> elements for true and false
  2. Change the rendered <select> element to a jquery slider using a JQuery.UI plugin

Creating the HTMLHelper

public static class HtmlHelperExtensions
{
public static MvcHtmlString ToggleSwitchFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression)
{
return htmlHelper.DropDownListFor(expression, new[]
{
new SelectListItem { Text = "No", Value = "false" },
new SelectListItem { Text = "Yes", Value = "true" } 
}, new { @class = "toggleswitch" });
}
}

This adds a HTMLHelper method that renders a dropdown list which comes down to a single select HTML element. There are two options in the select : one for true and one for false. To use it we just do 

@Html.ToggleSwitchFor(model => model.CommentsEnabled)

And we get the following html

<select class="toggleswitch" data-val="true" data-val-required="The CommentsEnabled field is required." id="CommentsEnabled" name="CommentsEnabled"><option value="false">No</option><option value="true">Yes</option></select>

This is all what we need to get our JQuery plugin going.

Creating the JQuery plugin

The plugin uses the JQuery.UI slider to create a toggle switch. This means that any styling or theme you might have for the slider will work for the toggle as well. The plugin transforms the select element into two labels with a slider in between. When you click on a label or move the slider the select control will be updated as well and when you do form post the values get updated. The http://taitems.github.io/UX-Lab/ToggleSwitch/ had two errors when I tried it

  1. The change event was just passing the change event of the slider. This meant even if the boolean property did not change (you moved the slider a little) you would still get a change event. In this version the change event is only fired when the value really changed.
  2. The plugin did not allow chaining.
  3. The normal ‘change’ event of JQuery was no longer fired. This is fixed by not having a change event on the control itself but just fire the existing change event.

To use it you need to add the CSS and JS of the plugin to your page. You also need the default JQuery UI js and css (which is not referenced by default!). Once you have done that you can activate the plugin for a control:

$(document).ready(function () {
$("#CommentsEnabled").toggleSwitch().change(function() {
alert("Changed!!");
});
});

I attached a sample MVC application as well as the JQuery.UI.ToggleSwitch plugin.

ToggleSampleMVC4.zip (771,1 KB)
jquery.ui.toggleswitch.zip (1,73 KB)