动态添加HTML中的原型Ajax.Autocompleter不起作用

时间:2010-10-26 04:49:20

标签: javascript ruby-on-rails prototype autocomplete nested-forms

嘿,这是我第一次真正写完一个没有SO的问题,在这个过程中给出了答案。 :)

我有一个嵌套的表单(沿着Ryan Bates关于该主题的Railscast教程),允许用户使用基于Prototype的javascript动态添加其他字段以添加/删除嵌套模型。可以添加和删除额外的字段,并且可以很好地创建新模型。

问题是,其中一个字段使用Ajax.Autocompleter;渲染部分时页面中的代码如下所示:

<script type="text/javascript">
//<![CDATA[
new Ajax.Autocompleter(...various args...);
//]]>
</script>

如果部分呈现为开始,则自动完成器工作正常(例如,如果表单以部分实例开始,或者编辑现有嵌套模型)。但是,它在动态添加的表单字段中不起作用。

我尝试过使用insert()并设置空div的innerHTML来插入HTML部分。使用insert(),会对自动填充程序代码进行评估,<script>标记中的所有内容都会消失(正如我所理解的那样),但自动完成功能不起作用。通过设置innerHTML,脚本的显示方式与预呈现的部分完全相同,但自动完成程序仍然无法调用。

我怀疑这与evalScripts的工作原理有关,我发现some documentation on the subject,但我很难弄清楚如何将它应用于Autocompleter声明。

非常感谢任何建议!

ETA :在新版块中添加用于添加的javascript:

  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});
  }

使用firebug进行调试显示内容在插入之前是正确的(即其中包含正常工作的自动完成代码)。

3 个答案:

答案 0 :(得分:1)

我知道这是一个较旧的问题,但我最近遇到了同样的问题。

我不确定您使用的是哪个版本的auto_complete?我正在使用git中的rails / auto_autocomplete。

在该插件中,javascript代码就像这样

lib/auto_complete_macros_helper.rb

def auto_complete_field(field_id, options = {})
    function =  "var #{field_id}_auto_completer = new Ajax.Autocompleter("

我遇到了同样的问题。输入字段将可见,但自动完成功能不起作用。事实证明,var关键字构成了可变局部范围。

这意味着在evalscripts中评估的任何内容都与原始DOM对象的范围不同。

我的补丁只是删除了var关键字。

lib/auto_complete_macros_helper.rb

def auto_complete_field(field_id, options = {})
    function =  "#{field_id}_auto_completer = new Ajax.Autocompleter("

我对你的设置知之甚少,但肯定说错了,但我敢打赌它也与evalscripts的范围有关。

答案 1 :(得分:0)

是你的JS在你通过ajax.updater加载的脚本标签中注册自动完成器吗?如果是这样,您必须添加evalScript参数才能对其进行评估:new Ajax.Updater('target',url,{method:'get', evalScripts:true});

答案 2 :(得分:0)

好的,作为一个实验,我尝试按照以下方式更改我的Autocompleter帮助程序代码,现在它可以正常工作:

FROM:

javascript_tag("new Ajax.Autocompleter(...

TO:

javascript_tag("var autocomplete_for_#{fieldname} = new Ajax.Autocompleter(...

这是在Rails助手中,但除非我误解,我认为重点是通过声明一个变量,它会导致原型在插入代码时实际评估新的调用。

(更多/更好地了解为什么这种方法有效,而另一方则不会受到欢迎,因为现在这主要是盲目运气。)