<% # formstrap/repeater # # ==== Required parameters # * +form+ - Form object # * +attribute+ - Name of the attribute of the form model # # ==== Optional parameters # * +header+ - Name of the template to use as header # * +label+ - Text to show as label. Label will be hidden if value is false # * +templates+ - List of all views that can be used as a template for a new block # * +flush+ - Set to true if you want the list items to sit flush with its parent. # * +row+ - Pass hash with options to pass to the row template. # * +preview_url+ - Enables previews of each row. Provide and endpoint capable of rendering a preview for the rows values. # # ==== Examples # # Basic version # <% render "formstrap/repeater", form: form, attribute: :questions do |question| %#> # <% render "admin/questions/fields, form: :question" %#> # <% end %#> # # # Let list group sit flush within its container # <% render "formstrap/repeater", form: form, attribute: :questions, flush: true do |question| %#> # <% render "admin/questions/fields, form: :question" %#> # <% end %#> # # # With fixed header row. A header row can be used to show the labels, so you can omit them in the repeated fields # <% render "formstrap/repeater", form: form, attribute: :questions, header: "admin/questions/header" do |question| %#> # <% render "admin/questions/fields, form: :question" %#> # <% end %#> # # # Allow more than one type of fields to be inserted. You must specify the templates as an array of view paths # <% templates = ["admin/questions/fields/type_1", "admin/questions/fields/type_2"] %#> # <% render "formstrap/repeater", form: form, attribute: :questions, templates: templates do |question, template_name| %#> # <% render "admin/questions/#{template_name}, form: :question" %#> # <% end %#> # # # Enable previews # <% render "formstrap/repeater", form: form, attribute: :questions, preview_url: admin_preview_question_path do |question| %#> # <% render "admin/questions/fields, form: :question" %#> # <% end %#> label = local_assigns.has_key?(:label) ? label : nil required = local_assigns.has_key?(:required) ? required : false header = local_assigns.has_key?(:header) ? header : nil templates = local_assigns.has_key?(:templates) ? templates : [] flush = local_assigns.has_key?(:flush) ? flush : true preview_url = local_assigns.has_key?(:preview_url) ? preview_url : nil row_options = local_assigns.has_key?(:row) ? row : {} template_names = templates.map { |template| File.basename(template, ".html.erb") } template_names = template_names.any? ? template_names : ["new"] object_model = form.object.class association_model = object_model.reflect_on_association(attribute).class_name.constantize association_object = association_model.new with_positions = association_object.attributes.keys.include?("position") associations = form.object.send(attribute) # We sort the collection with ruby to prevent a new query to be made that would dispose of nested object in memory associations = (with_positions && associations.map(&:position).compact.any?) ? associations.sort_by { |resource| resource.position } : associations repeater_id = form.object_id pass_thru = template_names.count == 1 ? "[data-template-name=\"#{template_names.first}\"]" : nil show_label = label != false # Override default row options row_options.merge!( preview_url: preview_url, pass_thru: pass_thru, repeater_id: repeater_id, ) %> <% if show_label %> <%= render "formstrap/label", form: form, attribute: attribute, text: label, required: required %> <% end %>