[ 
http://issues.apache.org/jira/browse/COCOON-1738?page=comments#action_12363259 
] 

Fabrizio Sitzia commented on COCOON-1738:
-----------------------------------------

Discussion
==========

Note that any 'double-listbox'-styled fields, which are rendered when the form 
is initially loaded (pre-initialised repeater rows), will work properly until 
after an Ajax round-trip to the server has occured!

That's one of the reasons you don't notice the problem right away! I didn't 
notice that problem when I ajax'ified some lengthy forms while migrating one of 
our webapps from Cocoon 2.1.7 to 2.1.8! But the users of our webapp did :-/

I could isolate two issues for the double-listbox problem:


Issue 1 - global var scope:
---------------------------

The variable containing the double-listbox 'OptionTransfer' object is 
initialised by a bit of inline Javascript code, which is generated by 
'forms-advanced-field-styling.xsl'.

This code will be executed by 'cocoon-ajax.js', when adding a row to the 
repeater for example.

Unfortunately, variables declared in the eval statement will not be bound to 
the global (browser window) scope. After the eval, the variable goes out of 
scope, causing the "optxxxxx is not defined" Javascript error in Cocoon 2.1.8

(Note that this issue appears to have been partially (?) solved in the 
BRANCH_2_1_X branch: Firefox & Safari behave OK, but the issue still exists for 
IE)


Issue 2 - onload handlers:
--------------------------

The 'OptionTransfer' object has an init() method that is meant to be invoked by 
the page's onload event.
The forms_createOptionTransfer method in 'form-lib.js' correctly adds an onload 
handler for the OptionTransfer object.
 
But unfortunately, when a partial page update is performed by Ajax, the page is 
not going to trigger an onload event.
That leaves the 'OptionTransfer' object only partially initialised, hence the 
"from.options has no properties" error message.



The dirty fix
=============

I've implemented a quick and dirty fix for Cocoon 2.1.8 (refer to the 3 
included svn diffs)

A proper fix should provide a robust solution to the global scope issue (mine 
are ad-hoc fixes), and a generic mechanism for initializing stuff that is 
initialized by the page's onload handler in a non-ajax scenario.

A few remarks about the diffs:

- In the importNode() method of cocoon-ajax.js, I've replaced eval with a 
setTimeout invocation: setTimeout runs the scripts in the browser window's 
scope, thus solving the global var scope issue for DOM-compliant browsers 
(tested with Firefox/Windows, Firefox/OSX and Safari/OSX)
Due to one of its zillion bugs, Internet Explorer of course requires a 
different fix.

- Solving the global var issue for Internet Explorer required turning the 'var 
optxxxx =' variable initialisation into 'this.opt =' (in 
'forms-advanced-field-styling.xsl')
Don't ask why! (I stumbled upon that tip by chance, in an article about 
closures in JScript)

- The onload handler execution issue is, ehr, 'solved', by running the 
double-listbox onload handler immediately after the 'this.opt =' 
initialisation. By that time, the left and right selection boxes are hopefully 
available in the DOM - and by this time, you will agree that this fix is indeed 
dirty ;-)

- In 'forms-lib.js', I've commented out the line that pushes the double-listbox 
onload handler to the form's onload handlers array. Otherwise, that handler 
would be executed twice for pre-initialised repeater rows!

> double-listbox problem in repeaters
> -----------------------------------
>
>          Key: COCOON-1738
>          URL: http://issues.apache.org/jira/browse/COCOON-1738
>      Project: Cocoon
>         Type: Bug
>   Components: Blocks: Ajax, Blocks: Forms
>     Versions: 2.1.8, 2.1.9-dev (current SVN)
>     Reporter: Fabrizio Sitzia
>  Attachments: cocoon-ajax.js.diff, forms-advanced-field-styling.xsl.diff, 
> forms-lib.js.diff
>
> Rendering a multivaluefield using the 'double-listbox' styling fails, when 
> that multivaluefield is contained in a repeater, and Ajax is enabled for the 
> form:
> The 'double-listbox'-styled fields in the repeater stop working as soon as 
> some action, involving a round-trip to the server and a partial re-rendering 
> of the repeater, is being performed (for example adding or deleting a 
> repeater row, validation error on submit...)
> After such a round-trip, a click on any of the double-listbox's UI elements 
> (double-click on an item, click on an option-transfer button) will yield a 
> Javascript error ("optxxxxx is not defined" on Cocoon 2.1.8, and 
> "from.options has no properties" on the current BRANCH_2_1_X)
> The multivaluefield's values will not be submitted correctly afterwards.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira