代码之家  ›  专栏  ›  技术社区  ›  GiH

如何使用jquery和rails 3通过嵌套表单发送动态参数?

  •  1
  • GiH  · 技术社区  · 11 年前

    我是rails的新手,我正在尝试使用jquery实现我自己的动态字段。我已经将字段添加到表单中,但我的参数没有按照我希望的方式发送。这是我的jQuery:

    $('form').on('click', '#add_ingredient', function(){
        count = 1;
        field = $('#ingredient_list li').first()
            .clone()
                .find('input')
                    .val('')
                        .end()
                            .find('input')
                                .prop({id: 'entry_ingredients_attributes_' + count + '_name', name: 'entry[ingredients_attributes][' + count +'][name]'  })
                                    .end();
        $('#ingredient_list').append(field);
        count += 1;
    })
    

    这允许我添加多个列表项,它们的id和名称会增加,因此它们是唯一的。

    我已经正确设置了模型以使用accepts_nested_attributes_for,我正在创建一个烘焙日记,其中包含模型Entry、Ingredient和关联EntryIngredient。我的问题如下:

    当我提交表单时,我只发送其中一个成分,即使我添加了多个字段,也只有最后一个被提交。这是当我提交一个包含超过1种成分的表单时,我的参数的输出:

    "ingredients_attributes"=>{"0"=>{"name"=>"Flour", "_destroy"=>"false"}, "1"=>{"name"=>""}}}}
    

    这也是我的表格,以防您有兴趣了解它是如何创建的:

      <div id="ingredients">
          <%= f.fields_for :ingredients, @entry.ingredients.build do |builder| %>
          <%= render 'ingredient_fields', :f => builder %>
          <% end %>
      </div>
      <div id='add_ingredient'>Add Ingredient</div>
      <div class="actions">
        <%= f.submit %>
    
    #_ingredient_fields
    <ul id="ingredient_list">
        <li>
          <%= f.label :name %>
          <%= f.text_field :name %>
          <%= f.hidden_field :_destroy %>
          <%= link_to "Remove", "#", :class => "remove_fields" %>
        </li>
    </ul>
    

    有人能给我指正确的方向吗?


    解决方案

    根据Zaid Crouch在下面的回答中的建议,事实证明我的选择者没有做正确的事情。我的JS现在是这样的:

    $('form').on('click', '#add_ingredient', function(){
        count = $('#ingredient_list li').length;
        field = $('#ingredient_list li').first()
            .clone()
                .find('input')
                    .val('')
                        .end()
                            .find('input :first')
                                .prop({id: 'entry_ingredients_attributes_' + count + '_name', name: 'entry[ingredients_attributes][' + count +'][name]'  })
                                    .end()
                                        .find('input :last')
                                            .prop({id: 'entry_ingredients_attributes_' + count + '__destroy', name: 'entry[ingredients_attributes][' + count +'][_destroy]', value: 'false'  })
                                                .end();
        $('#ingredient_list').append(field);
    })
    

    如果有人能推荐一种更好的方法来选择我正在更改属性的元素,我将非常感谢您的反馈。

    1 回复  |  直到 11 年前
        1
  •  3
  •   zkcro    11 年前

    如果您只得到提交的最后一个值,那么这可能是一个很好的提示,表明您有重复的输入 names 。您应该能够通过检查.js添加的html(使用firebug或webkit检查器)来验证是否发生了这种情况。

    查看您的函数,您正在初始化 count 函数中的变量;一旦函数返回,它就超出了作用域,因此每次调用函数时,它都会使用 count = 1 。您应该能够通过更改来解决此问题

    count = 1;
    

    count = $('#ingredient_list li').length;
    

    (您也可以去掉函数末尾的增量,因为它什么都不做)。

    您还需要确保更新 _destroy 隐藏字段也是。