Prototype Ajax.Autocompleter in dynamically added HTML does not work
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 rende开发者_StackOverflowred 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.
I know this is an older question but I had the same problem recently.
I'm not sure what version of auto_complete you are using? I was using the rails/auto_autocomplete from git.
In that plugin the javascript code was like this
lib/auto_complete_macros_helper.rb
def auto_complete_field(field_id, options = {})
function = "var #{field_id}_auto_completer = new Ajax.Autocompleter("
I was having the same problem. The input fields would be visible but the autocomplete functionality didn't work. It turned out that the var keyword makes the varaible local scope.
That meant anything evaluated in evalscripts was at a different scope than the original DOM object.
My patch was to just remove the var keyword.
lib/auto_complete_macros_helper.rb
def auto_complete_field(field_id, options = {})
function = "#{field_id}_auto_completer = new Ajax.Autocompleter("
I dont know enough about your setup to say for sure whats wrong, but I bet it has something to do with the scope of evalscripts as well.
is your JS to register the autocompleter within your script-tag you're loading via ajax.updater? if so, you have to add the evalScript
parameter to have it eval'ed: new Ajax.Updater('target',url,{method:'get', evalScripts:true});
Okay, so as an experiment I tried just changing my Autocompleter helper code as follows and now it works fine:
FROM:
javascript_tag("new Ajax.Autocompleter(...
TO:
javascript_tag("var autocomplete_for_#{fieldname} = new Ajax.Autocompleter(...
This is in in a Rails helper, but unless I misunderstand, I think the point is that by declaring a variable, it's causing prototype to actually evaluate the new call as it inserts the code.
(Any more/better insight into why this works and the other doesn't would still be v welcome though, since right now this was mostly blind luck.)
精彩评论