2013-07-24 90 views
10

我處於創建應用程序的早期階段,並且只是放置了一些基本代碼。下面是當前的代碼...在嵌套屬性欄中動態添加字段

應用程序/視圖/卡/ front.html.erb

<%= form_for(front_of_card_path) do |f| %> 
    <%= f.fields_for :competency_templates do |builder| %> 
    <%= render 'add_fields', f: builder %> 
    <% end %> 
    <%= link_to_add_fields "Add New Tag", f, :skill %> 
<% end %> 

路線

controller :cards do 
    get '/front',   action: 'front', as: 'front_of_card' 
    post '/save',    action: 'create', as: 'save_card' 
    get '/my_contact_info', action: 'back', as: 'back_of_card' 
    put '/save',    action: 'update', as: 'save_card' 
    get '/my_card',   action: 'show', as: 'card' 
    end 

控制器

def create 
    @skill= Skill.new(params[:skill]) 
    @tag = Tag.new(params[:tag]) 
    @tag.save 
    @skill.tag_id = @tag.id 
    @skill.save 
    redirect_to front_of_card_path, notice: 'Skill was successfully created.' 
    #get user/session 
    #save skills & tags 
    end 

cards.js。咖啡

jQuery -> 
    $('form').on 'click', '.remove_fields', (event) -> 
    $(this).prev('input[type=hidden]').val('1') 
    $(this).closest('fieldset').hide() 
    event.preventDefault() 

    $('form').on 'click', '.add_fields', (event) -> 
    time = new Date().getTime() 
    regexp = new RegExp($(this).data('id'), 'g') 
    $(this).before($(this).data('fields').replace(regexp, time)) 
    event.preventDefault() 

app_helper

module ApplicationHelper 
    def link_to_add_fields(name, f, association) 
    new_object = f.object.send(association).klass.new 
    id = new_object.object_id 
    fields = f.fields_for(association, new_object, child_index: id) do |builder| 
     render(association.to_s.singularize + "_fields", f: builder) 
    end 
    link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")}) 
    end 
end 

所以現在這段代碼給了我兩個文本字段。一個用於標籤名稱,另一個用於標籤重量,控制器將所有內容插入到數據庫中。我想用一些JavaScript來動態地添加儘可能多的標籤/權重字段。我發現的一切似乎都集中在嵌套屬性上。任何想法讚賞。

更新

增加了更多的代碼來實現這一點。我遇到的問題是第三可變我傳遞這條線......

<%= link_to_add_fields "Add New Tag", f, :skill %> 

它不喜歡「:技能」,但我不知道我應該在這裏傳遞。

+0

如果你只是使用jQuery,則拋出這些領域進入一個div類,當你點擊按鈕時,找到那個元素,a nd複製html,然後使用'after()'添加另一個div與複製的html。 – jeremywoertink

+2

只是想指出非常棒的[Cocoon](https://github.com/nathanvda/cocoon),所有這些都帶來了一些額外的選擇,從這種工作中解脫出來 – Romuloux

回答

20

因此,這裏是我想出了...這裏是我的兩個型號...

class Skill < ActiveRecord::Base 
    belongs_to :tag 
    attr_accessible :tag_id, :weight 
end 

class Tag < ActiveRecord::Base 
    has_many :skills 
    attr_accessible :name 
end 

我打電話從應用程序/視圖/技能/ _form.html.erb和使用部分一個js標籤來添加新的字段。另請注意,我正在重新渲染部分內容,然後將其隱藏在最後一個div標記中。

<div id="skillSet"> 
    <%= render partial: "skills_form" %> 

    </div> 
    <a href="javascript:;" id="addNewTag">Add New Tag</a> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

<div class="hide" id="new_skills_form"> 
    <%= render partial: "skills_form", locals: {skill: false} %> 
</div> 

部分很簡單。所有我在這裏做的是存儲值的數組...

<div class="skillsForm"> 
    <%= label_tag 'tag' %> 
    <%= text_field_tag 'tags[]' %> 
    <%= label_tag 'weight' %> 
    <%= text_field_tag 'weights[]' %> 
</div> 

...這裏是JavaScript ...真正的直線前進,只是說被點擊#addNewTag時,appeand #new_skills_form到#skillSet

$(document).ready(function(){ 
    $("#addNewTag").click(function(){ 
    $("#skillSet").append($("#new_skills_form").html()); 
    }); 
}); 

...終於控制器動作decontructs陣列,並將它們保存...

def create 
    @skill = Skill.new(params[:skill]) 
    tags = params[:tags] 
    weights = params[:weights] 

    tags.each_with_index do |tag, index| 
     tag = Tag.create :name => tag 
     Skill.create :tag_id => tag.id, :weight => weights[index] 
    end 
    end