Monday, May 26th, 2008

Declarative Syntax for Widgets

Category: JavaScript, Library

Jeff Watkins is updating his MVC library, Coherent, and is wondering if he should add declarative syntax for child widgets. Currently, you have to write a lot of init() setup code, but instead he would like to do something like:

javascript

  1. sample.MyWidget= Class.create(coherent.Widget, {
  2.  
  3.     init: function()
  4.     {},
  5.  
  6.     title: TextWidget('div.header em', {
  7.                 htmlKeyPath: '*.selection.title',
  8.  
  9.                 onclick: function(event)
  10.                 {
  11.                     ... handle clicking on the title ...
  12.                 },
  13.                 ... etc ...
  14.             }),
  15.  
  16.     nextButton: Widget('div.controls button.next', {
  17.                     onclick: function(event)
  18.                     {
  19.                         ... go to the next image ...
  20.                     }
  21.                 }),
  22.     ... etc ...
  23. });

Just before calling init, the Widget framework should create sub-widgets for title and nextButton. For the title, its html binding would be connected to the key path selection.title from the outer widget. Additionally, a click handler would be created with the given method. The scope of the onclick method for title would be MyWidget rather than the actual TextWidget.

Using the new Selector library, you could create widgets based on any CSS query rather than just a direct descendant or ID. I don’t think there’s any need to have sub-widgets within the sub-widgets. If that’s what you’re looking for, you probably want to look at creating a widget rather than declaring the structure.

How does that look? Any advice for Jeff?

Posted by Dion Almaer at 9:36 am
5 Comments

+++--
3.2 rating from 12 votes

5 Comments »

Comments feed TrackBack URI

This definitely looks like a step in the right direction.
Funny, I was just trying to wrap my head around the perfect syntax for declarative declaration of widgets using Joose and jQuery.

I’m not totally there yet. This is my work in progress using an abstract class for widgets and a custom meta class that defines the special class builder “events”:

Class("Button", {
isa: Widget,

has: {
message: {
init: "hello world"
}
},

events: {
click: function () {
alert(this.message)
},
dblclick: function () {
alert("please only click once :)")
}
}
})

Comment by Malde — May 26, 2008

The UIZE Framework supports declarative syntax for widgets using “passive” JSON objects inside script tags. Widgets declared in this way are adopted by the page widget (the main controller for the page). Any arbitrary structure of widgets can be declared in this way. What’s more, multiple declarations are “stitched” together into a single tree, so declarations can be flexibly split apart, so that the data governing the widgets can come from various server generated components. You can use the “children” propery or not. Furthermore, UIZE allows merely data declaration for widgets that are created in the page widget construction code, so the declarative data is “scooped” out of the page and consumed by the corresponding widgets. UIZE avoids using non-standard attributes in the markup for data declaration. For one thing, UIZE believes in the goal of validation of documents. Additionally,
attributes strings are rather limiting on the kind of data structure that ca n be specified for widgets. Try declaring a product grid widget’s data records in HTML attributes! Good luck with that ;-)

http://www.uize.com

Comment by uize — May 27, 2008

Oh, and here’s an example page that uses the declarative syntax supported by the Uize.Widget.Page base class of the UIZE Framework…

http://uize.com/examples/slideshow-with-dissolve.html

The syntax used in this example page is as follows…


$page_slideShow = {
widgetClass:'Uize.Widget.SlideShow',
slides:slidesPhotos,
children:{
slideImage:{
widgetClass:'Uize.Widget.Swap.Image',
width:350,
height:250,
built:false
},
slideRating:{
widgetClass:'Uize.Widget.Bar',
orientation:'horizontal',
minValue:0,
maxValue:10
}
}
};

JS modules for the widgets are loaded dynamically by the Uize.module method. A widget tree is defined in this declaration, looking as follows…

page
page.children.slideShow
page.children.slideShow.children.slideImage
page.children.slideShow.children.slideRating

Of course, the slide show widget also add its own child widgets for the navigation buttons.

Comment by uize — May 27, 2008

   OK, not having indentation officially sucks!

Comment by uize — May 27, 2008

But if I use my text editor to replace leading spaces with nbsp entities, you get something pretty…

$page_slideShow = {
   widgetClass:’Uize.Widget.SlideShow’,
   slides:slidesPhotos,
   children:{
      slideImage:{
         widgetClass:’Uize.Widget.Swap.Image’,
         width:350,
         height:250,
         built:false
      },
      slideRating:{
         widgetClass:’Uize.Widget.Bar’,
         orientation:’horizontal’,
         minValue:0,
         maxValue:10
      }
   }
};

Comment by uize — May 27, 2008

Leave a comment

You must be logged in to post a comment.