Hey, this is the first time I've actually finished writing up a question without SO giving me the answer in the process. :)
I've got a nested form (along the lines of Ryan Bates' Railscast tutorial on the topic) which allows users to dynamically add additional fields for adding/removing nested models using Prototype-based javascript. The extra fields can be added and removed and work just fine to create new models.
The problem is, one of the fields uses an Ajax.Autocompleter; the code in the page when the partial is rendered looks like this:
<script type="text/javascript">
//<![CDATA[
new Ajax.Autocompleter(...various args...);
//]]>
</script>
The autocompleter works fine if the partial is rendered to begin with (eg, if the form starts out with one instance of the partial, or when editing existing nested models). However, it doesn't work in the dynamically added form fields.
I have tried using both insert() and just setting the innerHTML of an empty div to insert the HTML partial. With insert(), the Autocompleter code is evaluated and everything in the <script>
tag vanishes (as I understand is expected), but the autocomplete does not work. With setting the innerHTML, the script appears exactly as it does in the pre-rendered partial, but the autocompleter still doesn't get invoked.
I suspect that this has something to do with how the evalScripts works, and I've found some documentation on the subject, but I'm having a hard time working out how to apply it to the Autocompleter declaration.
Any advice hugely appreciated!
ETA: adding the javascript used to add in the new section:
function add_section(link, nested_model_name, content) {
// get the right new_id which should be in a div with class "last_id" at the bottom of
// the nearest section
var last_id = parseInt($(link).up().previous('.last_id').innerHTML);
var new_id = last_id + 1;
var regexp = new RegExp("new_" + nested_model_name, "g");
content = content.replace(regexp, new_id)
// this is the line that actually inserts the content into the page
$(link).up().insert({before: content});
}
Debugging with firebug shows that the content is correct (ie has the normally-working autocomplete code in it) before it is inserted.