I have a class
class DataListBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helper
options_column
is a "block view", I'd remove the = in <%= l.options_column do |c| %>
, that's for sure. Then, I'd use concat
in options_column
instead of returning it directly as a string.
Anyway, the simple solution is here (I've used it, no problems at all):
https://github.com/markevans/block_helpers
First of all we refactored your helper for more intensive usage of content_tag
(just to get whats going in this code ^_^).
Next we add usage of output_buffer
which was defined but not used at all in helper.
After it all methods wich should be called from erb
should return nil
so they didn't appear in HTML.
And last syntactic suger was usage of instance_eval
so you don't need {|c| ...}
style blocks. You can use all variables from DataListBuilder
directly there.
module DataListHelper
def list_headers(args=[])
args = Array.new(args)
columns = []
args.map { |o| columns << content_tag(:li, o.split(":").first, :style=>"width:#{o.split(":").second}px;") }
content_tag(:ul, columns.join(" ").html_safe, :class=>"list-headers")
end
def data_list_total_records(array)
content_tag(:div, page_entries_info(array).html_safe, :class=>"total-records")
end
def data_list_for(object, headers=[], &block)
if object.is_a? Array
if object.length == 0
list_headers(headers).concat(content_tag(:strong, "<br />No records found".html_safe))
else
res_obj = data_list_total_records(object)
res_obj << content_tag(:ol, :class=>"data-list") do
res_ol = content_tag(:li) do
res = list_headers(headers)
object.each do |o|
builder = DataListBuilder.new(o)
res << content_tag(:li) do
content_tag(:ul, :id=>o.id, :class=>"list-row #{cycle('odd', 'even')}") do
capture(builder, &block)
builder.output_buffer.html_safe
end
end
end
res
end
res_ol << data_list_pagination(object)
end
res_obj
end
else
list_headers(headers).concat(content_tag(:strong, " <br />Not available."))
end
end
class DataListBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::UrlHelper
include Rails.application.routes.url_helpers
attr_accessor :object, :output_buffer, :controller
def initialize(object)
@object, @output_buffer = object, ''
end
def column (&block)
@output_buffer << if block_given?
content_tag(:li, instance_eval(&block))
else
content_tag(:li, "")
end
nil
end
def options_column(&link_block)
@output_buffer << if block_given?
content_tag(:li) do
content_tag(:dl, :class=>'options') do
res = content_tag(:dt) do
content_tag(:a, ' '.html_safe, :href => '#')
end
res << content_tag(:dd) do
content_tag(:ul) do
instance_eval &link_block
end
end
end
end
else
content_tag(:li, "")
end
nil
end
def link_item(title, url, options={})
content_tag :li, link_to(title, url, options)
end
end
end
And your view became this:
<%= data_list_for @leads, [" :10", "Age:30", "Contact:140", "Phone:140", "Email:180", "Company:100", ""] do |l| %>
<%= l.column { link_to " ".html_safe, "leads/details/#{object.id}", :class=>:plus, :remote=>true } %>
<%= l.column { object.age } %>
<%= l.column { object.contact.complete_name } %>
<%= l.column { object.contact.phones.blank? ? "-" : object.contact.phones.first.phone_number } %>
<%= l.column { object.contact.emails.blank? ? "-" : object.contact.emails.first.email } %>
<%= l.column { object.company.title } %>
<%= l.options_column do %>
<%= link_item 'Show', lead_path(object.id) %>
<%= link_item 'Edit', edit_lead_path(object.id) %>
<%= link_item 'New Note', "leads/#{object.id}/notes/new", :class=>"display-newxdoc", :id=>object.id %>
<%= link_item 'Create Opportunity', new_lead_opportunity_path(object.id) %>
<% end %>
<% end %>