[Twisted-web] DOM manipulation in an athena widget

glyph at divmod.com glyph at divmod.com
Sat Sep 30 18:38:54 CDT 2006

On Sun, 01 Oct 2006 00:14:14 +0100, Phil Mayers <p.mayers at imperial.ac.uk> wrote:

>What I'm then trying to do is hook up an event handler to onBlur (or 
>whatever) to compare the old and new values, set a dirty flag and enable the 
>"save" button.

>I couldn't find a way to do this with the Divmod.NotQuiteMochiKit packages 

I assume you're talking about Divmod.Runtime?

>(indeed, they seem wedded to innerHTML), so I whacked MochiKit in the page 
>header and tried this:

Some parts of the Divmod infrastructure still use MochiKit.  We're trying to remove this dependency in the future to allow Nevow users to use whatever version of MochiKit they like, but at least for the time being you can get to the version of MochiKit distributed with Nevow by putting an "//import MochiKit.Whatever" statement at the top of your JS module.

>class Frag(athena.LiveFragment):
>   jsModule = u"db.Record"
>   docFactory = loaders.stan(
>     T.table(render=T.directive('sequence'), data=T.directive('sql'))[
>       T.tr(pattern='item', render=T.directive('mapping'))[
>         T.td[T.slot(name='fieldName')],
>         T.td[
>           athena.handler(event='onclick', handler='editField'),
>           T.span[T.slot(name='fieldValue')],
>         ], # end of td
>       ], # end of tr
>     ])

I don't see a render=T.directive("liveFragment") anywhere, so this fragment is going to be complete garbage by the time it reaches the client.  There really ought to be a warning or something but it's a hard thing for the infrastructure to inspect.

>...and the jsmodule has:
>   function editField(self, node, event) {
>     if (node.inEdit) return false;
>     /* make the textbox */
>     var tb = INPUT({'type': 'text', 'value': scrapeText(node)});
>     /* swap the span for a textbox */
>     replaceChildNodes(
>       getElementsByTagAndClassName('span', null, node)[0], tb
>     );
>     /* THIS FAILS */
>     connect(tb, 'onblur', self.saveField);
>     return false;
>   });
>The nevow debug console thing logs "self has no properties" - what is self 
>in this context of a widget method/event call?

It *should* be an instance of db.Record in this case.

>Why does it have no properties?

I am not completely sure but I have a few theories:

 * You didn't include the appropriate render directive to set up the widget.
 * You didn't set 'self.saveField = XXX' anywhere.
 * You stomped on the version of MochiKit that Divmod was using internally.

>Absent a more complete set of DOM and event handling functions, and given 
>whatever the (to me) unfathomable incompatibility with Mochi and the Divmod 
>runtime is, how does one attach event handlers to client-side created DOM 
>nodes? Are the events normalised cross-browser as they are in Mochi? There's 
>an "xbevent" function in one of the examples that indicates not?

The major "incompatibility" is that it's a huge cost to pay on top of the already too-large Divmod runtime.  We're trying to reduce the dependency so that we don't require all users to pay that cost.  However, far from being incompatible, Nevow *includes* a lightly modified version of MochiKit, and will probably continue to so that you can use it as a "divmod module" in Athena applications, even after the Athena core no longer uses it.

More information about the Twisted-web mailing list