Declarative jQuery (with Microsoft Ajax)

Posted in Ajax,jQuery by bcardiff on the December 3rd, 2008

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.

20 Responses to 'Declarative jQuery (with Microsoft Ajax)'

Subscribe to comments with RSS or TrackBack to 'Declarative jQuery (with Microsoft Ajax)'.


  1. on December 3rd, 2008 at 6:15 pm

    [...] Vote Declarative jQuery (with Microsoft Ajax) [...]


  2. on December 3rd, 2008 at 6:19 pm

    [...] Vote Declarative jQuery (with Microsoft Ajax) [...]


  3. on December 10th, 2008 at 4:59 am

    [...] Brian likes our declarative syntax. And jQuery. And he did something quite fun with them, something we had clearly not anticipated: using Microsoft Ajax’s new declarative [...]


  4. on December 10th, 2008 at 5:11 pm

    [...] Brian J. Cardiff » Declarative jQuery (with Microsoft Ajax) . 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. (tags: weblogs.manas.com.ar 2008 mes11 dia10 jQuery declarative Ajax) [...]

  5. Steve said,

    on December 30th, 2008 at 3:03 am

    I’m at odds with this:

    Its far too intrusive.

    How about:

    <script….
    $.declare(’.wajbar’);

    html:

    I do this now in asp.net mvc – ie. a tablesorter

    $(“.tablesorter”).tablesorter(); //plugin

    table class=tablesorter

    jQuery is ALREADY attaching behaviors -right? This is how css and javascript work together.

    Sys.UI.Behavior is fine but I don’t really see the value of creating these unnatural attributes on my html elements, when it can be already done with classes ?

  6. Steve said,

    on December 30th, 2008 at 3:05 am

    It ate my html sorry

    <script….
    $.declare(’.wajbar’);

    html:

    should be

    input type=”text” maxlength=”60″ size=”30″ class=”wajbar”

  7. Steve said,

    on December 30th, 2008 at 3:08 am

    sorry, one more:

    jquery plugin == attaching ‘behavior’

    plugins are very easy to follow – no harder than the customer MS library js classes that I have used. I shifted over to jquery as it is easy to attach ‘behavior’s to any element. I feel it’s more intuitive and less obstrusive


  8. on December 30th, 2008 at 9:31 am

    @Steve,

    Once you have called $.declare(plugin_name) the markup I think is much more declarative. You leave css attribute for style manner and use sys:attach for attaching behaviors.

    I don’t like much mixing behaviors and styles in same class attribute, but I understand is the used way nowadays.

    A good point with MS syntax is that the configuration of the behavior is much more natural: with the element instead of doing it in a script tag, for example:

    <input type=”text” sys:attach=”autocomplete” autocomplete:url=”/ac” />

    Don’t you agree?

    The drawback is that the syntax requires a Sys.UI.Behavior but that is encapsulated in the plugin I introduce in this post.

    The sys:attach is 100% valid xhtml, is a new xmlns but I don’t think it will turn so unnatural.

    Thanks for the feedback! I really appreciate it.


  9. on January 29th, 2009 at 7:55 pm

    Dear Brian,

    Thanks for this awesome plugin.

    Is it possible to make the plugin in a way, so that it affects on textarea, maxlength?

    Cheers,
    Jake


  10. on January 29th, 2009 at 8:07 pm

    @Jake, the jquery.wajbar already works with textareas, the only minor issue is that maxlength is not a valid attribute for textareas.

    I still have pending to publish it on jquery plugins repository…


  11. on January 30th, 2009 at 5:03 pm

    Hey Brian,

    I’m sorry, I’m stupid about jQuery, and fairly new to it. I really like the functionality of it. And what I’d like to know is that, is there a way to specify the maxlength for textarea, without specifying it in html element—in other words, doing it manually, by adding some specs in the script itself?

    Thanks again,
    Jake


  12. on January 31st, 2009 at 12:48 am

    @Jake, I have uploaded at http://bcardiff.googlepages.com/jquery.wajbar.zip a demo of how to use the jquery.wajbar plugin. It includes one with textarea. Currently the maximum expected chars is grabbed from a maxlength attribute. If this isn’t enough for you to start using it, please tell me.


  13. on January 31st, 2009 at 4:53 pm

    Hi Brian, dearest friend!

    Thank you so much, you’re a wonderful person! Now it works and it’s dandy! :)

    Thanks! thanks! thanks!

  14. Venkata U. Lakkakula said,

    on April 4th, 2009 at 9:07 pm

    Nice work Brian,

    Does this work only with external plug-ins like “wajbar” or even with built in jQuery method calls like “Ajax/Load – load(url, data, callback)”?

    What I am trying to do is something like this:

    $(function() {
    $.declare(‘load’);
    });

    ………

    My intent here is to make an ajax/get call to a controller method and insert the return html inside the div tag. This tag is inside a client template. So, for each div tag created (through client template) I want different content displayed based on contentId.

    Unfortunately this is not working. Can you please let me know what I am missing here? Is there any another easy way to achieve same thing?

    Appreciate your help.

  15. Venkata U. Lakkakula said,

    on April 4th, 2009 at 9:12 pm

    Oops my html was trunkated… here it is without tags
    div class=”content” id=”content_{{contentId}}” sys:attach=”load” load:url=”/Controller1/GetContent/{{contentId}}”
    img src=”../../Content/Images/loading.gif” alt=”loading…”
    div


  16. on April 5th, 2009 at 2:24 am

    @Venkata,

    1. jQuery plugins usually have an option object parameter, and not simple parameters like jQuery load method. Your code will end up by executing $(domElement).load({url: ‘some.htm’}); which is not right way.
    2. One simple alternative will be to create a jQuery plugin that just expose another interface to the load method (one that can get an option object). I have create a sample of this here.
    3. I think it would be good to support this kind of methods out of the box, maybe calling $.declare(methodName, parameterName1, parameterName2, …, lastParameterName) is a way to tell how argument should be passed.
    4. Finally, I think you should use attr=”{{ ‘abc_’ + foo }}” instead of attr=”abc_{{ foo }}”.

    Hope you find useful the sample code. Also you will find a demo that shows the datepicker working. I used latest version of jQuery and Ajax Templates without changes on jquery.declarative :-) .

  17. Venkata U. Lakkakula said,

    on April 6th, 2009 at 12:33 pm

    Brian, Thanks a ton! how nice of you to write a sample for me!! You Rock!!!

  18. Prashant said,

    on August 3rd, 2009 at 2:58 pm

    Hi Brian
    Thank you for all you effort.
    I am trying to load a user control via an asmx service call, similar to the sample by Dave Ward, here
    http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/
    I downloaded your sample from http://bcardiff.manas.com.ar/drops/2009/04/jQueryDeclarative-AjaxLoad/index.htm and it works fine for the static content, however I can get it to call the asmx to load the usercontrol

    Thanks
    Prashant


  19. on August 3rd, 2009 at 3:25 pm

    Prashant,

    In this post I covered how to use jquery plugins with ASP.NET AJAX Client Templates behavior syntax. Is independent of what you are doing in the jQuery side, either load content, load json, or manipulate the DOM. I guess you read http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/ in order to return the rendering of an .ascx in an .asmx call, right?

    I’m not sure how the topic I covered in this post affect what you are trying to do.

  20. Prashant said,

    on August 3rd, 2009 at 5:00 pm

    Brian,

    I am trying to render the usercontrol into a div by doing:

    Instead of having to do:

    $.ajax({
    type: “POST”,
    url: “webservGetNames.asmx/GetNamesOfPeople”,
    data: “{}”,
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: function(msg) {
    $(‘#PeopleContent’).html(msg.d);
    }
    });

    Hope I answered your question

    Thanks
    Prashant

Leave a Reply