views:

76

answers:

2

For the last hour and a half I've trace Javascript calls in a Magento shop I'm building, because I have the strange effect that, when checking out, I can not leave page 2 (shipping address) of the onepage checkout, unless I switch from "send to this address" to "send to another address".

I've traced it down to this piece of javascript code in form.js, residing in Regionupdater.setMarkDisplay (line 254 ff.)

Since I'm a jquery man myself I'm not really in the loop with prototype functionality but I'm assuming .up and .down are practically what jquery does with .parent(s) and .children()?!

elem = $(elem);
var labelElement = elem.up(0).down('label > span.required') ||
                   elem.up(1).down('label > span.required') ||
                   elem.up(0).down('label.required > em') ||
                   elem.up(1).down('label.required > em'); 

elem is the region select field in the form. I'm assuming it's trying to find the label for this field (which exists). But both the "elem.up(0)" fragments apparently throw an

[Exception... "An invalid or illegal string was specified" code: "12" nsresult: "0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)"]

I've no idea what triggers this.

+1  A: 

You're basically right about what up and down do. That line of code is picking the first matching element:

elem = $(elem);
var labelElement = elem.up(0).down('label > span.required') || // Up to parent, down to first span.required inside a label
                   elem.up(1).down('label > span.required') || // Up to grandparent, down to first span.required inside a label
                   elem.up(0).down('label.required > em') ||   // up to parent, down to first em inside a label.required
                   elem.up(1).down('label.required > em');     // up to grandparent, down to em within a label.required

...where in each case it stops with the first one it finds.

The error looks like it's being thrown from a selector engine or something being passed a selector it doesn't understand. None of those selectors is particularly cutting-edge, so that's a bit strange. Are you using Prototype 1.7 RC2? Because the current released Prototype still only uses its own built-in selector engine (whereas 1.7 adds pluggable ones).

Ah! That's it -- look at the ids of the elements in that area. Do any of them have spaces or '#' or ':' in them, that sort of thing? I seem to recall a bug in the Prototype selector engine where it assumes fairly boring IDs... (Why are IDs relevant? Under the covers, the selector engine may use them when processing descendant or child selectors -- for instance, when processing down calls...)

Update This (fixed) bug may relate to this, if you're using an older version of Prototype you may still be running into it. Definitely worth looking at the IDs.

T.J. Crowder
Yeah, the IDs of the elements are all in the style of "shipping:region" and "billing:region", so apparently it breaks down there - which is kinda confusing, as everything else works. Magento uses Prototype 1.6.0.3 - when I replace it with 1.6.1 the whole thing breaks down completely and nothing at all works. Version 1.6.0.4b (or any version 1.6.0.4), as described in the fixed bug report, is nowhere to be found, not even in the git repository.
Sorcy
@Sorcy: There was never a released version 1.6.0.4. There was going to be, but the changes ended up justifying them calling it 1.6.1 instead. I'm surprised that things stop working if you move to 1.6.1. You might try throwing [deprecated.js](http://github.com/sstephenson/prototype/blob/master/src/deprecated.js) into the mix with 1.6.1, perhaps Magento is relying on a deprecated API call. I've never actually used deprecated.js so I can't comment on whether that's likely to work, but if it's easy to test... If you're stuck with 1.6.0.3, unfortunately those IDs will have to change. Good luck.
T.J. Crowder
@Sorcy: Or you could try patching your 1.6.0.3 file with just that one fix, the one that escapes the colons.
T.J. Crowder
A: 

I have the same error, on IE8, but in my case it's not because of unescaped colon. I have the error because I'm using a custom theme that modified the DOM so elem.up(0) is pointing to other element. You should look at skin/frontend/your_template/js/opcheckout.js at lines 420 and 428 functions setSameAsBilling and syncWithBilling or change your template file - shipping.phtml. Also on default skin this error does not apear.

Emanuel O.