Tao Te KaChing
Workin' the cash register of the Great Tao

jQuery, Ajax, onload, and Me...


So, lemme describe a little pickle that I am sure is not new in the web development world.


I inherit an ASP.NET MVC web application at work.  That, in itself, is always a problem.  However, the application does the following:

  • Main view is loaded.
  • User makes a selection.
  • A partial view (we’ll call it PV #1) is loaded onto right side via async Ajax call.
  • PV #1 displays existing items previously created by a user.  PV #1 contains two “versions” of said items.  The first is a hidden one clean and pristine copied, pasted, and shown by jQuery when a user adds a new item.  The second is riddled with inline scripts contained in a loop to render those previously created by users.  Said items contain a datepicker control initialized against a textbox.  We’ll refer to the first as the “template” item, and the second the “repeater’d” item.
  • “repeater’d” items all fire the datepicker.
  • “template” copied items do not.

Why does this make one’s head bang on their keyboard?  Because at first Deep Thought by Jack Handey, none of the items should fire their datepickers.  Dynamically rendered elements, besides a few particulars (foreshadow alert), do not fire onload events.  Input textboxes are one of them.  So why did the first set of items’ datepickers work?  And how do we make the added ones work?

Turns out the answer to the first was simple and annoying, ergo making it hard to find when looking at the forest and not the trees.  The partial view was being rendered from the start, and simply replaced when user actions took place.  Then some jQuery $.fn.live events would fire when those items actually did get rendered.  In other words, the scripts to initialize the controls themselves were loaded and had run with the initial rendering of the page, and those scripts contained jQuery live calls which would fire when elements matching their selectors became part of the DOM.

Knowing this made the solution to the second problem easy.  Being lazy, I did not want to rewrite a bunch of code to make things “better”, as that always takes 10x longer and does resolve the problem, usually adds others, and is really only partially “better” if you’re a good programmer and just seems better because it’s your code and you wrote it and you’re an arrogant shitbird.  Rule #71a: always leave as much of the former coder’s code in as possible so you can tell your co-workers how much those coders sucked and what a PITA it is to deal with their shit.

Anyway, the lazy answer to the jQuery copy-of-the-“template” item was to add a hidden image at the bottom of the template and give it an onload event to do the necessary initializations.  One stackoverflow post lists several elements that fire onload events.  I’ve only gotten two to work: iframe and img.  The code for testing that is here (ASP.NET, VS 2008 solution).