2011-09-26 15 views
3

我正在開發一個應用程序,該應用程序在許多不同的區域顯示錶格數據,並且我發現自己經常反覆使用相同的HTML表結構。例如,一個特定的表看起來像這樣:在Rails 3.1中,如何創建一個使用塊樣式格式的HTML表生成器

%table.zebra-striped#user-table{ :cellspacing => "0" } 
    %colgroup 
    %col{:id => "email"} 
    %col{:id => "username"} 
    %col{:id => "sign-in-count"} 
    %col{:id => "last-sign-in-at"} 

    %thead 
    %tr 
     %th{:id => "email-head", :scope => "col"} E-mail 
     %th{:id => "username-head", :scope => "col"} Username 
     %th{:id => "sign-in-count-head", :scope => "col"} Sign Ins 
     %th{:id => "last-sign-in-at-head", :scope => "col"} Last Sign In 

    %tbody 
    - @users.each do |user| 
     %tr{ :class => zebra } 
     %td 
      =h user.email 
     %td 
      =h user.username 
     %td 
      =h user.sign_in_count 
     %td 
      =h user.last_sign_in_at 

理想情況下,我想創造某種輔助方法,在那裏我可以這樣做:

= custom_table_for @users do 
    = column :email 
    = column :username do |user| 
    = link_to user.username, user_path(user) 
    = column "Sign Ins", :sign_in_count 
    = column :last_sign_in_at 

這樣我可以改變的格式列中的數據和列標題名稱(如果我對默認值不滿意),但會爲我生成表格。

我想我可以創建一個正常的幫手,但我不得不使用數組,我不知道如何包括自定義數據格式每列。

active_admin有類似這樣的,你可以在這裏看到的東西:http://activeadmin.info/docs/3-index-pages/index-as-table.html

任何線索或想法,將不勝感激。

回答

4

我只是想出了這一點:

的幾點:

  • @columns = []是復位,所以你可以把它不止一次。
  • custom_table_for中的yield調用您傳遞它的塊。
  • 列方法中的block被存儲並在custom_table_for中調用(如果已設置)。

我還包括一個示例類以顯示使用情況。

請注意我這樣做一個Rails應用程序之外,你幾乎可以肯定要使用http://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag代替p "<table>"的這僅是爲了示例的目的,當你在控制檯中運行它。

module TableHelper 
    def custom_table_for(items) 
    @columns = [] 
    yield 
    p "<table>" 
     @columns.each do |c| 
     p "<th>#{c[:value]}</th>" 
     end 

     items.each do |e| 
     p "<tr>" 
     @columns.each do |c| 
      e[c[:name]] = c[:block].call(e[c[:name]]) if c[:block] 
      p "<td>#{e[c[:name]]}</td>" 
     end 
     p "</tr>" 
     end 
    p "</table>" 
    end 

    def column(name, value = nil, &block) 
    value = name unless value 
    @columns << {:name => name, :value => value, :block => block} 
    end 
end 

class ExampleTable 
    include TableHelper 
    def test 
    @users = [{:email => "Email 1", :username => "Test User"}, {:email => "Email 2", :username => "Test User 2"}] 
    custom_table_for @users do 
     column :email, "Email" 
     column :username do |user| 
     user.upcase 
     end 
    end 
    end 
end 

et = ExampleTable.new 
et.test 

UPDATE

我遷移這軌使用content_tags

module TableHelper 
    def custom_table_for(items) 
    @columns = [] 
    yield 


    content_tag :table do 
     thead + tbody(items) 
    end 

    end 

    def thead 
    content_tag :thead do 
     content_tag :tr do 
     @columns.each do |c| 
      concat(content_tag(:th, c[:value])) 
     end 
     end 
    end 
    end 

    def tbody(items) 
    content_tag :tbody do 
     items.each { |e| 
     concat(content_tag(:tr){ 
      @columns.each { |c| 
      e[c[:name]] = c[:block].call(e[c[:name]]) if c[:block] 
      concat(content_tag(:td, e[c[:name]])) 
      } 
     }) 
     } 
    end 
    end 

    def column(name, value = nil, &block) 
    value = name unless value 
    @columns << {:name => name, :value => value, :block => block} 
    end 
end 
+0

真棒,迫不及待地讓這個旋轉。我想我可以將模塊粘貼在/lib/table_helper.rb文件中,然後我必須在我的應用程序視圖中明確包含TableHelper模塊以使用它。 – jklina

+0

嗯,很好的問題,我想你可以將它包含在你的應用程序幫助器中? – Gazler

+0

當我回家時,我會玩弄它。我現在肯定有足夠的領先優勢。 – jklina

0

恭維@ gazler的迴應,這裏有一個方法,使一個單一的resource--列的表一個用於屬性名稱,第二列用於它們的值:

module TableHelper 

    @resource = nil 

    def simple_table_for(resource) 
    @resource = resource 

    content_tag :table do 
     content_tag :tbody do 
     yield 
     end 
    end 
    end 

    def row(key, label = nil, &block) 
    if key.is_a? String 
     label = key 
    end 

    content_tag(:tr) { 
     concat content_tag :td, label || key.capitalize 
     concat content_tag(:td){ 
      if block_given? 
      yield 
      else 
      @resource.send(key) 
      end 
     } 
    } 
    end 
end 
相關問題