IE doesn't let us REST

Posted by Jonathan

The reason why wrote up my rant about not getting too exited about REST is that I had some fun time paying for my blind usage of REST.

While developing Webistrano I thought that this would be a nice project for playing with all the RESTful stuff that Rails currently offers. So I started to map my resources and thereby only allowing certain HTTP verbs to certain URLs.

This all works nice until reality in the form of IE hunts you down.

Until recently all my Ajax calls used HTTP POST for getting updates from the server. I used POST for so long that I didn't remember why. In Webistrano I use Ajax to periodically get status updates on a running deployment. As getting status updates translates perfectly to HTTP GET on the resource I used this code for it:

# controller
def show
  @deployment = @stage.deployments.find(params[:id])

  respond_to do |format|
    format.html # show.rhtml
    format.xml  { render :xml => @deployment.to_xml }
    format.js { render :partial => 'status' }
  end
end

# view _status.rhtml
<% unless @deployment.completed? %>
  <script type="text/javascript">    
    function update_status(){
      new Ajax.Updater('status_info','<%=h project_stage_deployment_path(current_project, current_stage, @deployment) %>',{
        method: 'get',
        evalScripts: true
      });
    }
    
    setTimeout(update_status, 3000);
  </script>
<% end %>    

This worked nicely in Safari and Firefox but Internet Explorer would update the status-div with the whole page. So you got the page-in-a-page effect. I've spend several hours trying to debug from where IE was getting this strange output and why there were no requests to the server. And then I found the answer and remembered why in the past I always used HTTP POST for my Ajax calls.

IE was caching the GET Ajax call.

In order to prevent IE from caching Ajax calls your need to either supply different parameters on each request or switch to POST. Switching to POST is not so easy as Rails will not allow POST requests to the .../deployments/1 resource. So unique parameters on each request it is:

# view _status.rhtml
<% unless @deployment.completed? %>
  <script type="text/javascript">    
    function update_status(){
      new Ajax.Updater('status_info','<%=h project_stage_deployment_path(current_project, current_stage, @deployment) %>',{
        method: 'get',
        evalScripts: true,
        parameters: {
          random_differentiator: Math.floor(Math.random()*50000) // work around IE caching bug
        }
      });
    }
    
    setTimeout(update_status, 3000);
  </script>
<% end %>

The alternative would be to define a custom action on the deployment resource that would answer to a HTTP POST but this destroys the whole "one resource URL, different representations" REST thing.

So long for RESTful Web Applications with IE.

tooltip.js - version 0.2

Posted by Jonathan

I just releases version 0.2 of my tooltip.js library.

The new version follows the mouse correctly on Firefox (thanks to Graham TerMarsch) and can apply a constant delta when displaying the tooltip. This can be useful if your CSS rules include absolute positioning that can result in a constant offset.

var my_tooltip = new Tooltip('id_of_trigger_element', 
                            'id_of_tooltip_to_show_element', 
                            { delta_x: -210, delta_y: 20 })

Another nice addition (by Xavier Lepaul) is the ability to create tooltips out of given text. Version 0.1 required you to give it the DOM id of a valid element. Version 0.2 will create a div with the class tooltip if it is given only text:

var my_other_tooltip = new Tooltip('id_of_trigger_element', 'a nice description')

This can be used to create popups out of title attributes:

Event.observe(window,"load",function() { 
  $$("*").findAll(function(node){
    return node.getAttribute('title');
   }).each(function(node){
     new Tooltip(node,node.title);
     node.removeAttribute("title");
   });
}); 

You can get tooltip.js here and you can try out the live demo.

Rails-Konferenz

Posted by Jonathan

Rails-Konferenz was really a success, nearly a hundred people showed up!

Lot’s of interesting talks and I’m looking forward to the next one.

The slides to my talk about JavaScript and RJS in Rails should soon on the Rails-Konferenz site.

There are also available here:

JavaScript und Ajax mit Rails

tooltip online demo

Posted by Jonathan

After several requests I’ve put up an online demo for tooltip.js and it now has it’s own page.

A lightweight prototype based JavaScript tooltip

Posted by Jonathan

For a recent project I needed JavaScript tooltip functionality for showing detail information. All tooltip libraries that I came across were too complicated and bloatet, did just too much and most of the time were still not flexible enough with the tooltip. So I decided to create my own library that is based on prototype.js:

<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/tooltip.js" type="text/javascript"></script>

<div id='tooltip' style="display:none; margin: 5px; background-color: red">
  Detail infos on product 1....<br />
</div>

<div id='product_1'>
  This is product 1
</div>

<script type="text/javascript">
  var my_tooltip = new Tooltip('product_1', 'tooltip')
</script>

Now whenever you trigger a mouseOver on the `trigger` element, the tooltip element will be shown slightly below the mouse pointer. On the mouseOut event the tooltip disappears. The script is clever enough to move the tooltip to the top and/or left if there is not enough space left on the screen to display the tooltip.

This way you are totally flexible with the tooltip. It can be any div with any CSS you like.

You can use my_tooltip.destroy() to remove the event observers and thereby the tooltip.

