Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用Haml和Formtastic动态添加和删除嵌套模型字段_Javascript_Ruby On Rails_Nested Forms_Formtastic - Fatal编程技术网

Javascript 如何使用Haml和Formtastic动态添加和删除嵌套模型字段

Javascript 如何使用Haml和Formtastic动态添加和删除嵌套模型字段,javascript,ruby-on-rails,nested-forms,formtastic,Javascript,Ruby On Rails,Nested Forms,Formtastic,我们都看到了Ryan Bates解释如何使用Javascript在父对象表单中动态添加或删除嵌套对象的精彩故事 有人知道这些方法需要如何修改才能与Haml Formtastic合作吗 为了增加一些背景,这里是我目前面临的问题的简化版本: #教师表单(具有嵌套主题表单)[来自我的申请] - semantic_form_for(@teacher) do |form| - form.inputs do = form.input :first_name = form.input :s

我们都看到了Ryan Bates解释如何使用Javascript在父对象表单中动态添加或删除嵌套对象的精彩故事

有人知道这些方法需要如何修改才能与Haml Formtastic合作吗

为了增加一些背景,这里是我目前面临的问题的简化版本:

#教师表单(具有嵌套主题表单)[来自我的申请]

- semantic_form_for(@teacher) do |form|
  - form.inputs do
    = form.input :first_name
    = form.input :surname
    = form.input :city
    = render 'subject_fields', :form => form 
    = link_to_add_fields "Add Subject", form, :subjects   
- form.fields_for :subjects do |ff| 
  #subject_field
    = ff.input :name
    = ff.input :exam
    = ff.input :level
    = ff.hidden_field :_destroy
    = link_to_remove_fields "Remove Subject", ff 
#个人科目表部分[来自我的申请]

- semantic_form_for(@teacher) do |form|
  - form.inputs do
    = form.input :first_name
    = form.input :surname
    = form.input :city
    = render 'subject_fields', :form => form 
    = link_to_add_fields "Add Subject", form, :subjects   
- form.fields_for :subjects do |ff| 
  #subject_field
    = ff.input :name
    = ff.input :exam
    = ff.input :level
    = ff.hidden_field :_destroy
    = link_to_remove_fields "Remove Subject", ff 
#应用程序助手(直接来自Railscasts)

#Application.js(直接来自Railscasts)

实现的问题似乎在于javascript方法——Formtastic表单的DOM树与常规rails表单大不相同

我已经在网上看到过好几次这个问题,但还没有找到答案——现在你知道,不仅仅是我会感谢你的帮助


杰克

你走对了方向:

…Formtastic表单的DOM树 与常规轨道有很大不同 形式

为了将Ryan的示例改编为formtastic,需要提醒的是,用于helper的
semantic\u字段与用于
helper的
semantic\u表单类似,后者以列表形式输出输入

要使内容尽可能接近Railscast代码,您需要:

  • 将嵌套字段的集合封装在包装器中(我使用带有
    subjects
    CSS ID的div)
  • 将嵌套字段封装在ul/ol包装器中(我应用了
    嵌套字段
    CSS类)
以下是您的文件的内容

教师表单(带嵌套主题字段):

主题字段部分(用于嵌套主题):

ApplicationHelper:

def link_to_remove_fields(name, f)
  f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end

def link_to_add_fields(name, f, association)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
    render(association.to_s.singularize + "_fields", :f => builder)
  end
  link_to_function(name, h("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"))
end
Application.js:

function remove_fields(link) {
  $(link).previous("input[type=hidden]").value = "1";
  $(link).up(".nested-fields").hide();
}

