Rails 3:如何使用Jquery添加/删除一组字段

Rails 3: How to add/remove a group of fields using Jquery?

本文关键字:字段 一组 删除 何使用 添加 Jquery Rails      更新时间:2023-09-26

我正试图弄清楚如何使用Jquery在Rails3应用程序中添加和删除一组字段。我得到了使用纯html的jquery脚本,您可以在这里看到:http://jsfiddle.net/beehive/ABvFH/1/

然而,我不知道如何将其翻译成Rails3。更具体地说,在application.js文件中,我应该用什么来替换"formfield"才能正常工作?

application.js

$(document).ready(function() {
    $(function() {
        var x = $('#uploadform');
        var i = $('#uploadform ul').size() + 1;
        $('#addmore').live('click', function() {
            if ($(".item", x).length < 9) {
                $('<ul class="item" class="field">formfield ' + i + ' <a href="#" id="remfields">Remove</a></p>').appendTo(x);
                i++;
            }
            return false;
        });
        $('#remfields').live('click', function() {
            if (i > 2) {
                $(this).parents('ul').remove();
                i--;
            }
            return false;
        });
    });​

});

form.html.erb

<%= form_for(@upload) do |f| %>
  <% if @upload.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@upload.errors.count, "error") %> prohibited this upload from being saved:</h2>
      <ul>
      <% @upload.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <h2><a href="#" id="addmore">Add More Fields</a></h2>
  <div id="uploadform">
    <ul class="field">
      <li>
        <%= f.label :title %><br />
        <%= f.text_field :title %>
      </li>
      <li>
        <%= f.label :genre %><br />
        <%= f.collection_select :genre, Upload::GENRES, :to_s, :to_s, :include_blank => true %>
      </li>
      <li>
        <%= f.label :category %><br />
        <%= f.collection_select :category, Upload::CATEGORIES, :to_s, :to_s, :include_blank => true %>
      </li>
      <li>
        <%= f.label :age %><br />
        <%= f.collection_select :age, Upload::AGES, :to_s, :to_s, :include_blank => true %>
      </li>
    </ul>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我所要做的就是注释$(function() {

$(document).ready(function() {
    //$(function() {
        var x = $('#uploadform');
        var i = $('#uploadform ul').size() + 1;
        $('#addmore').live('click', function() {
            if ($(".item", x).length < 9) {
                $('<ul class="item" class="field">formfield ' + i + ' <a href="#" id="remfields">Remove</a></p>').appendTo(x);
                i++;
            }
            return false;
        });
        $('#remfields').live('click', function() {
            if (i > 2) {
                $(this).parents('ul').remove();
                i--;
            }
            return false;
        });
    //});​

});

编辑:

插入它们是什么意思?

要访问元素,您可以使用循环浏览它们

    $('#uploadform > ul').each(function(index) {
        alert(index + ': ' + $(this).text());
    });

注意您生成的HTML。您正在为每个li(列表项)创建ul(无序列表)。您可能希望将其修复为仅附加列表项。

我想您希望允许用户在提交表单之前添加许多上传内容。在这种情况下,我使用rails嵌套属性。

下面是一个例子订单有许多照片

订单型号:

class Order < ActiveRecord::Base
  has_many :photos, :dependent=>:destroy, :inverse_of=>:order
  accepts_nested_attributes_for :photos, :allow_destroy=>true,:reject_if=> :all_blank
end

照片型号:

class Photo < ActiveRecord::Base
  has_attached_file :photo
  belongs_to :order
end

订单表单视图:

<%= form_for @order, :html => {:autocomplete => :off, :multipart => true} do |f| %>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
    <h3>Order photos</h3>
        <%= f.fields_for :photos do |photo| %>
        <%= render :partial=>'photo_form', :object=> photo, :as => :f %>
        <% end %>
    <%= link_to 'Add photo', new_photo_path, :remote=>true, :id=>'add_photo'  %>
    <%= f.submit%>
<% end %>

photo_form部分:

<fieldset class="photo" data-status="<%= f.object.persisted? ? 'db':'new' %>">
   <% if f.object.persisted? %>
      <div class="field">
    <label>Photo:</label><br />
    <%= link_to f.object.photo.url, :target=>'_blank' do %><%= image_tag f.object.photo.url(:mini) %><% end %>
      </div>
   <% else %>
      <%= f.label :photo
      <%= f.file_field :photo %>
      <%= f.text_field :description %>
  <%= f.check_box :_destroy, :class=>'delete' %>
</fieldset>

现在,在您的控制器中,您需要3个操作来编辑照片顺序:编辑、更新、添加照片(用户单击添加照片链接时的ajax操作):

class OrdersController < ApplicationController
  def edit
    @order = Order.find(params[:id])
  end
  # Action responsible for updating existing order record
  def update
    @order = Order.find(params[:id])
    if @order.update_attributes(params[:order])
       redirect_to @order, :notice=>'Order updated'
    else
       render :action => "edit" #save error, display order form with errors
    end
  end
  # Action responsible for creating nested form for order photo
  def new_photo
    #nothing just renders 'new_photo.js.erb'
  end
end

new_photo.js.erb:

$object=$("<%= escape_javascript( render(:partial => "photo_form", :locals=>{
    :f=>FormBuilder.new("order[photos_attributes][#{rand(400000)}]",Photo.new(),self,{},proc {})
}) ) %>").hide();  //generates new photo view
$object.insertBefore("a#add_photo").slideDown(500); 

这只是一个例子,但在应用程序中采用它应该不会有问题。