ラベル sort_header_tag の投稿を表示しています。 すべての投稿を表示
ラベル sort_header_tag の投稿を表示しています。 すべての投稿を表示

2012/08/31

録画チケットリスト項目を縦表示に

この録画システム構築も終盤に近い感じになってきた。ちょっと中継ぎのような内容だけれど、これはこれで自分的には勉強になったと思ってる。

以前の記事でクエリ機能付きの録画チケットリスト表示を作成した。というか既存のソースをちょっと修正する程度で対応していた。デスクトップならさほど気にならないけど、モバイル端末でリスト表示すると、題名やカテゴリの幅が縦書きかい?ってくらい狭くなってしまう。

これでは読みにくいので、Redmineプラグイン作成時に作ったように、ビデオサムネイルの隣にクエリ項目が縦に並ぶようにしたいな。そして、項目順のソートもちゃんと機能するようにしたいな。
と思ったので、やってみた。よくわからないことだらけだけど、何となく出来た。

前回の記事で作った、videoコントローラのshowアクションはそのまま使う。元々クエリやソートを行えるコードが含まれている。
ビューのshow.html.erbもそのまま使用する。

修正ポイントは、その中で下のように部分レンダリングで呼び出している  '_list.html.erb' をどうする?ってところ。
<%= render :partial => 'video/list', :locals => {:issues => @issues, :query => @query} %>

部分的なパッチではどうにもならず、フルスクラッチに近いのでソースを載せます。
_list.html.erb
<%= form_tag({}) do -%>
<%= hidden_field_tag 'back_url', url_for(params), :id => nil %>
<div class="autoscroll">
  <table class="list issues">
    <% previous_group = false %>
    <tbody>
      <% issue_list(issues) do |issue, level| -%>
      <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %>
      <% reset_cycle %>
      <tr class="group open">
        <td colspan="<%= query.columns.size + 2 %>">
          <span class="expander" onclick="toggleRowGroup(this);"> </span>
          <%= group.blank? ? 'None' : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
          <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", "toggleAllRowGroups(this)", :class => 'toggle-all') %>
        </td>
      </tr>
      <% previous_group = group %>
      <% end %>

      <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">

        <td><% thumb = issue.attachments.detect {|a| a.content_type == "image/jpg"} %>
          <% if !thumb.nil? %>
          <%= link_to image_tag("/videos/"+thumb.disk_filename), {:action => 'play', :id => issue.id } %>
   <% end %>
 </td>
 <!-- 縦表示 -->
        <td><table>
            <% query.columns.each do |column| %>
            <tr>
<!--
              <td align=right title=<%= "並び替え'"+column.caption+"'" %>>
                <%= link_to column.caption, :controller=>"video", :action=>"show", :sort=>"#{column.name},start_date:desc" %&g\
t;
-->
              <%= v_column_header(column) %>
              <td align=left><%= column_content(column, issue) %>
            </tr>
     <% end %>
        </table></td>
      </tr>
      <% end -%>
    </tbody>
  </table>
</div>
<% end -%>

'list issues'テーブルヘッダはサクッとなくした。
グループ表示はどうしようかと思ったけれど、それなりに機能するんで残した。
オリジナルでの項目内容表示は以下の一行で簡単に表示できてしまうけど
<%= raw query.columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
サムネイルの隣に縦に並べたいのでサブテーブルを作って、一つ一つ'tr/td'で表示する

最初にとった方法

テーブルヘッダに表示されているチケット項目名はどうやって表示するんだろ?
オリジナルでは、column_header(column)だけでヘッダに項目が表示されているようだ。きっとヘルパー関数だろう。issuesヘルパーだろうと思ったが、あったのは、redmine/app/helpers/queries_helper.rbの中だった。
なるのど、これで、column.captionに項目名が入っていることが分かった。
column.nameは?と思ったらこっちはレコードのカラム名だったので表示用じゃない。

項目ソートさせるにはどうするんだろ?
色々調べたらlink_toに:sortを付けておくとソートしてくれる感じになった。
<%= link_to column.caption, :controller=>"video", :action=>"show", :sort=>"#{column.name},start_date:desc" %>
だけど、これだとソートはされるが昇順/降順切り替えに対応出来ない。

普通のチケットリストヘッダはどうやってるんだろ?

queries_helperのcolumn_header(column)がその部分のようだ。
ここからsort_helperのsort_header_tagが呼ばれる。
さらに、sort_link関数で上記のようなソートオプション付きのリンクが生成される。
最終的にRailsのcontent_tagを使って'th'タグで出力される。

なるのど、column_header()とsort_header_tag()の2つでやっているのだな。
直接'th'タグを指定しているので残念ながらそのままじゃ利用できない。惜しい。

ヘルパー関数追加
’th’の代わりに'td'タグで出力する関数を用意すれば良さそうだ。
プラグイン作ったときに自動で生成されたvideo_helper.rbに加えることにした。
helpers/video_helper.rb
 -*- coding: utf-8 -*-                                                                                                                    
module VideoHelper
                                              
  def v_column_header(column)
    column.sortable ? v_sort_header_tag(column.name.to_s,
                                        :caption => column.caption,
                                        :default_order => column.default_order) :
      content_tag('td', h(column.caption))
  end
                                              
  def v_sort_header_tag(column, options = {})
    caption = options.delete(:caption) || column.to_s.humanize
    default_order = options.delete(:default_order) || 'asc'
    options[:title] = l(:label_sort_by, "\"#{caption}\"") unless options[:title]
    content_tag('td', sort_link(column, caption, default_order), options)
  end
end
それぞれの関数を、v_column_header、v_sort_header_tagにして'th'を'td'にしただけ。
これがビューで使えるように、コントローラファイル(video_controller.rb)に
helper :video
の1文を追加。ビューのみで使用するので、include VideoHelperは必要ない。
これでテーブルのtd項目で昇順/降順切り替え付きのソートリンクが出来た。

チケットごとの項目内容は、column_content(column, issue) で簡単に表示できるんで言うことなし。

見やすさは、ブラウザや端末別のビューを用意しておくとかで、もっと改善するだろうね。その辺に興味が湧いたらまたいじってみようと思う。

次回の記事はこの録画システム構築の終盤として、ビデオ簡易編集についてです。