Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Notes on Teaching JavaScript

For the past few months, I've been tutoring a friend in JavaScript, and I've rediscovered some trite knowledge anew: there's no better way to improve in a subject than to teach it.

My friend and I come at programming JS from different directions: he's primarily a Web designer who uses jQuery to enhance pages that can stand on their own, while I'm a Python/Zope developer who's currently using ExtJS as the framework for a full-blown web application. I did a lot of thinking before our first session about how to approach the undertaking—should I teach to a framework, since that would yield the most immediate benefits? If so, which? Would I be able to explain best practices without going laboriously over never-again-used fundamentals of programming? Would our sessions even be worthwhile, since hundreds of tutorials are freely available?

Luckily my tutee was enthusiastic about learning from the bottom up, which was significantly easier for me, since that's how I learned myself. Despite the familiar trajectory, our sessions have been pretty educational for me, too, in part because they've highlighted the difficulties (and rewards) of teaching JavaScript, as distinct from those involved in learning it.

Read More...

extdirect 0.4 released: Batched requests, new licensing

Sorry it's taken so long, those of you who've made requests and opened tickets, but finally, there's an update to extdirect. This release adds support for batched requests as described in the Ext.Direct spec (multiple calls within a certain amount of time are gathered into a single request).

In addition, I've removed the actual ExtJS code itself so this could be released under a less restrictive license. Ext 3.x is now merely a prerequisite.

Thanks to Brian Edwards and Jon-Pierre Gentil for their work on the analogous code in Zenoss, a version of which made its way into this release.

Read More...

Run pyflakes/jslint automatically in Vim

As maybe you can tell from the infrequency of updates to this blog, I (and the others with whom I'm working) have been churning out a huge amount of code recently, split roughly evenly between Python and JavaScript. One nice thing I got used to during the month I tried to switch from Vim to TextMate was a plugin that ran pyflakes every time I saved a Python file. After I gave up and went back to Vim, I missed that check. Luckily, other, more vimscript-savvy coders had the same idea. Here's how to set up both pyflakes and jslint to run on save.

Read More...

Ext.Direct remoting in Django

Well, as I didn't have a lot of other things weighing on me today, I created a Django implementation of the extdirect package I released earlier today. It's slightly more involved to set up, probably due to my not knowing Django nearly as well as Zope (suggestions welcome, Django enthusiasts), but after the initial setup writing the router classes is just as easy. Here's how to do it.

Read More...

Ext.Direct remoting in Zope

With ExtJS 3.0 came Ext.Direct, an excellent library for remoting server-side methods to the client side. We had already made the decision to switch to Ext with the revamped Zenoss UI, so I'd been working with Ext quite a lot; in the upcoming 2.5 release, there's a brand-new event console that makes heavy use of Ext.Direct. After learning its ins and outs with all that work, I decided to write a Python version of the server-side component to make it easier to use; I then went further and created a Zope 2 and 3 compatible component that makes it trivial. extdirect is the result. Here's some brief instruction on how to use it.

Read More...

YUI DataSource with dynamic oRequest

I preface this by asserting that I consider myself expert neither in YUI nor in JavaScript. There may be a better way to do this.

YUI (which I love) has an excellent abstract DataSource component that normalizes requests for data to something compatible with all their widgets. I find it generally useful as well, even when I'm not using, for example, a YUI DataTable to display data.

Last weekend I wrote a UI notification subsystem for Zenoss, based on YUI and Yowl. I used a DataSource to handle communication with the server. DataSources can be told to poll the server periodically, using the setInterval method:

myDataSource.setInterval(1000*60, "?var=123", callback)

This is all well and good, but in my case, I needed that second argument (oRequest) to be different each time, based on previous server responses; once setInterval is called, however, the same request parameters are used each time.

I got around this by writing an object extending XHRDataSource that would accept a callable for oRequest, which would be called each time it made an external connection. Turned out to be very simple (although I ran into "too much recursion" bug, described here. I used the fix at the end of the thread to get around it):

var Y = YAHOO.util; // Internal shortcut to save typing and lookups
CallableReqDS = function(oLiveData, oConfigs) {
// Workaround for bug #2176072 in YUI 2.6.0
this.constructor = Y.XHRDataSource;
// Chain constructors
CallableReqDS.superclass.constructor.call(this, oLiveData, oConfigs);
// Set constructor back (also part of fix)
this.constructor = CallableReqDS;
}
YAHOO.lang.extend(CallableReqDS, Y.XHRDataSource);

CallableReqDS.prototype.makeConnection = function(oRequest, oCallback, oCaller) {
if (typeof(oRequest)=='function') oRequest = oRequest();
CallableReqDS.superclass.makeConnection.call(this, oRequest, oCallback, oCaller)
}

Trivial, really, but it got the job done.


UPDATE: Here's an example. Let's say you want to defeat IE's draconian caching. Standard way to do this is to tack on a unique query string for each request, which you can't do with the default XHRDataSource, because the query string can't change from request to request when using setInterval. So you use this instead:

function getCacheBustingString(){
return "?ms=" + new Date().getTime()
}
var myDS = new CallableReqDS("/path/to/myurl");

myDS.setInterval(60, getCacheBustingString, callback)


That way the cache buster will be unique for each request.

Read More...

Accessing Zope variables with Javascript

ZPT totally ignores the contents of <script> tags, which makes it kind of a hassle to use values from the server in your Javascript. Short of writing a whole integration framework, the best way I've found to pull variables from page templates into Javascript is like this:

<tal:block tal:define="foo accessor/for/myvar">
<script tal:content="string:
var foo='${foo}';
"></script>
</tal:block>


I generally have one of these up at the top of the template, storing portal_url and whatever else I might need in a namespaced array. You can run into problems with nested quotes, but if you don't have the time to write more complex back-end methods, it's a handy quick-and-dirty hack.

Read More...