Brian J. Cardiff

Brian J. Cardiff

Brian (aka Branch), our official blues and swing dancer, is a developer lead always motivated to learn new things, who makes use of every opportunity to both teach and learn from his colleagues. He is particularly interested in information visualization, and developed his master thesis in relational formal methods in Computer Science at UBA.

Declarative jQuery (with Microsoft Ajax)

Almost everybody likes jQuery, I’m one of them. Recently Microsoft publish Client Templates preview 3 which is a awesome client side template engine. One of the best aspects of Client Templates is it’s declarative syntax for attaching behaviors (Sys.UI.Behavior) to a DOM element.

Following I expose the plugin jquery.declarative which allows you to use in a declarative way another jQuery plugin.

N.B.: Along this post I will use a plugin called wajbar, which is near to be published in jQuery plugins directory.

You can download the source code here.

jQuery way

Usually jQuery plugins extend the jQuery interface in simple way:

$(<selector>).<method>(<options>)

for example:

<input type="text" maxlength="60" size="30" id="text1" />
<script type="text/javascript">
    $(function() {
        $('#text1').wajbar();
    });
</script>

Nothing wrong, but thing could turn ugly if you have a lot of plugins and components all around.

declarative way

In order to use a declarative syntax for a plugin named P, you have the following requirements:

  • jQuery core
  • Microsoft Ajax (MicrosoftAjax.js)
  • Microsoft Ajax Templates (MicrosoftAjaxTemplates.js)
  • jQuery Declarative plugin (jquery.declarative.js)
  • jQuery P plugin which should use syntax: $(<selector>).<method>(<options>);
  • Add xmlns:sys=”javascript:Sys” sys:activate=”*” attributes to your body tag.

Note: If you are using a ScriptManager you already have Microsoft Ajax. Microsoft Ajax Templates and jQuery Declarative plugin in must be referenced within the ScriptManager. Otherwise just include the references in that order.

After referencing, you would need to expose the plugin P to jquery.declarative:

//general syntax
// $.declare(<entry method name of P>);
$.declare('wajbar');

This is need just once, usually when DOM ready is ready.

Now, for using a wajbar you need to attach it.

<input type="text" maxlength="60" size="30" sys:attach="wajbar" />

That’s it. Have in mind that using multiple times jquery plugins will be less obstructive this way. No need for additional CSS classname or IDs for later selecting the desired element.

using arguments in plugin initialization

I mention before that jquery plugins usually supports options to be passed in initialization: $(<selector>).<method>(<options>);. For example the wajbar support passing a ‘submit’ property to indicate a DOM that should be disabled if the input value is longer than maxlength.

Given:

<input type="text" maxlength="20" size="40" id="text1" />
<input type="submit" value="submit" id="button1" />

using plain jQuery you would need to call

$('#text1').wajbar({submit: $('#button1')});

but the declarative alternative is now

<input type="text" maxlength="20" size="40"
   sys:attach="wajbar"
   wajbar:submit="{{ $('#button1') }}" />
<input type="submit" value="submit" id="button1" />

you can even get further and remove all the ids of your code and make them really reusable!

<input type="text" maxlength="20" size="40"
   sys:key="self"
   sys:attach="wajbar" 
   wajbar:submit="{{ $(self).next('input:submit') }}" 
/>
<input type="submit" value="submit" />

It’s a bit more complicated the last, but is 100% reusable. With sys:key attribute you said how you want to expose the current DOM element in the evaluation within {{ }}.

ajax partial page load

In order to use the declarative syntax in with partial page rendering you need to call

Sys.Application.processNode(<the new dom element>);

Either the partial page executes that or hook per ajax loaded content, this depends on site conventions.

more than one plugin

This new syntax allows more than one plugin, each with their initialization options. You just need to enumerate the plugins separated by a comma.

For example using the tagSuggestion plugin:

<script src="tag.js" type="text/javascript"></script>
<link href="tag.css" rel="stylesheet" type="text/css" /> <script type="text/javascript">
    $(function() {
        $.declare('wajbar');
        // fake suggestions
        setGlobalTags(['javascript', 'jquery', 'java', 'json']);
        $.declare('tagSuggest');
    });
</script>

Create an input with wajbar and tag suggestion:

<input type="text" maxlength="30" sys:attach="tagsuggest, wajbar" />

Note that the declarative names are lowercase always, no matter the case of the method name, since the namespaces are always lowercase.

PDC Essentials @ Buenos Aires

Updated November 20th, you can download slide and demos here.

On Tuesday 18th, Juan and I will be presenting ASP.NET 4.0 Roadmap. Check which other talks are available and register here.

This is the event information:

  • Horario: martes, 18 de noviembre de 2008 16:00 – 22:00 p.m.
  • Lugar: ITTC. Sarmiento 1113 Piso 5. Buenos Aires Argentina.
  • Registración
  • Descripción:Durante los días del 27 al 30 de Octubre se lleva a cabo la Professional Developer Conference en Los Angeles, Estados Unidos. Durante este evento Microsoft realiza grandes anuncios sobre novedades en la plataforma de desarrollo, presentando su visión de Cloud Computing, construyendo aplicaciones que desdibujan las barreras entre la PC, la Web y los dispositivos móviles, lo nuevo en VS 2010, .net Framework 4, distintos avances sobre Windows 7, la siguiente mayor versión de la plataforma cliente Windows y mucho más. En este evento, estaremos presentando algunas de las novedades develadas durante el evento, contando con disertantes asistentes al mismo.

jQuery for Script#

