Archive for the ‘JavaScript’ Category

Learning jQuery - First impressions vs. Dojo

I spent yesterday playing around with jQuery. It’s quite different from Dojo and reminds me a lot of Prototype with a bigger community. I really like jQuery for doing DOM manipulation and find the terse syntax more appealing to write. I love the fact that it has a big community discussing, contributing, and helping each other learn. I do, however, have some concerns about how jQuery might scale up on a rich web application with a lot of functionality. The best way to find out for myself, of course, is to keep learning.

Extending the base functionality: big difference

Perhaps the biggest difference between Dojo and jQuery is the philosophy they took towards extending the base functionality. jQuery itself is best compared to Dojo base. If you want additional functionality, it’s available in user-created plugins which you download and include via script tag. In Dojo, you would find a module for this in dijit or dojox and include it with dojo.require.

Do you prefer extensions that have been planned out centrally to work together? Are you ok with having just one “official” way to do things with some configuration options? Would you rather just include the needed module and skip the process of searching for a plugin? Use Dojo.

Do you want to have the biggest number of options possible for the functionality you need? Don’t mind having to search around a little bit and compare plugins in exchange for finding one customized to exactly what you want? Use jQuery.

Dependency management

Dojo does really well here. There’s an “official way” to manage dependencies which is nicely supported by the library. You put your custom code in it’s own folder which becomes a namespace for your code. Create classes in separate files in the folder with dojo.declare and a dojo.provide statement. Just dojo.require them where you want to use them. The jQuery way is to… use the script tag? You can organize files containing the code however you want. I’ve only been using jQuery for a very short period of time, but I’d guess there are some “best practices” for organizing code that make this less of a problem when working with others.

Conclusion

The things that make Dojo great for writing complex applications are no help when trying to do simple enhancements. jQuery just makes these things incredibly easy. Just include the library, a plugin or two, and one file with your own code. I think in the future I may be using both depending on what sort of problem I need to solve.

 

December JavaScript meetup

This evening was my first visit to the Atlanta JavaScript meetup. It was great meeting other web-dev folks with a lot of shared interests. Ignition Alley is the first co-working space I’ve visited. Seems like a pretty cool concept which I’d definitely look into if I didn’t already have an office to visit every day.

I presented on JavaScript builds. My talk explained what a JavaScript build is, why you might want to make one, and how to implement a build process. I used Dojo’s build tools to describe how a build should work and also discussed the Closure compiler. Slides are at the bottom.

The other presentation was on Cappucino which looked great, though I’m not so sure I want to learn Objective-J if that’s all I can use it for. Sure it’s like Objective-C, but how well do the skills translate if I invest time in learning Objective-J and Cappucino disappears? Other than that concern, the demos look great. I was a little bummed that Atlas is still quite buggy and apparently no where near ready for prime time.

 

Convert your Python to JavaScript with Pyjamas

The problem

I faced an irritating situation last year in a project I was working on. I was creating a screen that pulled in a very large set of data from the database then did various calculations on the data based on input in a form. The results were shown in several grids and a flash chart all on the same page. These exact same calculations also needed to be run to generate a PDF on the server. I didn’t want to go back to the server for the calculation because the amount of data that needed to go back and forth was very large. At the same time, I didn’t want to write and maintain a piece of code that involved 30+ math operations in both JavaScript and Python.

So I discovered Pyjamas!

A little background: the Pyjamas project was started to be the Python answer to GWT. It’s a framework that allows you to define an entire UI in Python which is then converted to JavaScript and HTML. What I found though was that it’s possible to use the Python to JavaScript converter in the project to compile your own Python to JavaScript even if you don’t need the UI framework Pyjamas provides. This was a perfect solution to my problem!

Unfortunately, Pyjamas was still in its infancy at that time, so I had to use a much stripped down subset of Python to get it to build JavaScript successfully. Once I figured out the tricks, it was a great way to avoid a painful round trip to the server and yet also avoid maintaining the same logic in two languages.

Fast forward to today. The Pyjamas project has a greatly improved Python to JavaScript compiler. You can now import multiple modules through the usual Python import functionality. The painful things I had to do before (like not use the dict constructor!) are no longer necessary. There’s even a way to include external JavaScript files from Python for use in your final generated script.

How do I use this?

It looks like at this very moment (mid-November 2009) the compiler inside of Pyjamas is in the process of being broken out into a module called pyjampiler that makes it a little easier to use it independently of the larger project. This is currently getting moved into the main code, so look for it inside of the next release. For now you can download it from the link above. Playing around with pyjampiler is this easy:

pyjampiler.py --output=my_javascript.js --entry=my_python

Really! Your python imports will be followed, converted, and linked together. You’ll get JavaScript that behaves like your Python.

Tips for success

As cool as this is, there are some limits. You can’t import whatever you like from the Python standard library. The JavaScript generated is going to be much more verbose than something you would have written yourself. You’ll need to include a helper .js file which is not one of the frameworks you’re already using (supposedly it’ll play nice).

I think this technique is best limited to functionality like I described in the beginning of this post. I implemented my logic as a function that took in two dicts and returned another dict of results. The only thing handled by the piece that was converted was the arithmetic required to drive the calculator. I wrote JavaScript to handle the DOM manipulations required to display the results on the client and Python to turn the results into a PDF on the server.

What do you think? Is this a reasonable way to avoid maintaining the same logic in two places? Have a better solution?

 

dojo.dnd.Source fires onDndDrop before it has actually moved the node?

Lately I’ve been working with drag and drop on a project. I’m dragging controls between two containers that are set to be dojo.dnd.Source. When a control is dropped on a target, I need to get a list of all the controls in each Source involved. I would really like my onDndDrop handler to look something like this:

function(source, nodes, copy, target){
        if(source.node==this.top_node || target.node==this.top_node){
            var childNodes = dojo.query('#' + this.top_node.id + ' > .custom-control');
            var newOrder = dojo.map(childNodes, function(childNode){
                return childNode.id;
            });
            console.debug(newOrder)
        }
    }

Unfortunately, I came across some annoying behavior. If the source node is located before the target node in the DOM, the onDndDrop event is firing on it before the move actually takes place! My function to calculate what controls are in each Source is therefore getting incorrect results and says the moved control exists in both the source and target Sources. The solution was to add an additional filter for the nodes:

function(source, nodes, copy, target){
        var isSource = source.node==this.top_node;
        var isTarget = target.node==this.top_node;
        if(isSource || isTarget){
            var childNodes = dojo.query('#' + this.top_node.id + ' > .custom-control');
            var newOrder = dojo.map(childNodes, function(childNode){
                return childNode.id;
            });
            // make sure that if the node should be moved out of the Source it really is gone
            // sometimes dojo calls this code for the Source before the node has ACTUALLY been moved
            if(isSource && source.node != target.node){
                newOrder = dojo.filter(newOrder, function(childName){
                    return !dojo.filter(nodes, function(movedNode){
                        return movedNode.id == childName;
                    }).length;
                });
            }
            console.debug(newOrder)
        }
    }

As a side note, it works as expected if the target node is before the source in the DOM. I wouldn’t mind this behavior if it was at least consistent.

 

I wish JavaScript had named params too

Re: Chrome Extension API; How we wish we have named parameters

If only! Sure, you can use a hash to get a similar effect, but why not just add that in? JavaScript is getting more and more like Python every day anyway…

 

Mixed case event names in Dijits? Silly little annoyance…

So today I was hooking up some event handlers in Dojo. It looks like this for DOM elements:

dojo.connect(myElement, "onclick", myObj, "handler");

One would expect it to be similar for a dijit like:

dojo.connect(myDijit, "onclick", myObj, "handler");

But that didn’t work. Why not? Because the dijit event names are camel-case:

dojo.connect(myDijit, "onClick", myObj, "handler");

Why not standardize them to match the equivalent DOM event names with lowercase spellings?

 

Why I’m leaving Prototype for Dojo

When I first decided to learn a JavaScript framework, I went with Prototype. It was 2006. Prototype was one of the most mature frameworks. When combined with scriptaculous, there were a good amount of things you could do. The big win for me, however, was the large community and decent documentation. It was a good choice and we’ve had a very productive three years together.

Unfortunately, I feel like the Prototype world has not kept up with the times. Well, perhaps that’s a miss-statement. Prototype is still just what it started out as: a base to build upon. Scriptaculous still provides animation and a few widgets. Meanwhile, the other frameworks have become much more full-featured. The widgets provided by Dojo, YUI, or ext.js are far beyond the ones offered by Scriptaculous. Writing something complex? Package management would help a lot. What about some base CSS to get started on my project with (or even better, themes)?

I will still be using Prototype for smaller projects. I think it’s great if you just want to toss in a dash of JavaScript flare and would like to use some nice helpers. But, I’m done writing big applications with Prototype/scriptaculous. It’s time to learn something new!

I’ve done a quick review of the options out there, and I’ve decided to pick up Dojo next. Ext.js needs to be licensed for commercial projects. What if the cost is too much for a project I’m working on? YUI looks excellent, but somehow it feels less organized. In fact, I plan on playing around with YUI a bit too for comparison.