<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-6805679788123355859</id><updated>2009-05-28T11:45:55.114-07:00</updated><title type='text'>Dojo  &amp; Javascript findings</title><subtitle type='html'>Javascript is a real language.. no really..</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default?start-index=26&amp;max-results=25'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-1343273504495656741</id><published>2009-03-05T16:13:00.000-08:00</published><updated>2009-03-05T16:29:11.112-08:00</updated><title type='text'>Rails 2.2 + Dojox.data + Dojox.grid</title><content type='html'>I'm interested in taking the speed of rails and displaying in the very ajax way's of dojo.&lt;br /&gt;&lt;br /&gt;Some quick pointers on getting the backend to play nicely with the front end.&lt;br /&gt;&lt;br /&gt;1. In your rails app go to Configuration -&gt; Initializers -&gt; new_rails_defaults.rb&lt;br /&gt;2. set the following to false: &lt;span style="font-style:italic;"&gt;ActiveRecord::Base.include_root_in_json&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Reason being that the response when encoded to json, natively will have the object name preceding every item in the returned list where as dojo.data just wants the items listed in an array.&lt;br /&gt;&lt;br /&gt;eg.&lt;br /&gt;Native: [{something:{data:1}}. {something:{data:2}}]&lt;br /&gt;After change: [{data:1},{data:2}]&lt;br /&gt;&lt;br /&gt;3. In your controller copy the format.xml line in each block to a line just below and change the .xml to .json and "render :json". This gives the controller the ability to respond to JSON requests.&lt;br /&gt;&lt;br /&gt;eg: &lt;br /&gt;&lt;br /&gt;format.xml  { render :xml =&gt; @something }&lt;br /&gt;format.json { render :json =&gt; @something }&lt;br /&gt;&lt;br /&gt;4. use the dojox.data.RailsStore in your javascript. This will tag ".json" on to your requests and correctly set header information for JSON interaction.&lt;br /&gt;&lt;br /&gt;At this point you should be able to create a dojo.data store and connect it into a widget to see some results.&lt;br /&gt;&lt;br /&gt;The last thing is that the store will have functionality for querying and sorting. This isn't in the default rails controllers and is the next thing I'm working on for a good solution.&lt;br /&gt;&lt;br /&gt;Be aware that Rails as of the 2ish version will happily work with JSON so requests to and from the server can be handled without the need for plugins.&lt;br /&gt;&lt;br /&gt;To get a service going is as easy as:&lt;br /&gt;&lt;span style="font-style:italic;"&gt;var store = new dojox.data.RailsStore({target:"/something"});&lt;/span&gt;&lt;br /&gt;where in this case something is the base REST path.&lt;br /&gt;&lt;br /&gt;Note that writing back to the server with dojo.data doesn't not currently work as the message sent is the plain data object where as rails wants the object to be named. Ie&lt;br /&gt;&lt;br /&gt;We send: {data:1}&lt;br /&gt;server wants: {something:{data:1}}&lt;br /&gt;&lt;br /&gt;as a quick hack, changes to the dojox.rpc.Rest class can be made look at the method (drr._change). This is too much of a hack at the moment though and I'm looking for a better way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-1343273504495656741?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/1343273504495656741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=1343273504495656741' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1343273504495656741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1343273504495656741'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2009/03/rails-22-dojoxdata-dojoxgrid.html' title='Rails 2.2 + Dojox.data + Dojox.grid'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-8047111964138894245</id><published>2009-02-19T17:12:00.001-08:00</published><updated>2009-02-19T18:25:13.198-08:00</updated><title type='text'>Dojo..not in 6K but comparable to JQuery</title><content type='html'>Firstly, I think fundamentalism when it comes to the JS library selection is a really poor way to go. I prefer the positive competition and innovation that comes from multiple libraries in development. However JQuery is being heavily used by a vocal web community that parts of which seem very quick to throw out negative (and now incorrect) ideas about other libraries, including the Dojo toolkit. &lt;br /&gt;&lt;br /&gt;JQuery has the many positives including that it's all about DOM work, it's exceptionally fast (which is why everyone is looking at 'sizzle') and it's relatively small. This is what John meant it to be and he's really stuck to his vision. But others have started coming in with plugins and this is where I feel things are less clear.&lt;br /&gt;&lt;br /&gt;People say JQuery is small, and for the core it is. But if you load plug-in code along side it then the total code is not as small. Now conversely people say Dojo is big.. but in truth the core is fairly small. It's when you load the code to support features such as widgets that things get bigger. So the ideas here are a little misleading. &lt;br /&gt;&lt;br /&gt;In an effort to investigate dojo's big-boned reputation I decided to see how small we can make things. So where are we to start with? A basic dojo build makes a core dojo.js file that includes the full _base weighing in at around 80kb. This compared to JQueries 54kb is a little heavier.&lt;br /&gt;&lt;br /&gt;I found the article describing &lt;a href="http://www.sitepen.com/blog/2008/04/02/dojo-mini-optimization-tricks-with-the-dojo-toolkit/"&gt;dojo-mini&lt;/a&gt; which is how to make a small build of dojo. But I'm looking to it's heart. What about those guys that pull in JQuery, make something fade out and scream "AH HA! BEST LIBRARY EVER!".&lt;br /&gt;&lt;br /&gt;So here's what I did. I found the "&lt;a href="http://www.sitepen.com/blog/2008/07/01/dojo-in-6k/"&gt;Dojo in 6K&lt;/a&gt;" article. A promising start as we can load up the core dojo in a ridiculously fast way. I particularly like the "stubs" idea.&lt;br /&gt;&lt;br /&gt;This however still spawns off numerous requests if I want to get in "dojo._base.fx" for some basic animation work. So next off we turn to the build system. Here I created the following profile:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dependencies = {&lt;br /&gt; layers: [&lt;br /&gt;  {&lt;br /&gt;   name: "dojo.js",&lt;br /&gt;   customBase: true,&lt;br /&gt;   dependencies: [&lt;br /&gt;    "dojo._base.window",&lt;br /&gt;    "dojo._base._stubs"&lt;br /&gt;   ]&lt;br /&gt;  },&lt;br /&gt;  {&lt;br /&gt;                        name: "_baseFx.js",&lt;br /&gt;                        customBase: true,&lt;br /&gt;                        layerDependencies: [&lt;br /&gt;                                "dojo.js"&lt;br /&gt;                        ],&lt;br /&gt;                        dependencies: [&lt;br /&gt;    "dojo._baseFx"&lt;br /&gt;                        ]&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt; ],&lt;br /&gt; prefixes: []&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note there is no inclusion of the dijit or dojox prefixes. We're going for tiny animation grade system here. Note also that I'm using the "stubs" file for my main dojo.js file.&lt;br /&gt;&lt;br /&gt;Next up the dojo._baseFx file:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dojo.provide("dojo._baseFx");&lt;br /&gt;dojo.require("dojo._base.fx");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here all we're doing is including the core fx file and this file will be rebuilt so we can include it via dojo.require() later.&lt;br /&gt;&lt;br /&gt;One last change. When you build using profiles that use "customBase" there is a new regex approach to making sure you don't produce a bad build. The build system reads your code looking for references relating to _base you may have forgotten and throws them in. This system called "injection" is not what we're after here. Hence I modified the file "jslib/buildUtil.js" in the method "buildUtil.addGuardsAndBaseRequires" added the line "needBaseRequires=0;" to the top. This means we always ignore the injection for now. Note this means builds may not always have what you need so there's a level of developer responsibility that comes with turning off this helpful code.&lt;br /&gt;&lt;br /&gt;Finally we run the build. This will produce a dojo.js file that for me was about 17k. And a _baseFx.js file that was around 28k. It also moves over the other dojo code but for something to fadeIn / fadeOut I just want some key files. I copied over the two mentioned files along with the _base directory and we're now ready to go.&lt;br /&gt;&lt;br /&gt;In the HTML I included dojo.js in the usual way and then added the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dojo.addOnLoad(function(){&lt;br /&gt;&lt;br /&gt;dojo.require("dojo._baseFx");&lt;br /&gt;&lt;br /&gt;dojo.fadeOut({node:"nodeName"}).play();&lt;br /&gt;&lt;br /&gt;})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When the page is ready the addOnLoad causes the extra code to load (baseFx) and then instantly uses it to find a node called "nodeName" and hide it with a nice fade out effect.&lt;br /&gt;&lt;br /&gt;This not only works but does something that JQuery currently does not. It lazy loads over half of the code meaning the page will appear very quickly for an end user after the 17k initial dojo.js load and while they are sitting there thinking what to do next the remainder of the code is pulled in. In reality this happens faster than you can think and if sent over the wire with gzip the code content will be even tinier.&lt;br /&gt;&lt;br /&gt;Remember back to the stubs though? why did we do that? Well it's a safety net. Say we follow up the previous code with:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dojo.addOnLoad(function(){&lt;br /&gt;dojo.query("something").innerHTML = "blah";&lt;br /&gt;})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;dojo.query is not currently in our environment due to the small custom _base. But the stubs package knows that any call to query should load it. The code is loaded as it is needed and we carry on. &lt;br /&gt;&lt;br /&gt;For web applications this approach isn't really optimal. But for the designers out there that complain dojo is too bloated to be used for simple web page work, think again. 17k and Dojo is usable. A moment later we're animating. &lt;br /&gt;&lt;br /&gt;Don't get me wrong, John Resig continues to amaze me with his work and JQuery in general. But I'm really hoping one day people will stop uttering things about Dojo that just aren't true, especially not on a podcast (Rubyology Ep73).&lt;br /&gt;&lt;br /&gt;Final thought&lt;br /&gt;- JQuery 1.3.1 minified = 54Kb&lt;br /&gt;- Dojo (as above) 17Kb loader + 28Kb baseFx = 55Kb&lt;br /&gt;(To add lazy loading to JQuery)&lt;br /&gt;- 54kb JQuery 1.3.1 + 3kb &lt;a href="http://code.google.com/p/ajaxsoft/wiki/xLazyLoader"&gt;xLazyLoader&lt;/a&gt; = 57Kb&lt;br /&gt;&lt;br /&gt;To load the page initially with Dojo in the above way you need to load 17Kb&lt;br /&gt;To load the page initially with JQuery + loader you need 57Kb&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-8047111964138894245?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/8047111964138894245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=8047111964138894245' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/8047111964138894245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/8047111964138894245'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2009/02/dojonot-in-6k-but-comparable-to-jquery.html' title='Dojo..not in 6K but comparable to JQuery'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-7032689910161730126</id><published>2008-10-14T23:34:00.001-07:00</published><updated>2008-10-15T00:48:46.706-07:00</updated><title type='text'>Polymorphism</title><content type='html'>I love that word.. anyway, I stumbled on an &lt;a href="http://ejohn.org/blog/javascript-method-overloading"&gt;article&lt;/a&gt; by John Resig that I'd read a while back talking about method overloading in JS.&lt;br /&gt;&lt;br /&gt;Looking through the article and comments was quite interesting and inspired me to write this down just in case I feel the need to revisit the topic one day.&lt;br /&gt;&lt;br /&gt;Edit: I extended the "Object" prototype previously.. a big no no but one that made proof of concepts quick and easy.. I've updated the code to follow the JR way of leave JS objects untouched.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;var poly = {&lt;br /&gt; addMethod: function(object, name, fn){&lt;br /&gt;  object._store = object._store || {};&lt;br /&gt;  object._store[name] = object._store[name] || {};&lt;br /&gt;  object._store[name][fn.length] = fn;&lt;br /&gt;  object[name] = function(){&lt;br /&gt;   if(object._store[name][arguments.length])&lt;br /&gt;     return object._store[name][arguments.length].apply(this, arguments);&lt;br /&gt;   else&lt;br /&gt;     throw new Error("Wrong number of arguments");&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I noticed if you were to borrow the function via call or apply the scoping would go badly so I used some closure hackery to preserve this. It's possibly a bit suspect but it works.&lt;br /&gt;&lt;br /&gt;Usage and example of scope preservation:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;var n = {name:"I am n"};&lt;br /&gt;poly.addMethod(n, "getName", function(){ return (this.name);})&lt;br /&gt;n.getName()&lt;br /&gt;&gt;&gt;I am n&lt;br /&gt;var s = {name:"I am s"};&lt;br /&gt;s.do = function(){ return n.getName.apply(this, []); }&lt;br /&gt;s.do()&lt;br /&gt;&gt;&gt;I am s&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-7032689910161730126?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/7032689910161730126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=7032689910161730126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/7032689910161730126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/7032689910161730126'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/10/polymorphism.html' title='Polymorphism'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-2790324456895214692</id><published>2008-08-03T21:17:00.001-07:00</published><updated>2008-08-03T21:27:42.180-07:00</updated><title type='text'>Kicking the dijit toolbar up a notch</title><content type='html'>I love that dijit has a menu system built in using dijit dropDownButtons and the dijit toolbar. I don't love that interacting with a mouse requires more clicking than the native windows menu system most users are familiar with.&lt;br /&gt;&lt;br /&gt;The key is that the dropDownButtons work independently from one another. Click one and that menu shows, hover over the next menu and you can see focus but it doesn't show the menu till you click on it. Under windows once we click a menu open, everything starts responding to a hover event.&lt;br /&gt;&lt;br /&gt;Rather than grumble, I decided to fix this behaviour:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;dojo.declare(&lt;br /&gt; "widget.DropDownButton",&lt;br /&gt; dijit.form.DropDownButton,&lt;br /&gt; {&lt;br /&gt;  respondToMouseOver: false,&lt;br /&gt;  &lt;br /&gt;  postCreate: function(){&lt;br /&gt;   this.inherited(arguments);&lt;br /&gt;   dojo.connect(this, "_openDropDown", this, "_updateRespondOpen");&lt;br /&gt;   dojo.connect(this, "_closeDropDown", this, "_updateRespondClose");&lt;br /&gt;   dojo.connect(this.domNode, "onmouseover", this, "_respondToMouseover");&lt;br /&gt;   dojo.subscribe("/dropDownOpen", this, "_setRespondState");&lt;br /&gt;   dojo.subscribe("/dropDownCloseAll", this, "_closeDropDown");&lt;br /&gt;  },&lt;br /&gt;  _setRespondState: function(state){&lt;br /&gt;   this.respondToMouseOver = state;&lt;br /&gt;  },&lt;br /&gt;  &lt;br /&gt;  _respondToMouseover: function(){&lt;br /&gt;   if(this.respondToMouseOver){&lt;br /&gt;    dojo.publish("/dropDownCloseAll", [true]);&lt;br /&gt;    this._openDropDown(arguments);&lt;br /&gt;   }&lt;br /&gt;  },&lt;br /&gt;  &lt;br /&gt;  _updateRespondOpen: function(){&lt;br /&gt;   dojo.publish("/dropDownOpen",[true]);&lt;br /&gt;  },&lt;br /&gt;  _updateRespondClose: function(){&lt;br /&gt;   dojo.publish("/dropDownOpen",[false]);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here the buttons work as a team. When one opens it lets the others know its time to respond to the hover. When one closes due to clicking off the focus or selecting an option it keeps the others in the loop and they stop worrying about the hover. Dojo's pub/sub is a wonderfully simple networking tool for your widgets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-2790324456895214692?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/2790324456895214692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=2790324456895214692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/2790324456895214692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/2790324456895214692'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/08/kicking-dijit-toolbar-up-notch.html' title='Kicking the dijit toolbar up a notch'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-7065598656037300355</id><published>2008-07-13T22:51:00.001-07:00</published><updated>2008-07-13T22:55:51.009-07:00</updated><title type='text'>JavaScript + Rhino + SQLite + Dojo + Jetty +..what's left?</title><content type='html'>As a small side project I decided to see what things would look server side if JavaScript was the driving force.&lt;br /&gt;&lt;br /&gt;I'm using Rhino (Mozillas JavaScript interpreter) to start the ball rolling, get a Jetty server instance up and load some dojo into the background for the hell of it. From there you can open up a SQLite connection to a local database and start writing things out via servlets.&lt;br /&gt;&lt;br /&gt;My driving force was what does a server have to be these days? given that JavaScript libraries such as Dojo, YUI, EXT and JQuery UI are all creating extremely dynamic front ends, we're leveraging server-side rendering technologies less and less. In fact they are starting to conflict with wanting to do the same things. So if all I need is data from my server, then all I need is some clever servlets and a hint of JSON.&lt;br /&gt;&lt;br /&gt;So from my simple hackery I have the basics working. It's not robust, scalable or designed to handle enterprise smarts. But as an after hours proof of concept it's an odd and cool feeling to think I can build a servlet response with JavaScript that is reading database objects from a tiny local DB and spitting it straight to JSON.&lt;br /&gt;&lt;br /&gt;Oh and since all of it is hosted in java I've been developing this on Windows, Ubuntu and an OSX box. Amusingly Jetty and the DB are smaller than the dojo source install I'm using. Note you have to grab the source install of dojo if you want load it in Rhino. The source is intentionally stripped down on release to work only in browsers.&lt;br /&gt;&lt;br /&gt;So the trickiest thing so far has been figuring out the Jetty API. Damn thing keeps changing leaving some of the tutes to be misleading. As I gradually become more familiar with it, it's becoming less of a hassle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-7065598656037300355?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/7065598656037300355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=7065598656037300355' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/7065598656037300355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/7065598656037300355'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/07/javascript-rhino-sqlite-dojo-jetty.html' title='JavaScript + Rhino + SQLite + Dojo + Jetty +..what&apos;s left?'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-4975572484624006683</id><published>2008-06-12T19:06:00.000-07:00</published><updated>2008-06-12T20:43:56.675-07:00</updated><title type='text'>Dojo.query, dojo.Nodelist and Chaining Actions</title><content type='html'>I've recently becoming more and more reliant on dojo.query for finding the nodes I want to work on. Gone are the days of trying to cleverly use name and id as the only two distinguishing features of a node. Now we can use almost any attribute on a node. To see how this can be useful I'll talk about a recent case.&lt;br /&gt;&lt;br /&gt;To begin with we are given a HTML form that is arranged so that there are lines of input elements and at the beginning of each line is a checkbox. The checkbox is used to enable or disable a row of elements depending on its checked state.&lt;br /&gt;&lt;br /&gt;To do this in the old days we could either assign some id's to the nodes and do some string manipulation on the id so that items like "row1_1, row1_2, row1_3" were toggled (not pretty) or we could walk the dom tree and start going through parentNode, childNodes etc checking tagNames and so on. This is pretty hard work. Lets see how it could be done with a hint of dojo.&lt;br /&gt;&lt;br /&gt;if our row looks like the following:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; class='checkboxTrigger'&amp;gt;&lt;br /&gt;  &amp;lt;label for='asd'&amp;gt;Test&amp;lt;/label&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What do we want our code to do to it? Well when the pages loads, we need to disable the entry fields, uncheck all checkboxes and setup our events so that clicking a checkbox toggles the rows state. Right.. time for some code&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;var formHelper = {&lt;br /&gt;    toggleRow: function(e){&lt;br /&gt;        this.toggleNodes((!e.target.checked), e.target.parentNode);&lt;br /&gt;    },&lt;br /&gt;    init: function(){&lt;br /&gt;        dojo.query(&amp;quot;.checkboxTrigger&amp;quot;).onclick(dojo.hitch(this,this.toggleRow)).attr(&amp;quot;checked&amp;quot;,false);&lt;br /&gt;        this.toggleNodes(true);&lt;br /&gt;    },&lt;br /&gt;    toggleNodes: function(status, rootNode){&lt;br /&gt;        rootNode = rootNode||dojo.body();&lt;br /&gt;        dojo.query(&amp;quot;input:not(.checkboxTrigger):not(.submits),select,radio&amp;quot;, rootNode).attr(&amp;quot;disabled&amp;quot;,status);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;dojo.addOnLoad(dojo.hitch(formHelper,formHelper.init));&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What do we have here? Lets walk through how the page uses this code.&lt;br /&gt;&lt;br /&gt;We can see at the end, a dojo.addOnLoad is used to link up the formHelper.init function. We wrap that with dojo.hitch to make sure that when the function is called by the window onload event, any references inside the method correctly know that "this.{method}" means "formHelper.{method}", not "window.{method}". You'll have to trust me on this one and if you want to know more, look up "scoping"&lt;br /&gt;&lt;br /&gt;When the init is called we use dojo.query to get all the elements on the page that use the style class "checkboxTrigger". Easy. On those elements we setup an onclick action that points to the "toggleRow" method. Again see the use of hitch to keep the scope in check. Notice what's next? straight after the onclick we can call the further ".attr" method to set the checked state on the nodes. This is because query and it's methods keep returning Nodelists, so we can keep chaining the calls.&lt;br /&gt;&lt;br /&gt;Next we call the toggleNodes method. This methods goal is to set everything other than the trigger checkbox nodes to be either enabled or disabled. Note that in this method we are doing a query for all inputs that don't have the checkboxTrigger class and that don't have the submits class. I put the submits style class on the save and cancel buttons to make sure that they're never impacted upon. Also note that this query can grab other things like select boxes etc. On each of these nodes we simply set the disabled state via the "attr" method. Also note that if we don't give it a specific node to focus on we just apply the query to the body. &lt;br /&gt;&lt;br /&gt;Finally the toggleRow is simply a wrapper to toggleNodes but with the additional step that we pick which row to dojo.query inside. That is we narrow the search for nodes to toggle to one row.&lt;br /&gt;&lt;br /&gt;And that's it. The code can be dropped on to any page of a similar structure with the right class names. You can also add / remove the number of form elements in a row without worrying about changing a thing. Compact, reusable, robust.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-4975572484624006683?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/4975572484624006683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=4975572484624006683' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4975572484624006683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4975572484624006683'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/06/dojoquery-dojonodelist-and-chaining.html' title='Dojo.query, dojo.Nodelist and Chaining Actions'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-264563483461810307</id><published>2008-06-03T18:35:00.000-07:00</published><updated>2008-06-03T19:16:13.763-07:00</updated><title type='text'>dojo.query - not just another dojo.byId</title><content type='html'>The more I find out about the magical function that is dojo.query, that more that I'm blown away by it's potential.&lt;br /&gt;&lt;br /&gt;It feels so unfamiliar at first using javascript and knowing that I'm grabbing and working with node objects rather than using string ID's all the time but once you get used to it, it's liberating. &lt;br /&gt;&lt;br /&gt;Finding and filtering nodes by any number of attributes and classes is only just scratching the surface though. Dojo.query not only makes getting things easy but what it returns is just as powerful.&lt;br /&gt;&lt;br /&gt;dojo.nodeList is a fairly new entity to me but one that has a similarly great potential. It's intention is to hold a bunch of node elements and make working on them easier than you'd expect.&lt;br /&gt;&lt;br /&gt;In one of my last posts I used dojo.forEach to loop through nodes adding a connect on each item, but as Alex Russell pointed out, we needn't worry about half of that code.&lt;br /&gt;&lt;br /&gt;Instead we can write:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dojo.query(".checkboxTrigger").onclick(updateStatus);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I love the fact that it not only makes things shorter, but somewhat more readable. It applies the updateStatus function as the onclick for all the return nodes. Easy.&lt;br /&gt;&lt;br /&gt;Looking into the api for the &lt;a href='http://api-staging.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.NodeList'&gt;dojo.NodeList&lt;/a&gt; there are plenty of things we can do to our nodes. We can create animations, addContent, clear content, etc.&lt;br /&gt;&lt;br /&gt;I highly recommend a bit of exploring in both the dojo.query and dojo.NodeList areas as I'm continuing to find more and more things of interest.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-264563483461810307?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/264563483461810307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=264563483461810307' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/264563483461810307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/264563483461810307'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/06/dojoquery-not-just-another-dojobyid.html' title='dojo.query - not just another dojo.byId'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-617231570697287366</id><published>2008-05-19T00:26:00.001-07:00</published><updated>2008-05-19T00:44:28.617-07:00</updated><title type='text'>Old-School Dijit helpers</title><content type='html'>Being raised on dojo 0.4.x there were a few widget things that seem to have been lost along the way for dojo 1.x. This may be due to better practice etc but old habits die hard.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;var widget = {&lt;br /&gt;   byId: function(/*String*/ id){&lt;br /&gt;      return dijit.byId(id);&lt;br /&gt;   },&lt;br /&gt;   all: function(){&lt;br /&gt;      var widgetArray = [];&lt;br /&gt;      var widgets = dijit.registry._hash;&lt;br /&gt;      for(var a in widgets){ widgetArray.push(widgets[a]); }&lt;br /&gt;      return widgetArray;&lt;br /&gt;   },&lt;br /&gt;   allHash: function(){&lt;br /&gt;      return dijit.registry._hash; &lt;br /&gt;   },&lt;br /&gt;   byType: function(/*String*/ type){&lt;br /&gt;      type = type.toLowerCase();&lt;br /&gt;      var widgets = this.all();&lt;br /&gt;      var widgetArray = dojo.filter(widgets, function(item){&lt;br /&gt;         return (item.declaredClass.toLowerCase() == type);&lt;br /&gt;      });&lt;br /&gt;      return widgetArray;&lt;br /&gt;   }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Main ones here are core.widget.all() that returns all present widgets and core.widget.byType() that can fetch by declared widget class. &lt;br /&gt;&lt;br /&gt;"all" is handy for debugging some times just to make sure all your widgets are appearing on the page and sometimes to see if dynamic widgets are being created.&lt;br /&gt;&lt;br /&gt;"byType" isn't used as much but some times can be handy to grab numerous widgets of the same type that aren't related like buttons etc.&lt;br /&gt;&lt;br /&gt;There are likely to be newer (smarter) ways of doing this kind of stuff. But it was a quick hack to get an old approach back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-617231570697287366?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/617231570697287366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=617231570697287366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/617231570697287366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/617231570697287366'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/05/old-school-dijit-helpers.html' title='Old-School Dijit helpers'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-4151566675942128696</id><published>2008-05-18T22:01:00.000-07:00</published><updated>2008-05-18T22:55:24.120-07:00</updated><title type='text'>Evolved coding with Dojo - No more string trickery</title><content type='html'>Nothing like a bit of code in action to get a sense of how JavaScript as a language is coming along. &lt;br /&gt;&lt;br /&gt;So to get things rolling, I've come up against the situation where there are several rows of a form and each one starts with a checkbox. Clicking that checkbox enables or disables the form elements in that row restricting access to that row and making sure the user is aware of what they are changing when they do it.&lt;br /&gt;&lt;br /&gt;I've often seen how my hardcore java programmer colleagues approach this. They usually hardcode an onclick with node id trickery to find what to enable and disable. Server side they increment id's and hope they match as the page changes. Just one of many possible approaches here.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;function update(obj){&lt;br /&gt; var id = obj.getAttribute("id");&lt;br /&gt; var new_id = id+"_element";&lt;br /&gt; var node = document.getElementById(new_id);&lt;br /&gt; node.disable = obj.checked?'':true;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can do better than this though.&lt;br /&gt;&lt;br /&gt;For starters, anyone who's seen dojo a little bit will know about dojo.connect. This means we don't need to hard-code onclicks, can be smarter about memory leaks (crucially with IE) and connect anything to anything.&lt;br /&gt;&lt;br /&gt;Step one, when the page loads we want all the checkboxes on the page to magically gain an onclick event. I could search for all checkboxes in general but don't want to accidentally clash with form input checkboxes. So to make this easy I'm going to give all the checkboxes I want the style class 'checkboxTrigger'. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;dojo.addOnLoad(function(){&lt;br /&gt;  dojo.forEach(dojo.query(".checkboxTrigger"), function(item){&lt;br /&gt;    dojo.connect(item, "onclick", updateStatus);&lt;br /&gt;  });&lt;br /&gt;})&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The function does pretty much what was said... On load, query for elements with a class 'checkboxTrigger'. For each of those, connect the updateStatus function. &lt;br /&gt;&lt;br /&gt;Next we need the update function.&lt;br /&gt;&lt;br /&gt;The update function should figure out what checkbox was clicked. Then find all the input fields in that row, except for checkbox triggers, then set the disabled attribute on all of the remaining form elements.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;var updateStatus = function(/*Event*/ e){&lt;br /&gt;  var targetNode = node = e.target;&lt;br /&gt;  while(node.tagName.toLowerCase()!="tr"){ node = node.parentNode; }&lt;br /&gt;  var inputs = dojo.filter(dojo.query("input", node), function(item){ &lt;br /&gt;    return (item.className!="checkboxTrigger");&lt;br /&gt;  });&lt;br /&gt;  var state = targetNode.checked?'':true;&lt;br /&gt;  dojo.forEach(inputs, function(item){ item.disabled=state; });&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So here we find the target of our click event which should be the checkbox. Walk up the dom tree a few steps to find the "tr" row node. You could use "div" if you wrap your nodes in a div (being politically correct). From there we use query to find inputs in that row, filter out checkboxes with our special class name and then use forEach to loop through and set a disabled status on those fields.&lt;br /&gt;&lt;br /&gt;Presto. A function that can generically enable or disable fields in a row using trigger checkboxes. We didn't care how many rows there are or how many fields in the row and no trickery with id's. This means generic code with less chance of failing to find nodes and killing your code with exceptions.&lt;br /&gt;&lt;br /&gt;There's plenty you could do to this final function to make it more robust, more capable of finding form elements etc, but it's a place to start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-4151566675942128696?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/4151566675942128696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=4151566675942128696' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4151566675942128696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4151566675942128696'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/05/evolved-coding-with-dojo-no-more-string.html' title='Evolved coding with Dojo - No more string trickery'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-581160833036013726</id><published>2008-04-14T19:28:00.000-07:00</published><updated>2008-04-14T19:42:00.343-07:00</updated><title type='text'>Why Not - Code highlighting with Dojox</title><content type='html'>I recently stumbled across files in dojox for code highlighting and I thought why not? why not add a bit of syntactical sugar to blogger. So making use of AOL's very generous cross domain dojo hosting, I gave it a go.&lt;br /&gt;&lt;br /&gt;You'll find info on the AOL CDN dojo releases here: &lt;a href="http://dev.aol.com/dojo"&gt;http://dev.aol.com/dojo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From there we need to include the dojo core in our template using bloggers template html editor and add a tiny bit of script that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;script djConfig='parseOnLoad: true' src='http://o.aolcdn.com/dojo/1.1.0/dojo/dojo.xd.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;dojo.require(&amp;quot;dojox.highlight.languages.javascript&amp;quot;);&lt;br /&gt;dojo.addOnLoad(function(){&lt;br /&gt;    dojo.query(&amp;quot;code&amp;quot;).forEach(dojox.highlight.init);&lt;br /&gt;});&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which means when the page is finished loading, grab all the "code" blocks using dojo.query and then loop over them initialising them with dojox.highlight.init.&lt;br /&gt;&lt;br /&gt;This is pretty much lifted from the highlight test case and is worth a look if you want to see more examples.&lt;br /&gt;&lt;br /&gt;At this point, a little tweak to the css with the block&lt;br /&gt;&lt;br /&gt;pre code {&lt;br /&gt;display: block;&lt;br /&gt;border:1px dashed #aaaaaa;&lt;br /&gt;overflow:auto;&lt;br /&gt;background-color:#ffffff;&lt;br /&gt;color:#444444;&lt;br /&gt;padding:3px;&lt;br /&gt;whitespace:pre;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;..and we have code blocks that are highlighted and will handle scrollable overflow.&lt;br /&gt;&lt;br /&gt;For some reason, IE currently doesn't obey the 'pre' aspect of all of this and hence white spacing is lost. I'll look into that when I get a chance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-581160833036013726?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/581160833036013726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=581160833036013726' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/581160833036013726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/581160833036013726'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/04/why-not-code-highlighting-with-dojox.html' title='Why Not - Code highlighting with Dojox'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-5750706885151785982</id><published>2008-03-18T20:30:00.000-07:00</published><updated>2008-04-14T19:27:45.805-07:00</updated><title type='text'>Templating made nicer with Jaxer, dijit and dojo.query</title><content type='html'>Once upon a time dojo had markup ability using custom tags. This was pulled because as it turns out, some browsers just scrap tags they don't understand. One browser that did support tags of a non HTML nature though was Mozilla and in turn we get this freedom back via Jaxer.&lt;br /&gt;&lt;br /&gt;So in this knowledge, I did a quick concept mock-up. And in essence the gain can be varying depending on the amount of work you want the back end to do.&lt;br /&gt;&lt;br /&gt;In it's simplest form, we can change&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;div dojoType=&amp;quot;dijit.form.button&amp;quot; label=&amp;quot;test&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;into&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;dijit dojoType=&amp;quot;dijit.form.button&amp;quot; label=&amp;quot;test&amp;quot;&amp;gt;&amp;lt;/dijit&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and simply do a server-side rebadging of the nodes so our gain is mostly readability of tags.&lt;br /&gt;&lt;br /&gt;But I wanted something a little more exciting. I've been working with JSF and JSTL on and off and am pretty familiar with the notion of a tag, render/component definition and tag definition in a config file. What this gives us is a splitting of code, presentation and config.&lt;br /&gt;&lt;br /&gt;So following that blueprint I created a tag definition that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;tags: {       &lt;br /&gt;    dijit:{&lt;br /&gt;        button: {&lt;br /&gt;            include: &amp;quot;dijit.form.Button&amp;quot;,   &lt;br /&gt;            dojoType: &amp;quot;dijit.form.Button&amp;quot;,   &lt;br /&gt;            passthrough:['label', 'iconClass', 'showLabel'],&lt;br /&gt;            passthroughContent: true   &lt;br /&gt;        },&lt;br /&gt;        numberspinner: {&lt;br /&gt;            include: &amp;quot;dijit.form.NumberSpinner&amp;quot;,&lt;br /&gt;            dojoType: &amp;quot;dijit.form.NumberSpinner&amp;quot;,&lt;br /&gt;            passthrough:['constraints', 'value']&lt;br /&gt;        }           &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here we have a reference to what include is needed, the dojoType and any passthrough tag attributes we might need. The passthrough is really an optional concept but I kind of like making safe the information that gets taken from the tag and pushed to the widget.&lt;br /&gt;&lt;br /&gt;Next how to call it. Simply put:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;dijit type=&amp;quot;button&amp;quot; label=&amp;quot;test2&amp;quot;&amp;gt;&amp;lt;/dijit&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And lastly...the processor. Well usually we kick things off with a dojo.addOnLoad but that's not applicable in Jaxer land (at the moment) so instead we start things using a connect and the "onserverload" event.&lt;br /&gt;&lt;br /&gt;The processor does the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Loop over the the tag definition object grabbing the first level child nodes. These nodes are the actual tag names to search for so in our case we have "dijit". &lt;/li&gt;&lt;li&gt;Use dojo.query to find every instance of custom tags like "dijit" and add them to a queue.&lt;/li&gt;&lt;li&gt;Loop over the queue, first checking each node for content that has a dijit tag in it. If so add it to the back of the queue so that we process from inside content to outside parent tags.&lt;/li&gt;&lt;li&gt;Continuing with the node, use its type to find the definition in the tag definition set and convert the node into a div tag with a dojoType attribute.&lt;/li&gt;&lt;li&gt;Pull over a base set of attributes like id, name, style and then the pass through attributes.&lt;/li&gt;&lt;li&gt;Add the specified require to an object for later.&lt;/li&gt;&lt;li&gt;If necessary, pull content of the dijit tag over to the div tag.&lt;/li&gt;&lt;li&gt;When all nodes are processed, loop over the require object building up a series of dojo.require statements.&lt;/li&gt;&lt;li&gt;Add the require statements to a script block in the page and make sure it's set to runat='client'&lt;/li&gt;&lt;/ol&gt;With this process we convert all nodes to the expected divs and neatly contain all dojo.requires in one place.  This means we can now create a simple reference in a custom tag to a more elaborate template configuration and backend generation. It really feels like an evolution of JSTL in some ways.&lt;br /&gt;&lt;br /&gt;Does it work? My proof of concept code says yes and I've taken it further so that instead of replacing dijit tags with divs we replace it with programmatic instantiation. This idea is even better in some ways as it takes some of the heavy lifting away from the parser. The client-side only has to worry about code execution and not only that we can use the backend to accumulate code and keep it tidy just as we did with accumulating the dojo.requires and then outputting them in one place. Having said that I've been really impressed at recent optimizations with the parser.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;It's worth noting that this as always is a "what if" experiment and should not be taken as perfect or an enterprise solution&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;From my quick trials one of the key advantages with Jaxer has been the ability for the server to keep track of various page level pieces of information and then arrange them neatly for the client-side. The fact that it's Mozilla-like at the back end effortlessly supporting the required features is really refreshing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-5750706885151785982?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/5750706885151785982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=5750706885151785982' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/5750706885151785982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/5750706885151785982'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/03/templating-made-nicer-with-jaxer-dijit.html' title='Templating made nicer with Jaxer, dijit and dojo.query'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-4270655632483258066</id><published>2008-03-04T19:44:00.000-08:00</published><updated>2008-03-04T19:48:28.810-08:00</updated><title type='text'>Jaxer + Dojo - Progress</title><content type='html'>Some really great progress has been made by the dojo guys, particularly J. Burke.&lt;br /&gt;&lt;br /&gt;Catch some of the discussion on the trac thread:&lt;br /&gt;&lt;a href="http://trac.dojotoolkit.org/ticket/5878"&gt;&lt;br /&gt;http://trac.dojotoolkit.org/ticket/5878&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There's been some discussion about the callback state of Jaxer and this interests me mostly because I'm curious and kind of like the idea of functional dojo everywhere. I've started a ticket looking into why Dojo and callbacks are different (and not working) in comparison to the working JQuery examples.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://trac.dojotoolkit.org/ticket/6066"&gt;http://trac.dojotoolkit.org/ticket/6066&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-4270655632483258066?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/4270655632483258066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=4270655632483258066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4270655632483258066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4270655632483258066'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/03/jaxer-dojo-progress.html' title='Jaxer + Dojo - Progress'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-3014068263633566206</id><published>2008-02-25T14:41:00.000-08:00</published><updated>2008-02-25T16:32:59.991-08:00</updated><title type='text'>Dojo + Iframes</title><content type='html'>There's been a lot of talk about getting dojo to work with Iframes but I think that statement has left room for confusion. To get dojo to work with iframes, there are two possible scenarios. &lt;br /&gt;&lt;br /&gt;The first is that we want to load dojo into the parent frame and use it to access child frames. This is presuming the child frame is simple content and only needs to be modified with things like dojo.byId.&lt;br /&gt;&lt;br /&gt;The other scenario is the one that I am more concerned with and that is dojo is loaded both into the parent and the child iframe. This is because we want to use things like dijit widgets and other advanced rendering ideas in both the parent and the child windows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Scenario 1 - Child frame = Simple content&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For the first case where we only want to access information in the child window, tools such as dojo.setContext and dojo.withGlobal are perfect as they temporarily swap dojo's context to act as if it were within that child window. From there all the calls to finding dom nodes etc are performed locally in that child window. Be careful though as these methods swap the context of the global object so all dojo related commands are performed within the current context. If you leave the context locked to a child frame and don't swap it back in time for some parent code to run, things can behave badly.&lt;br /&gt;&lt;br /&gt;As far as I know you can't reliably create dijit widgets in a child iframe whilst keeping all the dojo code hosted in the parent frame. I'd be really happy if someone told me I was wrong on this.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Scenario 2 - Child frame = Dojo content&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For the second scenario we load dojo code twice (first in the parent and then in the child iframe window) but we do have the advantage that dojo is allowed to work independently of other documents. No worries about concurrently running code and context sharing / swapping. Other things like dijit don't have to worry about sharing manager code cross-window either.&lt;br /&gt;&lt;br /&gt;Apart from the heavy lifting of the code there is one other downside to a dojo in each frame as pointed out by &lt;a href="http://jpsykes.com/126/dojo-and-iframes-tip"&gt;JPSykes in his entry&lt;/a&gt;. There is a siloing effect between the frames as they don't register with one another or communicate with one another. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Speeding up the load&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Given that I want to load dojo in each frame to gain full dojo/dijit functionality I found a way of making the code loading experience a little smoother. When we initialise a page with iframes we load the parent window and then it's dojo resource, then repeat for the child window and it's dojo resource. Since we are loading dojo twice I wondered could I leverage what the parent window knows of the dojo code?&lt;br /&gt;&lt;br /&gt;Looking at the mechanics of dojo, dojo loads code with dojo.require and that is a very elaborate (and really fantastic) wrapper to the native xml http request object. That means underneath it all, we are still just getting text and evaluating it into the page. This is what caught my attention. If you dig deep enough through the dojo.load methods you'll find a method called dojo._loadUri. &lt;br /&gt;&lt;br /&gt;dojo._loadUri uses _getText to retrieve a string of the code and drop it into the page. My theory was, what if we don't just discard that string but rather add it to a storage object and then get a child frame when it calls dojo.require to ask the parent "have you already got this?". If it does, instead of making a remote request, we can grab it off the storage node, hopefully speeding things up. &lt;br /&gt;&lt;br /&gt;When you step back from the technical side, this becomes an in-page caching system using dojo.require as the interface to that data cache. So is it possible? The following I store in a file called parentCache.js and load directly after loading dojo.js:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;var codeRepository = {};    &lt;br /&gt;if(typeof(djConfig.noParentCache)==&amp;quot;undefined&amp;quot;){&lt;br /&gt;    dojo._loadUri = function(/*String (URL)*/uri, /*Function?*/cb){&lt;br /&gt;        if(this._loadedUrls[uri]){ return true; }&lt;br /&gt;        var topWindow = window.top;&lt;br /&gt;        if((topWindow)&amp;amp;&amp;amp;(topWindow != window.self)){&lt;br /&gt;            // attempt to load in the parent window&lt;br /&gt;            topWindow.dojo._loadUri(uri);&lt;br /&gt;            // make sure we have a storage node&lt;br /&gt;            if(topWindow.codeRepository){&lt;br /&gt;                // load from parent&lt;br /&gt;                var contents = topWindow.codeRepository[uri];&lt;br /&gt;            }&lt;br /&gt;            if(!contents){&lt;br /&gt;                //not present, try loading manually locally.&lt;br /&gt;                var contents = this._getText(uri, true);            &lt;br /&gt;            }&lt;br /&gt;        } else {&lt;br /&gt;            //we are the parent, load it manually.&lt;br /&gt;            var contents = this._getText(uri, true);            &lt;br /&gt;        }&lt;br /&gt;        if(!contents){ return false; }&lt;br /&gt;        codeRepository[uri] = contents;&lt;br /&gt;        this._loadedUrls[uri] = true;&lt;br /&gt;        this._loadedUrls.push(uri);&lt;br /&gt;        if(cb){ contents = '('+contents+')'; }&lt;br /&gt;        var value = dojo[&amp;quot;eval&amp;quot;](contents+&amp;quot;\r\n//@ sourceURL=&amp;quot;+uri);&lt;br /&gt;        if(cb){ cb(value); }&lt;br /&gt;        topWindow = null;&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;} else {&lt;br /&gt;    console.log(&amp;quot;------------------------ no parentCache ----------------------------&amp;quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note. Yes, I'm sure you can make this more compact or streamlined.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;By keeping this separate from dojo I don't have to worry about re-editing dojo code when we upgrade. Looking at the code, it overrides the loadUri method with the new ability as described above. It is also wrapped in a check that checks djConfig for the noParentCache flag. If that is set to true then we don't worry about this caching idea. This flag is very helpful for development as without it, if we change code and try to reload the iframe, it'll grab the cached copy off the parent again without picking up the saved file changes.&lt;br /&gt;&lt;br /&gt;The real catch for this is that you don't create monolithic dojo build files anymore. Loading everything up with a single dojo.js means only a minor advantage for the iframe caching as we still need to load a base dojo.js file to start things. Finding a balance between how much of an initial load you do and how much you allow to cache for child frames is a bit of a guessing game. What it does mean though is that child frames no longer care how fast or reliable your internet connection is once you start getting cached info off the parent.&lt;br /&gt;&lt;br /&gt;Again I don't claim this to be perfect, the "best way" or Dojo compliant. It's just exploring ideas.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Overcoming the Silo&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;How we approach cross iframe communication really depends on the requirements. If we want to broadcast a message to all frames then we can use dojos fantastic topic / publish code to push a message around. We can even create wrappers that loop over each frame and use withGlobal just as mentioned in discussions &lt;a href="http://www.liucougar.net/blog/archives/88"&gt;found here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The thing I've found is that it's often easiest to use window.top to always find the root parent window and work from there. Whether it's pushing information into a common storage point or cascading a message or action back down through the frames. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Caution&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;From all this cross frame tinkering, there are known memory leak conditions under IE that can occur with window and variable references if not cleaned up. If you are communicating between windows, try and keep the information that is passed between them, contained and clean it up when the function is finished. Iframe memory leaking with the dojo object seems to occur under IE no matter what I do but some minor things like stray variable references can have massive impacts on how much is leaked.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-3014068263633566206?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/3014068263633566206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=3014068263633566206' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3014068263633566206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3014068263633566206'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/dojo-iframes.html' title='Dojo + Iframes'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-1142362843337898693</id><published>2008-02-21T18:13:00.000-08:00</published><updated>2008-02-21T18:30:01.476-08:00</updated><title type='text'>D + J - Simple Tree Test</title><content type='html'>Simple test case grabbing a file list of the dojo dir (one child deep) and pushing that into a dijit.tree widget. &lt;br /&gt;&lt;br /&gt;Disclaimer: I'm in no way claiming this to be the "right" way of doing things with Dojo or Jaxer. This is just some experimenting.&lt;br /&gt;&lt;br /&gt;&lt;a title="treeSnip.jpg" href="http://s127.photobucket.com/albums/p147/ashendw/?action=view&amp;current=treeSnip.jpg"&gt;&lt;img src="http://i127.photobucket.com/albums/p147/ashendw/th_treeSnip.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;      @import &amp;quot;dijit/themes/dijit.css&amp;quot;;    &lt;br /&gt;      @import &amp;quot;dijit/themes/tundra/tree.css&amp;quot;;    &lt;br /&gt;      @import &amp;quot;dojo/resources/dojo.css&amp;quot;;&lt;br /&gt;      @import &amp;quot;dijit/tests/css/dijitTests.css&amp;quot;;      &lt;br /&gt;    &amp;lt;/style&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body class=&amp;quot;tundra&amp;quot;&amp;gt;      &lt;br /&gt;    &amp;lt;script runat=&amp;quot;client&amp;quot; src=&amp;quot;dojo/dojo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;    &lt;br /&gt;    &amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;      //dojo compatability block&lt;br /&gt;      Jaxer.load(&amp;quot;dojoCompat.js&amp;quot;);      &lt;br /&gt;      function oncallback(){&lt;br /&gt;        Jaxer.load(&amp;quot;dojoCompat.js&amp;quot;);&lt;br /&gt;        dojo = window.dojo;&lt;br /&gt;      }&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;      &lt;br /&gt;      function getFolderInfo(pathStr, level){  &lt;br /&gt;        var maxLevel = 1; //hard coded limiter for quick test case&lt;br /&gt;        if(!pathStr){ pathStr = &amp;quot;dojo&amp;quot;; } &lt;br /&gt;        if(!level){ level = 0; }&lt;br /&gt;        var dir = new Jaxer.Dir(Jaxer.Dir.resolvePath(pathStr));&lt;br /&gt;        var files = dir.readDir();&lt;br /&gt;        var fileNames = [];&lt;br /&gt;        try{&lt;br /&gt;          dojo.forEach(files,function(item, index, data){&lt;br /&gt;            var name = item.getLeaf();&lt;br /&gt;            var info = {&lt;br /&gt;              &amp;quot;id&amp;quot;:(&amp;quot;node&amp;quot;+index),&lt;br /&gt;              &amp;quot;name&amp;quot;:name,&lt;br /&gt;              &amp;quot;isDir&amp;quot;:item.isDir(),&lt;br /&gt;              &amp;quot;isFile&amp;quot;:item.isFile()&lt;br /&gt;              };&lt;br /&gt;            if(item.isDir()){&lt;br /&gt;              if(level == maxLevel){&lt;br /&gt;                info.children = []; &lt;br /&gt;              } else {&lt;br /&gt;                var newPath = (pathStr+&amp;quot;/&amp;quot;+name);&lt;br /&gt;                info.children = getFolderInfo(newPath,(level+1));&lt;br /&gt;              }&lt;br /&gt;            }&lt;br /&gt;            fileNames.push(info);&lt;br /&gt;          });&lt;br /&gt;        } catch(e){}&lt;br /&gt;        return fileNames;&lt;br /&gt;      };&lt;br /&gt;      &lt;br /&gt;      function getData(){&lt;br /&gt;        return dojo.toJson(getFolderInfo());&lt;br /&gt;      }&lt;br /&gt;      getData.proxy = true;      &lt;br /&gt;    &amp;lt;/script&amp;gt;  &lt;br /&gt;    &amp;lt;script runat=&amp;quot;client&amp;quot;&amp;gt;&lt;br /&gt;      dojo.require(&amp;quot;dijit.Tree&amp;quot;);&lt;br /&gt;      dojo.require(&amp;quot;dojox.data.jsonPathStore&amp;quot;);&lt;br /&gt;      dojo.require(&amp;quot;dojo.parser&amp;quot;);&lt;br /&gt;      &lt;br /&gt;      function buildTree(){&lt;br /&gt;        var dirStructure = dojo.fromJson(getData());&lt;br /&gt;        var data = new dojox.data.jsonPathStore({&lt;br /&gt;          data:dirStructure, &lt;br /&gt;          idAttribute:&amp;quot;id&amp;quot;, &lt;br /&gt;          labelAttribute:&amp;quot;name&amp;quot;})&lt;br /&gt;        var tree = new dijit.Tree({&lt;br /&gt;          store:data, &lt;br /&gt;          label:&amp;quot;root&amp;quot;, &lt;br /&gt;          labelAttr:&amp;quot;name&amp;quot;, &lt;br /&gt;          somePropertyAttr:&amp;quot;name&amp;quot;, &lt;br /&gt;          query:{query: '$[*]'}});&lt;br /&gt;        dojo.byId('placeholder').appendChild(tree.domNode);&lt;br /&gt;      }&lt;br /&gt;      dojo.addOnLoad(buildTree);&lt;br /&gt;    &amp;lt;/script&amp;gt;    &lt;br /&gt;    &amp;lt;div id=&amp;quot;placeholder&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;    &lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-1142362843337898693?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/1142362843337898693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=1142362843337898693' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1142362843337898693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1142362843337898693'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/d-j-simple-tree-test.html' title='D + J - Simple Tree Test'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-1577807857567453066</id><published>2008-02-21T17:51:00.001-08:00</published><updated>2008-02-21T18:07:48.521-08:00</updated><title type='text'>dojo + jaxer - Updated compatibility block</title><content type='html'>Most recent revision of the compatibility block that gives dojo on server and callbacks.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;    //dojo compatibility block&lt;br /&gt;    Jaxer.load(&amp;quot;dojoCompat.js&amp;quot;);            &lt;br /&gt;    function oncallback(){&lt;br /&gt;        Jaxer.load(&amp;quot;dojoCompat.js&amp;quot;);&lt;br /&gt;        dojo = window.dojo;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;dojoCompat.js:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;var djConfig = {baseUrl:&amp;quot;dojo/&amp;quot;};&lt;br /&gt;Jaxer.load(djConfig.baseUrl+&amp;quot;dojo.js&amp;quot;);&lt;br /&gt;dojo._loadUri = function(/*String (URL)*/uri, /*Function?*/cb){                &lt;br /&gt;    Jaxer.load(uri);        &lt;br /&gt;    return true;&lt;br /&gt;}&lt;br /&gt;dojo.toJson = function(obj){&lt;br /&gt;    return Jaxer.Serialization.toJSONString(obj);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At this point I can now build up dojoCompat.js to add in further overrides and compatibility tweaks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-1577807857567453066?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/1577807857567453066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=1577807857567453066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1577807857567453066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1577807857567453066'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/dojo-jaxer-updated-compatibility-block.html' title='dojo + jaxer - Updated compatibility block'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-3623142756648491200</id><published>2008-02-21T17:39:00.000-08:00</published><updated>2008-02-21T17:42:54.039-08:00</updated><title type='text'>Jaxer + Dojo - dojo.toJson</title><content type='html'>For some reason calling dojo.toJson on the server with Jaxer outputs arrays as objects with indexes. No biggie.. Jaxer provides a serialization extension of it's own. Server side tweak:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;dojo.toJson = function(Obj){&lt;br /&gt;  return Jaxer.Serialization.toJSONString(obj);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-3623142756648491200?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/3623142756648491200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=3623142756648491200' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3623142756648491200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3623142756648491200'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/jaxer-dojo-dojotojson.html' title='Jaxer + Dojo - dojo.toJson'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-3133237490005301587</id><published>2008-02-21T14:37:00.000-08:00</published><updated>2008-02-21T14:43:14.629-08:00</updated><title type='text'>Jaxer + Dojo - callbacks</title><content type='html'>One quick note.. I noticed when doing callbacks that I could see dojo but the second I tried to use it for anything more than a property (like getting the dojo version) things always crashed.&lt;br /&gt;&lt;br /&gt;Reason can be found in the discussion of making JQuery run in jaxer. There are three instances of the Dom. Pre-render server, client side and callback. Callback currently doesn't share the same environment so they use a function "oncallback" to to a quick setup before actioning server side callback commands. &lt;br /&gt;&lt;br /&gt;To make dojo work correctly with my server-side and callbacks I just the following into my runat='server' block:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;function oncallback(){&lt;br /&gt;    Jaxer.load(&amp;quot;dojo/dojo.js&amp;quot;);&lt;br /&gt;    dojo = window.dojo;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.aptana.com/node/202"&gt;further info on the matter&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-3133237490005301587?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/3133237490005301587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=3133237490005301587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3133237490005301587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3133237490005301587'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/jaxer-dojo-callbacks.html' title='Jaxer + Dojo - callbacks'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-4924138934442986750</id><published>2008-02-20T22:21:00.000-08:00</published><updated>2008-02-20T22:29:12.581-08:00</updated><title type='text'>Jaxer + Dojo</title><content type='html'>I like the idea of this Jaxer stuff but being a dojo guy have the tricky position of most of the code coming into pages via dojo.require.&lt;br /&gt;&lt;br /&gt;Feeling I still wanted dojo at the server side I did a quick hack that seems to work well enough for now. Note you MUST use a build release because the initial loader / bootstrap stuff goes badly if left to try and self load. Using a compressed build file means everything comes in with the standard script tag.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 420px"&gt;&lt;code&gt;&amp;lt;script runat=&amp;quot;server&amp;quot; src=&amp;quot;dojo/dojo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;        &lt;br /&gt;&amp;lt;script runat=&amp;quot;client&amp;quot; src=&amp;quot;dojo/dojo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;        &lt;br /&gt;&amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;    dojo.baseUrl = &amp;quot;dojo/&amp;quot;;&lt;br /&gt;    dojo._loadUri = function(/*String (URL)*/uri, /*Function?*/cb){                &lt;br /&gt;        Jaxer.load(uri);        &lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Adjust the base path to match your directory structure.&lt;br /&gt;&lt;br /&gt;Note I have included dojo twice rather than runat="both".. this is because I don't want the server side version to be pushed to the client. The client side version reloads a clean instance of Dojo with all the browser state set correctly.&lt;br /&gt;&lt;br /&gt;From then on, server side we can call dojo.require to pick up files and use them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-4924138934442986750?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/4924138934442986750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=4924138934442986750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4924138934442986750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4924138934442986750'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/jaxer-dojo.html' title='Jaxer + Dojo'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-1462344578600861967</id><published>2008-02-09T17:39:00.000-08:00</published><updated>2008-02-09T19:01:44.780-08:00</updated><title type='text'>Java style Iterator in Dojo</title><content type='html'>I love iterators.. no more clashing of variables in for loops etc..But I'm a java guy so here's a java style Iterator extended from the dojox.collections.Iterator&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;dojo.provide("core.Iterator");&lt;br /&gt;&lt;br /&gt;dojo.declare(&lt;br /&gt; "core.Iterator",&lt;br /&gt; null,&lt;br /&gt; {&lt;br /&gt;  constructor: function(/*array*/ arr){&lt;br /&gt;   this.a = arr;&lt;br /&gt;   this.index = 0;&lt;br /&gt;   this.element = this.a[0]||null;&lt;br /&gt;  },&lt;br /&gt;  &lt;br /&gt;  _position: 0,&lt;br /&gt;  &lt;br /&gt;  hasNext: true,&lt;br /&gt;  element: null,&lt;br /&gt;  &lt;br /&gt;  atEnd: function(){&lt;br /&gt;   return (this._position&gt;=this.a.length);&lt;br /&gt;  },&lt;br /&gt;  &lt;br /&gt;  next: function(){&lt;br /&gt;   this.index = this._position;&lt;br /&gt;   this.element = !this.atEnd() ? this.a[this._position++] : null;&lt;br /&gt;   this.hasNext = !this.atEnd();&lt;br /&gt;   return this.element;&lt;br /&gt;  },&lt;br /&gt;  &lt;br /&gt;  reset: function(){&lt;br /&gt;   this.index = this._position = 0;&lt;br /&gt;   this.hasNext = !this.atEnd();&lt;br /&gt;   this.element = this.a[0]||null;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Usage:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var arr = [1,2,3]&lt;br /&gt;var iterator = new core.Iterator(arr);&lt;br /&gt;while(iterator.hasNext){&lt;br /&gt; doSomething(iterator.next());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-1462344578600861967?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/1462344578600861967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=1462344578600861967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1462344578600861967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1462344578600861967'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/02/java-style-iterator-in-dojo.html' title='Java style Iterator in Dojo'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-5071184079003270607</id><published>2008-01-10T19:09:00.000-08:00</published><updated>2008-01-10T19:16:23.165-08:00</updated><title type='text'>Javascript vs HTML environment</title><content type='html'>At the moment we have a browser that is a html oriented environment supporting javascript.&lt;br /&gt;&lt;br /&gt;With all the JS engine development lately, how long will it be before we see a javascript environment that supports HTML?&lt;br /&gt;&lt;br /&gt;Already we draw pages using almost soley dom manipulation in the browser. Wouldn't it be interesting to go to a javascript page in your app and start drawing immediately rather than using html scaffolding and page loading events.&lt;br /&gt;&lt;br /&gt;Rhino (the java / js engine) has always intregued me. Maybe we need to think more along those lines?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-5071184079003270607?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/5071184079003270607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=5071184079003270607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/5071184079003270607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/5071184079003270607'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2008/01/javascript-vs-html-environment.html' title='Javascript vs HTML environment'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-2466000583011255538</id><published>2007-12-11T18:01:00.000-08:00</published><updated>2007-12-11T18:14:05.582-08:00</updated><title type='text'>Dojo Presentation Shorthand</title><content type='html'>I like the idea of a browser based simple Powerpoint. I'm not a fan of crazy transition effects as I feel they waste time and get annoying. Fade in some bullet points and I'm done.&lt;br /&gt;&lt;br /&gt;Hence the dojox.presentation work is a step in the right direction for me. I didn't however like the idea of duplicating each "part" with an "action" when I wanted to consistently fade in each bullet. So I made a function to simplify things.&lt;br /&gt;&lt;br /&gt;The addOnLoad will go through the page hunting for elements with the class ".part" inside slides and then convert them to part widgets. In the process it builds a matching action widget with the default settings. We have to manually push the items into the slide so the slide knows what to do. &lt;br /&gt;&lt;br /&gt;I also built a variant to hunt for particular nodes so the li's get targetted without a class but I'll leave that to your imagination. Much more compact code and almost as easy as typing it up in powerpoint.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;dojo.addOnLoad(function(){&lt;br /&gt; var slides = dijit.registry.byClass("dojox.presentation.Slide");&lt;br /&gt; var partCounter = 0;&lt;br /&gt; slides.forEach(function(slide){&lt;br /&gt;   var parts = dojo.query(".part",slide.domNode);    &lt;br /&gt;   parts.forEach(function(part){    &lt;br /&gt;     var partname = 'part' + partCounter; &lt;br /&gt;     var partWidget = new dojox.presentation.Part({as:partname},part);&lt;br /&gt;     slide._parts.push(partWidget);&lt;br /&gt;     var tempNode = document.createElement('input');&lt;br /&gt;     slide.domNode.appendChild(tempNode);&lt;br /&gt;     var actionWidget = new dojox.presentation.Action({forSlide:partname},tempNode);&lt;br /&gt;     slide._actions.push(actionWidget);&lt;br /&gt;     partCounter++;&lt;br /&gt;   })&lt;br /&gt; })&lt;br /&gt;}) &lt;br /&gt;&lt;br /&gt;...html snip...&lt;br /&gt;&lt;br /&gt;&amp;lt;div dojoType="dojox.presentation.Deck" id="testPresentation"&gt;&lt;br /&gt;  &amp;lt;div dojoType="dojox.presentation.Slide" title="Slide 1"&gt;&lt;br /&gt;    &amp;lt;p&gt;Nothing special to start with&amp;lt;/p&gt;&lt;br /&gt;  &amp;lt;/div&gt;&lt;br /&gt;  &amp;lt;div dojoType="dojox.presentation.Slide" title="Slide 2"&gt;&lt;br /&gt;    &amp;lt;p&gt;Now for some fade in points&amp;lt;/p&gt;&lt;br /&gt;    &amp;lt;li class='part'&gt;Item 1&amp;lt;/li&gt;&lt;br /&gt;    &amp;lt;li class='part'&gt;Item 2&amp;lt;/li&gt;&lt;br /&gt;  &amp;lt;/div&gt;&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-2466000583011255538?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/2466000583011255538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=2466000583011255538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/2466000583011255538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/2466000583011255538'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2007/12/dojo-presentation-shorthand.html' title='Dojo Presentation Shorthand'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-390905945082814481</id><published>2007-12-06T14:54:00.000-08:00</published><updated>2007-12-06T15:08:05.803-08:00</updated><title type='text'>Dom Tree vs Code Mash</title><content type='html'>One thing that I've started to feel more and more is my dislike of mashed up presentation code. What made me think of it was reading some raw PHP. PHP has frameworks to split out evaluation code from inline html but most often you just see part of the page break out into some code then transition back into html, back and forth throughout the page.&lt;br /&gt;&lt;br /&gt;This makes me uncomfortable these days and most likely as I'm primarily a Java / JavaScript developer. My JS code has the convention of being a single block in the page or a separate file and the html is a scaffold that I work with. Code is evalutated before or after a page load so timing is no longer an issue and I rarely need to figure things out on the fly as the page is being drawn.  It's not always the easiest to read either when you have JS code connecting to elements in the page but it usually only takes a little browsing and some good coding conventions to find your way.&lt;br /&gt;&lt;br /&gt;The part I like about this dividing of code is browsing the HTML, I don't get lost in code. In a dom tree you don't tend to snap the tree in half and start spitting out some ascii before you pick up where you left off. I feel this should be true for the actual code.&lt;br /&gt;&lt;br /&gt;In my opinion, the MVC concept isn't just for enterprise level server, browser, database constructs.. As javascript gets used more and more there's a page level variant on this idea too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-390905945082814481?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/390905945082814481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=390905945082814481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/390905945082814481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/390905945082814481'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2007/12/dom-tree-vs-code-mash.html' title='Dom Tree vs Code Mash'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-3261890488418466230</id><published>2007-11-06T15:13:00.000-08:00</published><updated>2007-11-06T15:40:15.096-08:00</updated><title type='text'>Parent Caching</title><content type='html'>So caching is a tricky one. The browser should cache requests to make things faster so that when we repeatedly need resources, it doesn't have to keep running off and fetching things. Instead it just dips into a local file cache and presto a quick load.&lt;br /&gt;&lt;br /&gt;Enter dojo using XHR to fetch the code and in my case, throw in a bit of HTTPS style complication. At this point can we be sure what is being cached and when over all browsers?&lt;br /&gt;&lt;br /&gt;Backing up a bit, I have a fairly unique case of dojo usage where I have iframes (each using dojo) inside a consistant non-refreshing parent page. The creating of iframes and loading means I end up with a lot of code duplication and code loading.&lt;br /&gt;&lt;br /&gt;To access the code in each page and frame, dojo.require is used fetching plain text that gets eval'ed into the page. If a browser isn't clever enough to cache XmlHttpRequest object feeds we are fetching that same code over and over. &lt;br /&gt;&lt;br /&gt;What if we kept hold of that raw text javascript code? What if we use the fact that the parent page doesn't refresh? And what if we started making it available to child iframe pages. Then child iframes could start asking the parent for code and if it's not available, let the parent go get it and keep it for other pages to use also.&lt;br /&gt;&lt;br /&gt;This effectively makes the parent page a local proxy for dojo.require. The concept when you think about it isn't too hard and looking into the dojo.loader code it wasn't hard to implement either.&lt;br /&gt;&lt;br /&gt;I first load the dojo.js file always and then load a secondary javascript file that overides the dojo._loadUri method. This way feels less obtrusive and I don't loose my changes when we upgrade dojo.&lt;br /&gt;&lt;br /&gt;This is my first hack version (and it is a proof of concept hack created in all of 10 minutes):&lt;br /&gt;&lt;br /&gt; var codeRepository = {}; &lt;br /&gt; dojo._loadUri = function(/*String (URL)*/uri, /*Function?*/cb){&lt;br /&gt;   if(this._loadedUrls[uri]){&lt;br /&gt;     return true; // Boolean&lt;br /&gt;   }&lt;br /&gt;   var topWindow = window.top;&lt;br /&gt;   if((topWindow)&amp;&amp;(topWindow !=window.self)){&lt;br /&gt;      topWindow.dojo._loadUri(uri);&lt;br /&gt;      if(topWindow.codeRepository){&lt;br /&gt;        var contents = topWindow.codeRepository[uri];&lt;br /&gt;      }&lt;br /&gt;      if(!contents){&lt;br /&gt;        var contents = this._getText(uri, true);   &lt;br /&gt;      }&lt;br /&gt;    } else {&lt;br /&gt;      var contents = this._getText(uri, true);   &lt;br /&gt;    }&lt;br /&gt;    if(!contents){ return false; } // Boolean&lt;br /&gt;    codeRepository[uri] = contents;&lt;br /&gt;    this._loadedUrls[uri] = true;&lt;br /&gt;    this._loadedUrls.push(uri);&lt;br /&gt;    if(cb){ contents = '('+contents+')'; }&lt;br /&gt;      var value = dojo["eval"](contents+"\r\n//@ sourceURL="+uri);&lt;br /&gt;      if(cb){ cb(value); }&lt;br /&gt;      return true; // Boolean&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;The function hasn't changed significantly other than whenever we get code we always push it to the code repository object (this in theory should be optimized to only new code).&lt;br /&gt;&lt;br /&gt;Also we use having a parent as a means of knowing when to get the code from above and when to resort loading in the standard way. You need to check that the top most window isn't actually your current window or bad looping will occur.&lt;br /&gt;&lt;br /&gt;Finally there is a failsafe. If things go badly and with all our loading you still have no content, the current page will try loading the content the old fashioned way. &lt;br /&gt;&lt;br /&gt;The result is as you open iframes and use the system more, code accumulates in the parent page and overall there are fewer requests. With usage, things get faster and if you have a remote user on a slow connection things will speed up dramatically.&lt;br /&gt;&lt;br /&gt;This does break one rule though. This system takes advantage of small dojo.require requests. The dojo guys recommend you build a unified file will your most common code merged together and then load that via script tags so that future requires already have the code there. This can't optimize for that as we take hold of the code as we remotely fetch it. &lt;br /&gt;&lt;br /&gt;Hence there is a fine line between merging and inline loading code versus leaving it in separate files for some parent caching and dojo.require fetching. Overall things seem to be working better than expected with this approach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-3261890488418466230?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/3261890488418466230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=3261890488418466230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3261890488418466230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/3261890488418466230'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2007/11/parent-caching.html' title='Parent Caching'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-1524649710085155725</id><published>2007-10-14T18:35:00.000-07:00</published><updated>2007-10-14T18:36:04.801-07:00</updated><title type='text'>Widgets vs Managers</title><content type='html'>This isn't a "my way is best" article. It's just something I've been thinking on recently.&lt;br /&gt;&lt;br /&gt;With all the push for widget development lately we are getting really good at turning an inert snippet of HTML into a full blown widget with many abilities. Also where we once had a few of these on a page we are now starting to build applications with masses of functionality.&lt;br /&gt;&lt;br /&gt;While it is very clean to package up the functionality of a widget into a unit of code I've also used the pattern that a widget is merely a place to store data and link information to a dom object while the heart of the functionality is stored in a manager or shared resource.&lt;br /&gt;&lt;br /&gt;Which approach you use I think depends on the case. But I don't think we should forget that repeating yourself may not always be the best and most efficient answer.&lt;br /&gt;&lt;br /&gt;A simple example of this can be seen in Dijit's tooltip. The master tooltip is drawn and then moved and repopulated as required. Both a widget and being smart about how you create many instances of the same visual components.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-1524649710085155725?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/1524649710085155725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=1524649710085155725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1524649710085155725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/1524649710085155725'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2007/10/widgets-vs-managers.html' title='Widgets vs Managers'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6805679788123355859.post-4701224843331643451</id><published>2007-09-26T18:06:00.000-07:00</published><updated>2007-09-26T18:17:12.246-07:00</updated><title type='text'>What does $ mean to you?</title><content type='html'>&lt;a href="http://www.sitepen.com/blog/2007/09/24/a-fine-line-between-abstraction-and-obfuscation/"&gt;This article&lt;/a&gt; in the section "More on Naming" says exactly what I've been thinking for months now. &lt;br /&gt;&lt;br /&gt;People in Java land are smart enough to use full word method names so you can read your code later but when I get into javascript and libraries like Prototype I start seeing punctuation scattered everywhere and single letters. This reminds me of Perl which is the only language I'm aware of that has a competition to figure out what a single line of code actually does.&lt;br /&gt;&lt;br /&gt;If you want to write code that is meaningful, maintainable and others can interact with that aren't pro javascript writers, make things readable. Use names like getNode, setValue etc.. if you're worried about file size, develop this way and then run your code through a compressor like the ones provided by Yahoo, Dojo and many other sources now.&lt;br /&gt;&lt;br /&gt;As a random note, sure Javascript doesn't have Typing but I really like the convention started by Dojo to use commented types in front of variable names on method definitions.&lt;br /&gt;&lt;br /&gt;eg setValue(/*int*/ val) &lt;br /&gt;&lt;br /&gt;or &lt;br /&gt;&lt;br /&gt;updatePage(/*String*/ content, /*Boolean*/ forceUpdate, /*int?*/ index)&lt;br /&gt;&lt;br /&gt;Here we can easily see what we expect a variable value to be and the use of "?" suggests that the variable is optional. You need not adhere to the standard types. I often throw in the type /*DOM Node*/ or a custom object name. The key is you know what it should be when you go to use the function and so do other people.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6805679788123355859-4701224843331643451?l=dojofindings.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dojofindings.blogspot.com/feeds/4701224843331643451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6805679788123355859&amp;postID=4701224843331643451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4701224843331643451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6805679788123355859/posts/default/4701224843331643451'/><link rel='alternate' type='text/html' href='http://dojofindings.blogspot.com/2007/09/what-does-mean-to-you.html' title='What does $ mean to you?'/><author><name>Tony Issakov</name><uri>http://www.blogger.com/profile/14073612676446851996</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12773181674037980197'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>