At the moment the tooltip appears and hides with Element.show() and Element.hide() but a future version will use the script.aculo.us effects.

Download it here (BSD license): tooltip-v0.1.js

UPDATE:
I've put up an online demo here. In the future more updates can be found here.

Dojo and Rails or better Dojo and the base relative path

Posted by Jonathan

For a new project we need a WYSIWYG editor and my experiences with FCKeditor are not the best. It throws a bunch of JavaScript errors and warnings and just doesn’t feel right.

As I know Prototype and script.aculo.us quite good I thought I should give Dojo and their nice editor a try. Dojo is a heavy-weight framework compared with Prototype but has some very nice Widgets.

Normally you integrate Dojo like this:

&lt;script src="path/to/dojo/dojo.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
  dojo.require("dojo.widget.*");
  dojo.require("dojo.widget.Editor");
  //.. have fun with Dojo
&lt;/script&gt;

In my case I wanted to use the Dojo rich text editor in a view called /mail/new so I had this code in app/view/mail/new.rhtml:

&lt;script src="/javascripts/dojo/dojo.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
  dojo.require("dojo.widget.*");
  dojo.require("dojo.widget.Editor");
  //.. have fun with Dojo
&lt;/script&gt;

So you just include the core Dojo source file and the rest is done by magic. The problem is that this magic relies on finding dojo in a path relative to this file and does not use the path you used to include the core file. I got this error:

Could not load 'dojo.widget.Editor'; last tried '__package__.js'

If you look (e.g. with FireBug) where Dojo tried to load the JavaScript from you will see

GET http://localhost:3000/mail/src/widget/Editor.js
GET http://localhost:3000/mail/src/widget.js
GET http://localhost:3000/mail/src/__package__.js
GET http://localhost:3000/mail/__package__.js

I looked through the documentation and searched for a way to tell Dojo where all it’s files are. I found this solution:

&lt;script src="/javascripts/dojo/dojo.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
  dojo.setModulePrefix("dojo", "../javascripts/dojo/src");
  dojo.require("dojo.widget.*");
  dojo.require("dojo.widget.Editor");
  //.. have fun with Dojo
&lt;/script&gt;

This worked for the JavaScript files but not for the CSS that is pulled down afterwards to make the editor look nice:

GET http://localhost:3000/javascripts/dojo/src/widget/Editor.js
GET http://localhost:3000/javascripts/dojo/src/widget/Toolbar.js
GET http://localhost:3000/javascripts/dojo/src/widget/RichText.js
GET http://localhost:3000/javascripts/dojo/src/widget/ColorPalette.js
GET http://localhost:3000/mail/src/widget/templates/HtmlToolbar.css

So the code that includes the CSS does not honor the dojo.setModulePrefix.

After whining at the mailings list I got this hint:

&lt;script type="text/javascript"&gt;
 djConfig = {baseRelativePath: "../javascripts/dojo/"}; 
&lt;/script&gt;

&lt;script src="/javascripts/dojo/dojo.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
  dojo.require("dojo.widget.*");
  dojo.require("dojo.widget.Editor");
  //.. have fun with Dojo
&lt;/script&gt;

Now everything works fine:

GET http://localhost:3000/javascripts/dojo/src/widget/Editor.js
GET http://localhost:3000/javascripts/dojo/src/widget/Toolbar.js
GET http://localhost:3000/javascripts/dojo/src/widget/RichText.js
GET http://localhost:3000/javascripts/dojo/src/widget/ColorPalette.js
GET http://localhost:3000/javascripts/dojo/src/widget/templates/HtmlToolbar.css

Hopefully that will save someone a desperate evening.

Rails 1.1.1 and script.aculo.us 1.6.1 released

Posted by Jonathan

Rails 1.1.1 was just released!

I was waiting with upgrading the FreeBSD port as Rails 1.1 had some issues and 1.1.1 was in the planning. I hopefully have the port updated be the end of the weekend. The upgrade to Rake 0.7 is already submitted.

Further script.aculo.us 1.6.1 was also released some minutes ago. It includes Protoype 1.5.0_rc0 and fixed some ugly IE bugs.

Have fun with all the upgrades.

More effects in prototype.js

Posted by Jonathan

Thomas Fuchs, who is involved in Ruby on Rails and protoype.js, published a demo site with some new effects in prototype.js.
protoype.js is a object-oriented Javascript library for dynamic web applications. This library is responsible for the presentation of the AJAX effects that are supported in Ruby on Rails.

If you do not know his older demos, be sure to check them out.

Fun with JavaScript

Posted by Jonathan

Two links to interesting stuff with JavaScript.

The first one is a Greasemonkey user script that lets you trace XMLHttpRequest queries. This is useful for developing AJAX enabled Websites.
For more fun with AJAX watch out the coming version of Ruby on Rails with many out-of-the-box effects. This relies on the great object-oriented JavaScript library prototype
by Sam Stephenson.

Another thing to check out is GTDTiddlyWiki a Wiki/Blog combination that uses JavaScript to run the whole site. It is just one HTML page that you can download to your computer and use locally without a webserver!