function add_fields(link, association, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + association, "g")
  $(link).up().insert({
    before: content.replace(regexp, new_id)
  });
}
使用以下gems:

  • formtastic(0.9.10)
  • haml(3.0.2)
  • 小黄瓜(1.0.26)
  • 轨道(2.3.5)

    • jQuery的application.js:

      function remove_fields(link) {
        $(link).prev("input[type=hidden]").val("1");
        $(link).parent(".nested-fields").hide();
      }
      
      function add_fields(link, association, content) {
        var new_id = new Date().getTime();
        var regexp = new RegExp("new_" + association, "g")
        $(link).parent().before(content.replace(regexp, new_id));
      }
      

      在Rails 3中,不需要在助手中使用h()函数。只要省略就行了。

      多年来,我一直在断断续续地思考这个问题,今天我想出了一些我引以为豪的东西——优雅、不引人注目,而且你只能完成两三行(非常长的)代码

      ParentFoo有许多嵌套条,带有适当的接受嵌套参数和所有这些好东西。将嵌套的_栏的一组字段呈现到链接上的“数据添加嵌套”属性中,使用:child_索引设置一个可以稍后替换的字符串。在第二个参数data add nested replace中传递该字符串

      父\u foos/\u form.html.haml

      - semantic_form_for @parent_foo do |f|
        -# render existing records
        - f.semantic_fields_for :nested_bars do |i|
          = render 'nested_bar_fields', :f => i
      
        # magic!
        - reuse_fields = f.semantic_fields_for :nested_bars, @parent_foo.nested_bars.build, :child_index => 'new_nested_bar_fields' do |n| render('nested_bar_fields', :f => n) end
        = link_to 'Add nested bar', '#', 'data-add-nested' => reuse_fields, 'data-add-nested-replace' => 'new_nested_bar_fields'
      
      - f.inputs do
        = f.input :name
        = f.input :_delete, :as => :boolean
      
      嵌套的部分字段没有什么特别之处

      父\u foos/\u嵌套\u bar\u fields.html.haml

      - semantic_form_for @parent_foo do |f|
        -# render existing records
        - f.semantic_fields_for :nested_bars do |i|
          = render 'nested_bar_fields', :f => i
      
        # magic!
        - reuse_fields = f.semantic_fields_for :nested_bars, @parent_foo.nested_bars.build, :child_index => 'new_nested_bar_fields' do |n| render('nested_bar_fields', :f => n) end
        = link_to 'Add nested bar', '#', 'data-add-nested' => reuse_fields, 'data-add-nested-replace' => 'new_nested_bar_fields'
      
      - f.inputs do
        = f.input :name
        = f.input :_delete, :as => :boolean
      
      在jQuery中,将元素的点击与数据添加嵌套字段绑定(我在这里使用了live(),这样ajax加载的表单就可以工作了)以将字段插入DOM,并用新ID替换字符串。这里我做的是在链接()之前插入新字段的简单操作,但是您也可以在链接上提供一个add-nested-replace-target属性,说明您希望新字段在DOM中的什么位置结束

      application.js

      $('a[data-add-nested]').live('click', function(){
        var regexp = new RegExp($(this).data('add-nested-replace'), "g")
        $($(this).data('add-nested').replace(regexp, (new Date).getTime())).insertBefore($(this))
      })
      
      当然,你可以把它放在助手里;我在这里直接在视图中介绍它,这样原则就很清楚了,而不必在元编程中乱搞。如果您担心名称冲突,可以在该助手中生成一个唯一的ID,并在嵌套替换中传递它

      对删除行为的想象留给读者作为练习


      (为Rails 2显示,因为这是我今天正在工作的站点-在Rails 3中几乎相同)

      您可以发布主题的
      字段的HTML输出吗?
      ?感谢您的解决方案--因此主题字段与按钮一样显示,但当我单击任一链接时,我将滚动到屏幕顶部,没有任何操作(我已经打开了js默认值,以防您怀疑)。我尝试了Steve的解决方案,删除链接起作用,但不幸的是添加按钮不起作用。可能我的标记有点不同——使用Rails 3和最新的Formtastic。有什么想法吗?我只使用上面列出的gems尝试了此设置。而且,听起来你并没有完全按照我的示例进行设置,所以你可能会这么做让您的表单结构不同。我建议您在继续删除字段之前,首先使用指向添加字段和添加字段帮助器的链接。谢谢--通过此操作,“删除”按钮可以正常工作,但“添加”按钮不能正常工作……使用Rails3和最新的Formtastic。注意:在Rails 3中,由于html转义,这可能没有那么容易:(使用escape\u once似乎有效,就像在这个半相关的示例中插入一个字段:-new\u field=escape\u once f.input(:related\u thing)=link_to‘Add other’、‘#’、‘data insert’=>new_field我进一步开发了这项技术,以便在没有模型的情况下使用-我遇到过一个客户希望指定要在报告中显示的字段集的情况。此版本使用块而不是单独的字段模板,并使用“通用模型”生成可替换的参数仪表。要点如下: