首先說一下需求吧:
聯(lián)系人信息的增刪改查,每個聯(lián)系人都會可能有多個電話,在不用ajax的情況下去實現(xiàn)這種信息在一個頁面上的操作
通過嵌套屬性(nested attribute),你可以通過parent來保存與其相關(guān)聯(lián)的屬性。默認情況下,嵌套屬性是關(guān)閉的,你可以開啟accepts_nested_attributes_for這個類方法,就在該model上生成并綁定一個屬性 。例如,為你的model增加兩個新方法:
class Bid::Contact < ActiveRecord::Base
??has_many :telephones
??accepts_nested_attributes_for :telephones, allow_destroy: true
end
由于我們要在聯(lián)系人剛新建的時候就需要給一個電話和郵箱的輸入框,所以我們要在controller頁面做一些初始化:
@bid_contact = Bid::Contact.new
@bid_contact.telephones.build
在view頁面我們最好單獨給電話信息的錄入框做一個頁面:(_firm_field.html.haml)
%table.col-md-8.col-xs-8
??%thead
????%tr
??????%td=?f.input?:country_num,?as:?:string,?wrapper:?:table_fields_for,?placeholder:'國家代碼',?readonly:?true
??????%td=?f.input?:phone_num,?wrapper:?:table_fields_for,?placeholder:'電話號碼'
??????%td=?f.input?:ext,?wrapper:?:table_fields_for,?placeholder:'分機號'
??????%td=?f.input?:note,?wrapper:?:table_fields_for,?placeholder:'備注'
??????%td.col-md-1
????????=?f.hidden_field?:_destroy
????????=?link_to?"刪除",?"javascript:void(0)",?class:?"remove_fields?"
在bid_contact頁面則可以這么寫:
%tr
??%th 電話
??%td= f.simple_fields_for :telephones do |builder|
?? ?? = render '/bid/firms/phone_field', f: builder
??.form-actions
????= link_to_add_fields "添加電話錄入框", f, :telephones , "phone_field"
#我們需要給表格的電話信息的表單存在添加按鈕里,所以就自己寫了一個生成按鈕的方法
def link_to_add_fields(name, f, association, partial=nil, link_options={})
??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|
????partial ||= association.to_s.singularize + "_fields"
?? ??render(partial, f: builder)
??end
??link_to(name, 'javascript:void(0)', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")},style:link_options[:style])
end
控制添加移除電話項的按鍵事件可以這么寫:
$('form').on('click', '.add_fields', function(event){
$(this).before($(this).data('fields'));
event.preventDefault();
});
//設(shè)定_destroy的值為true,這表示刪除這一項
$('.remove_fields').click(function (event) {
$(this).prev('input[type=hidden]').val('true');
$(this).closest('table').hide();
event.preventDefault();});