How to de-anonymize your anonymous functions 2010-05-19

First of all, de-anonymized functions are called named functions and they look a lot like “regular” functions (in fact, they are).

Why should I de-anonymize?

For debugging. Instead of having a stack trace filled with ?() (representing an anonymous function), it is nicely printed and easier to follow.

For self-reference. Example, when you want an anonymous function to recall itself recursively, you would have to call arguments.callee. It's odd and it's deprecated anyway (people pointed to me that it's not really deprecated but it throws an error in ECMAScript 5 strict).

Stack trace of anonymous functions…

If you run this in your firebug console (every javascripter should have firebug).

You get a stack trace that looks like this : func() func() func()

… versus stack trace of named functions

You get a stack trace that looks like this : f1() f2() f3()

As you can see, it's a lot easier to debug and to understand who's calling who.

Warning : There's a bug in IE with named functions.

Recursive anonymous function

Let's create a recursive anonymous function that counts to 10.

And let's create it but using a named function.

Once again, the code is much clearer and it's not using a deprecated element.

A note about closures to advanced javascripters

I just wanted to say that in the last example, you could have written this :

As you can see at line 4, I call the count function which is not the name of the function but the variable to which the function is assigned. It works, but it may not be the best thing to do. You can learn more about closure on that previous post and I'll write more about it.


An undo/redo library for your app 2010-04-26

I wrote about undo before and I pushed it farther. What about an undo/redo system? I extended the v.01 of the undo and I now handle undo and redo in the same object.

Annoucing redo in jskata.undo

I made a new version of jskata.undo still hosted on GitHub. If you look closer, it is now part of a library called jskata that is not officially announced. My next post will talk about it in details.

Demo

Take a look at the demo. The javascript of the demo is available here. You can see the complete doc on GitHub.

How does it work?

Execute an action that you can undo/redo

Doing something requires calling execute with 2 functions as parameters : the do and the undo.

Undo and redo the last action

Very easy!

Events and properties

For the moment, jskata.undo has just one event : onChange.

There are 2 properties : canUndo() and canRedo().


Error with hashes in IE but not in Firefox 2010-04-06

There's a common error that happens quite a lot on IE only and never on Firefox. You search it, you check all your variables, you comment your code to the bare minimum but you can never find it.

Stop looking! Here's the answer.

You probably just forgot a comma (,) at the end of a hash. Here's an example :

var val = {
  cat:"Mistigri",
  dog:"Rex",
  butler:"Jeeves", // There's an extra comma
}

You see the extra comma at the string “Jeeves”? This what causes the problem. Firefox handles an extra comma nicely but Internet explorer doesn't. To correct the error, just write :

var val = {
  cat:"Mistigri",
  dog:"Rex",
  butler:"Jeeves" // There's no extra comma
}

JSLint to the rescue

Programmieraffe told me about JSLint. You paste your javascript code and it verifies it for you. Not only for extra-commas but everything else.


How to write a simple undo system for your app 2010-03-29

I really like undos. If I could undo that that last beer… Unfortunately, I can't. But, I can offer undo to users of my application.

When I thought about undo before, I thought about a complicated Rails plugin that would keep an anonymous ID linking to any table in the database with an “action” field that would contain the action to undo. Pretty complicated stuff for something as simple.

The javascript solution

One day while I was writing some javascript, the solution struck me : I could handle this completely with javascript. The basic idea is that whenever an action is completed, I can save its undo function in an array and call it whenever I need it.

Example, if I'm saving a user in a database with Ajax :

  1. I send the data to server to save a new user
  2. The server returns the ID of the new user
  3. I create a function with an ajax request that will send a delete of this user to the server
  4. I add the previous function to a stack of undo functions to be able to call it later

That, when I call that last function, it will undo that user creation without having to keep it in memory server-side.

Introducing jsKata.undo

I wrote a little something called jsKata.undo on GitHub that contains the logic describe earlier. It's quite simple but it may grow over time. It has no requirement, not even jQuery. It's very simple to use.

The complete doc is on GitHub.

1. Adding an action that can you can undo

I'll use the “add a user” example with jQuery.

$.post(
  "http://yoursite.com/users/new", // The url to add a user
  {name:"John Boucher"}, // The name of the user
  function(newUser, textStatus, XMLHttpRequest) { 
    // This is called when the post is over
    var newUserId = newUser.id;

    // We begin by creating a function to delete the user
    var undoNewUser = function() {
      $.post(
        "http://yoursite.com/users/delete", // The url to delete a user
        {id:newUserId} // The ID of the new user to delete
      );
    }

    // We add the undo function to the stack
    jskataUndo.push(undoNewUser);
  }
);

2. Undo the last action you made

jsKata.undo.undo();

3. Events

Each time there's a change, an onChange event is called. To assign yours, simply write :

jsKata.undo.onChange = function() {
  // Show the undo button
   $("#undoButton").show();
}

There's also an onEmpty event that is called when the stack of undoable actions is empty.

jsKata.undo.onEmpty = function() {
  // Hide the undo button
   $("#undoButton").hide();
}

Complete demo

There is a complete demo on GitHub as well as the HTML and Javascript code for it. Take a look!


Two google-like jquery calendars 2010-03-15

Sometimes, it feels to me that javascript was invented for the only purpose of writing calendars to select a date. I wrote one myself (because I had to, not because I wanted to) in a previous job. I use a new calendar that is “better than the other one” on each of my project. It seems like the world will never run out of javascript calendars. In fact, you probably are writing a new one as you read this.

I want to talk about a different kind of calendar. The really hard one to write : calendars for displaying events in jquery.

The pretty jquery-week-calendar

Written by Rob Monie, this is the first one I tried. I was amazed about how easy it was to integrate with the current development of Timmy (you can see an early beta when you're logged here). You can take a look at the demo. Unfortunately, I had unexplicable bugs and I didn't take the time to understand them. Please, don't do like me and participate to the code on GitHub.
  • Looks good
  • Easy to integrate
  • May be buggy when drag-dropping/resizing

The robust fullcalendar

We switched to this calendar, written by Adam Shaw, because it had three different views (month, week, day) and because we had some problem with the other calendar. It doesn't look as good as the week-calendar (demo). You can also participate on GitHub.

  • The default look is OK
  • Harder to work with
  • Display may seem slow (on firefox)
  • More robust than week-calendar

Finally

These guys have made a great job doing something really hard. Just think about two overlapping events or when an event is two minutes long or hundreds of special cases that could happen. Kudos to them for giving their time and talent to us.

A word about git

Our team (me and Frank, the RubyFleebie guy) worked with SVN for a couple of years until Git stole the spotlight. For a couple of months, we worked with it and enjoyed it. Until we had to do “more advanced” things (branching, merging which is pretty basic to my sense) and things got incredibly hard. We switched to Mercurial a couple weeks ago which feels more like the perfect mix between SVN and Git. So if, like us, you feel puzzled by Git, give Mercurial a chance.