Ни о чём →
Rails. Добавление элемента при использовании nested attributes
Теория
При использовании nested attributes и fields_for очень часто нам нужно добавлять новый элемент в форму при помощи javascript.
Руководствуясь принципом DRY рекомендую использовать следующее решение. Я знаю, что это общеизвестная техника, но как обычно бывает большинство всё-равно изобретает свои решения, ну и во всяком случае на русском языке таких примеров я не видел.
В application_helper.rb я уже добавил следующий код:
def add_object_link(name, form, object, partial, where)
html = render(:partial => partial, :locals => {:form => form}, :object => object)
link_to_function name, %{
var new_object_id = new Date().getTime() ;
var html = jQuery(#{html.to_json}.replace(/index_to_replace_with_js/g, new_object_id)).hide();
html.appendTo(jQuery("#{where}")).slideDown('slow');
}
end
Это основной helper, который генерирует html нового элемента при помощи javascript, где:
name — заголовок ссылки
form — объект формы form_for
object — объект элемента, который нужно добавить
partial — название шаблона, который генерирует html для отображение добавляемого элемента
where — id html-контейнера на странице
Пример
Допустим у нас есть рубрика (Rubric), в которую нужно добавить какие-то характеристики (Anchor)
app/models/rubric.rb
class Rubric < ActiveRecord::Base
has_many :anchors
accepts_nested_attributes_for :anchors, :allow_destroy => true
end
app/models/anchor.rb
class Anchor < ActiveRecord::Base
belongs_to :rubric
end
app/view/admin/rubrics/edit.html.haml
- form_for @rubric do |f|
%h3
Анкоры
!= add_object_link('<img src="/images/icons/add.png" />', f, Anchor.new, "anchor", "#anchors")
%ul#anchors
- @rubric.anchors.each do |anchor|
!= render :partial => "anchor", :locals => {:form => f, :anchor => anchor}
!= f.submit("Сохранить анкоры")
app/view/admin/rubrics/_anchor.html.haml
- raise ArgumentError unless defined?(form)
- raise ArgumentError unless defined?(anchor)
%li.anchor
- form.fields_for :anchors, anchor, :child_index => (anchor.new_record? ? "index_to_replace_with_js" : nil) do |anchor_form|
!= anchor_form.text_field :title
- if anchor_form.object.new_record?
%a{:href => "#", :onclick => "jQuery(this).parent('.anchor').remove(); return false;"}
%img{:src => "/images/icons/delete.png"}
- else
!= anchor_form.check_box '_destroy'
!= anchor_form.label '_destroy', 'удалить?'
p.s. Ни на что не претендую, просто хочу обратить всё большее количество людей в свою веру =)
26.03.2011 20:43+0300