form.element.length returns object? Wow!

20 Jul 2009
Posted by doq

Recently I was constructing Drupal 6 web-site using Hierarchical Select and Ubercart.

New vocabulary with some terms was added for product node type. Hierarchical select was configured to render it.

Then go try creating new product at node/add/product page. Select some term from vocabulary. Works fine in Firefox but JavaScript alert is shown in IE6/7:

Received an invalid response from the server.

Let's discuss what's the problem is.

What's the problem

Whenever you change term in select box - Hierarchical Select sends AJAX request to get children of this term to render the second-level select box. This AJAX request includes form data array that is constructed using jQuery's formToArray() method:

Drupal.HierarchicalSelect.update = function(hsid, updateType, settings) {
  var post = $('form:has(#hierarchical-select-' + hsid +'-wrapper)', Drupal.HierarchicalSelect.context).formToArray();

Ubercart is adding new form item with name length to the node form at node/add/product page. This makes IE crazy and the following code from formToArray() implementation (hierarchical_select_formtoarray.js) produces an error:

  1. var form = this[0];
  2. var els = semantic ? form.getElementsByTagName('*') : form.elements;
  3. if (!els) return a;
  4. for(var i=0, max=els.length; i < max; i++) {
  5. var el = els[i];
  6. var n = el.name;
  7. if (!n) continue;

Pay attention that els.length will be an Object, not integer.

How to fix?

Never use length as the name of form item.
Or use this patch. It should fix the problem with IE. The max variable was removed from the above code. We then loop from zero to infinite until no form item is found:

  1. var form = this[0];
  2. var els = semantic ? form.getElementsByTagName('*') : form.elements;
  3. if (!els) return a;
  4. // We don't use form.elements.length here because IE6/7 fails
  5. // when form item with name "length" exists.
  6. for (var i=0; ; i++) {
  7. if (typeof(els[i]) == 'undefined') {
  8. break;
  9. }
  10. var el = els[i];
  11. var n = el.name;
  12. if (!n) continue;

This formToArray() function is also implemented in jQuery Form plugin (which is also part of Drupal core). It might worth fixing it there also.

AttachmentSize
Hierarchical Select IE 6/7 fix patch1.14 KB
Tags:  | 

Comments

Wouldn't have guessed ))

Wouldn't have guessed )) Thanks a lot!

Avis Martin (not verified) | Aug 26th, 2009 at 3:14 am

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

 
 
 
If you have found mistakes in the text then please select it and press Ctrl-Enter to send report to the site administrator.