Quite a good title :-) . Some weeks ago I find the time to create proof of concept for that task: create a jQuery wrapper for Script#. The result is a partial wrapper that could be completed to support all in all jQuery functionality.

The main issues I encountered while developing were:

  • Write a Script# adapter
  • Adapt event handlers interfaces
  • Support jQuery overloads

At the same time I was learning a bit of Microsoft Ajax Client-Side Templates (preview 2), part of ASP.NET AJAX 4.0, which are not in preview 3 stage. I also had to to a minimal script# adapter for this, but it was totally ad-hoc.

Due to the dependence with Microsoft Ajax, aacorlib Script# engine is used, which doesn’t support some C# features like foreach.

Write a Script# adapter

First of all you need to read some Script#. Then need realize that anycode that depends on a Script# adapter is not testable unless you implement some basic behavior of the adapted component.

For example the wrappers usually returns null, or default(T), for a function that it’s return type is T.

jQuery use a fluent interface, so returning this instead of null
will allow a minimal chance be testable (to avoid spurious runtime null pointer exceptions.

Adapt event handlers interfaces

With jQuery an event handler is declared as follows:

var anchors = $("a");
anchors.click(function(){
    var target = $(this).attr('href');
    alert('anchor to ' + target + 'clicked.');
});

In C# the this keyword is binding to the current class, not as in Javascript. This force the full creation of a wrapper, previously I tried to just have a trivial wrapper with the ImportedAttribute
in every method, but wasn’t enough.

After some tweaks I finally got this to work:

jQuery anchors = jQueryApi.Select("a");
anchors.click(delegate(object sender){
    string target = jQueryApi.Select(sender);
    Script.Alert("anchor to " + target + "clicked.")
});

And the “implementation” magic code is:

public class jQuery {
    // ...
    public jQuery click(EventCallback fn){
        Script.Literal("{0}.click(function(){{ return {1}(this); }})", _jquery, fn);
        return this;
    }
}

Support jQuery overloads

In Script#, Javascript overloads are declared as extern
methods with AlternateSignatureAttribute
. What I try to get was a easy way to implement jQuery overloads. The
Function.apply
method was very useful.

In the following code it is shown how jQuery.attr methods are adapted, and how jQuery wrapper is maintained. It’s not very nice, but is what is needed to get this works.

public class jQuery
{
    [AlternateSignature]
    public extern string attr(string key);
    public jQuery attr(string key, string value)
    {
        object r = Script.Literal("{0}.attr.apply({0}, arguments)", _jquery);
        if (r == _jquery) // preserve jQuery wrapper
            return this;
        else
            return (jQuery) r; // cast for compilation, it will return corresponding type
    }
}

Sample Application

Doesn’t do much:

  1. Gets a hardcoded list of TODOs in JSON
  2. Unfold template using Client-Side Teamplates
  3. Add behavior to unfolded DOM

All this is implemented in Script# using an MVP pattern. Algo in Views/Tasks/Layout.aspx there is a commented Javascript implementation.

You can download the solution here.

Haskell Monads on the web

Yesterday I spent some time reading about Haskell implementations of Monads because I want to prepare some exercise. I share some links and snippets.

  • http://www.haskell.org/tutorial/monads.html
  • http://www.haskell.org/haskellwiki/Monad
    • Laws & syntax
    • Monads in other languages
  • Philip Wadler / Monads
    • The essence of functional programming
      • This paper explores the use monads to structure functional programs. No prior knowledge of monads or category theory is required.
      • Monads increase the ease with which programs may be modified. They can mimic the effect of impure features such as exceptions, state, and continuations; and also provide effects not easily achieved with such features. The types of a program reflect which effects occur.
      • The first section is an extended example of the use of monads. A simple interpreter is modified to support various extra features: error messages, state, output, and non-deterministic choice. The second section describes the relation between monads and continuation-passing style. The third section sketches how monads are used in a compiler for Haskell that is written in Haskell.
    • Monads for functional programming
      • The use of monads to structure functional programs is described. Monads provide a convenient framework for simulating effects found in other languages, such as global state, exception handling, output, or non-determinism. Three case studies are looked at in detail: how monads ease the modification of a simple evaluator; how monads act as the basis of a datatype of arrays subject to in-place update; and how monads can be used to build parsers.
  • http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm
    • So far we’ve seen the monad concept applied to implicitly passing state. However monads can be used to implement several other programming features including: consuming input, producing output, exceptions and exception handling, nondeterminisim. To handle this variety, the basic operations of >>= and return are overloaded functions.
    • Monads and Software Engineering
      • The key to engineering a large software project is to make changes easy..
      • Monads can be used to make functional programs far more adaptable. You need to insert another processing step? Go right ahead, don’t worry about plumbing the state. You need another variable in the state? No problem, just change the underlying state and the basic members of the monad. You need to output messages from your computation? No problem, just change the monad to add an output string. You need to handle exceptions or nondeterminism? No problem, just change the monad.
      • It might be said that Haskell with monads does not give you much that you won’t find in an imperative, nondeterministic language, with extensible, strong, but generic typing, and a powerful applicative expression sublanguage. The problem is there is no such language in common use. Monads make up for many of the drawbacks of Haskell relative to imperative languages, but without giving up any of its strengths.
  • http://en.wikibooks.org/wiki/Programming:Haskell_monads
    • Simple example for generation random numbers with a seed.
  • http://logic.csci.unt.edu/tarau/research/PapersHTML/monadic.html
    • `monad-based’ approach to the definition of all-solution predicates in lambdaProlog. As a follow-up, we obtain a clarification of Prolog’s high-order operators and their similarities and differences with monad comprehensions in functional languages.