A functional difference

Posted by Jeff Beeman on Thu, 11/08/2007 - 09:40

I spent two hours trying to solve a niggling Internet Explorer problem the other night. It involves a module I'm writing that needs to fudge the autocomplete path generated Drupal's autocomplete textfield form element. I wanted to base the path in one autocomplete textfield based on the result of another autocomplete textfield (if it had data in it). It took just a bit of experimentation to get this working perfectly in Firefox and I was really pleased with the results and happy that I didn't have to hack anything in core. jQuery's ability to quickly and easily add event listeners and modify attributes was a major lifesaver in this case.

The problem: apparently IE wigs out occasionally with attaching newly defined functions to events via jQuery. Take the following code, for example:


$('#edit-school').focus( function() { Drupal.ideal.setSchoolAutocomplete(); } );

The code above follows examples on the jQuery docs site, other code in Drupal (see autocomplete.js, for example), and is fairly standard code for jQuery stuff. The rest of the code does the following:


Drupal.ideal.setSchoolAutocomplete = function() {
id = Drupal.ideal.getDistrictIdFromString($('#edit-district').val());
if (id) {
path = (id == 0) ? Drupal.settings.ideal.schoolAutocomplete : Drupal.settings.ideal.schoolAutocomplete + "/" + id;
$('#edit-school-autocomplete').val(path);
$('input.form-autocomplete').unbind();
Drupal.autocompleteAutoAttach();
Drupal.ideal.registrationAttach();
}
}

Drupal.ideal.getDistrictIdFromString = function(string) {
match_start = '(DistrictID: ';
match_end = ')';
if (string.indexOf(match_start) >= 0) {
start = string.indexOf(match_start) + match_start.length;
end = string.length - match_end.length;
if (start && end) {
return string.substring(start, end);
}
}
return 0;
}

As you can see, I unbind all events from any autocomplete textfield. This is so I can get my data added into the path and re-run Drupal.autocompleteAutoAttach so that the autocomplete events pay attention to the new path. This worked perfectly fine in Firefox, but caused unresponsive script errors in IE 6 and 7. What was the fix? A simple matter of semantics. Bind directly to the function name, and everything is peachy-keen:


$('#my-textfield').focus( Drupal.ideal.setSchoolAutocomplete );

Maybe this is fixed in newer versions of jQuery (Drupal 5.2 runs on jQuery 1.0.4, I believe), but regardless it's far from something that should be breaking Internet Explorer.

The full, final code (minus settings junk) is:


Drupal.ideal.registrationAttach = function() {
$('#edit-school').focus( Drupal.ideal.setSchoolAutocomplete );
}

Drupal.ideal.setSchoolAutocomplete = function() {
id = Drupal.ideal.getDistrictIdFromString($('#edit-district').val());
if (id) {
path = (id == 0) ? Drupal.settings.ideal.schoolAutocomplete : Drupal.settings.ideal.schoolAutocomplete + "/" + id;
$('#edit-school-autocomplete').val(path);
$('input.form-autocomplete').unbind();
Drupal.autocompleteAutoAttach();
Drupal.ideal.registrationAttach();
}
}

Drupal.ideal.getDistrictIdFromString = function(string) {
match_start = '(DistrictID: ';
match_end = ')';
if (string.indexOf(match_start) >= 0) {
start = string.indexOf(match_start) + match_start.length;
end = string.length - match_end.length;
if (start && end) {
return string.substring(start, end);
}
}
return 0;
}

if (Drupal.jsEnabled) {
$(document).ready(Drupal.ideal.registrationAttach);
}