jQuery Advice For Dealing With Stupid Internet Explorer

It feels so good getting rid of that many long Javascript lines, sorry, ECMAscript, and playing with some jQuery and DOM. Well, at least until you meet with that browser which ignores so many web standards: Internet Explorer, unfortunately still used by a big bunch of naive users who don't know there are way better options out there.

This week I had to modify a lot of jQuery code to get it working with that horrible browser from Redmond. And the job is even harder without a tool like Firebug. Internet Explorer just spits a line number when there's an error, often without a file name, or just cryptic messages.

I refuse to install any other Microsoft application just to debug their errors, I prefer thinking, changing some code and seeing if line numbers change. It's a very old fashion way of debugging but it works.

One of the problems I found while working with Internet Explorer and jQuery involved using the html() method to change some element's content. I was able to solve this by modifying some parent() or even using remove() and then append() or after() (see jQuery docs). However, I haven't found any logic for most of these issues yet, in some cases html() worked but quite often Internet Explorer died showing a run time error.

Also, while designing a jQuery enabled calendar using an HTML table I realized that correctly using thead and tbody could make a difference. It's better to have a correctly structured table to avoid Internet Explorer complaining.

Making your web application run with Internet Explorer is not an impossible task but takes a good amount of time and can make you think about killing yourself while listening to a Steve Ballmer interview, yeah, that horrible.

I guess that many web developers, like myself, are already thinking on increasing their fees when some job requires dealing with Internet Explorer, not a bad idea, really.

Javascript Expected Identifier Error On Internet Explorer

A really weird thing was happening with some jQuery code, I was getting this error in both Internet Explorer 6 and 7: Expected Identifier.

I googled a little and found this could happen if you included an extra comma in some expressions but that wasn't my case.

Some coffees later I found the offending code was:

var class = $(this).parent().attr('class');

Yep, class seems to be a reserved word in Internet Explorer, thanks again Microsoft for making web developers lifes so difficult.

I just changed the variable name to fix the error, something like this:

var tabClass = $(this).parent().attr('class');

A little later I found another mention of the class problem, hell!, where was this article when I was looking for the fix? It seems you can't set classes with jQuery's attr() method in Internet Explorer either, well, I guess that's why we have addClass() and removeClass().

jCalendar: A jQuery Based Calendar Goes The Drupal Way

While working on a Drupal based project where we needed a date picker for our forms, my good friend, and old drupaler, Gerhard, recommended me taking a look at Ted Serbinski's jCalendar, a jQuery based calendar.

I started hacking a quick version of jcalendar.module using some ideas of the very helpful jscalendar.module, which uses the jsCalendar javascript library, like using a special CSS class called via #attribute in the form element array to convert textfields into jcalendar enabled.

The jcalendar module uses hook_form_alter() to look for textfields with the add-jcalendar class, I had to use something different than jcalendar which is used later on the generated form elements by the jQuery code.

This is a sample of how to enable jcalendar from one of your textfields once you've installed the module:

// Define a range of years to show
$years = array('0' => 0) + drupal_map_assoc(range(2007,2020));

$plot_dates = array(
'2008-11-03',
'2007-04-01',
'2007-06-11',
); // YYYY-MM-DD

$form['firstdate'] = array(
'#type' => 'textfield',
'#title' => 'The first date',
'#default_value' => '2007-09-29',
'#weight' => -20,
'#attributes' => array('class' => 'add-jcalendar'),
'#jcalendar_year_range' => $years,
'#jcalendar_plot_dates' => $plot_dates,
'#description' => t('YYYY-MM-DD'),
);</code>

The #jcalendar_year_range custom property allows you to provide a range of years, look at the associative array $years, to show in the calendar. If the property is not passed jcalendar.module defaults to the current year plus 20.

#jcalendar_plot_dates, which is not working yet, should allow passing an array of dates to the calendar to plot. I'm not sure if this should be the job of the Drupal module or jCalendar's jQuery code.

This first version of jcalendar.module works, it converts your textfield to three select boxes, day, month, year, and a nice table based date picker, easy to theme via CSS, and once you have the right date you can do whatever you want with it. The original textfield is removed later so your form validation and processing functions should consider if jcalendar is enabled (a simple if (module_exists('jcalendar'))) to handle form elements in a different way.

So, what's the catch? Unfortunately, after I finished my tests and added a second date textfield to my form, I needed to choose a start date and an end date, then I realized jcalendar is duplicating its job for each textfield, it seems the jQuery code only supports one jcalendar per web page. I still need to review the comments in Ted's blog and talk to him to confirm this but I thought it would be a good idea posting what I've done so far in case any of you want to play with the code and improve it.

So here it is, download jcalendar.module and let us know if you get a way to work with more than one calendar per page or alternate ways to alter the original forms.