サイボウズみたいな表を作りたい
ここ数日のイメージ
「縦に時間があって、横に人名があって、開始と終了の時間を元に予定を表示させたいな・・・」
こんな感じのプラグインとかヘルパーとかあるんじゃないかと探したが見つからない。
Redmineの1週間の表は1日の予定を出すけど、時間で区切ってくれない。
ガントチャートも人名というグループで表示はしてくれない。
そこで作りはじめる。
コントローラー
/app/controllers/hoge.rb def dayview @day_gantt = find_response_search if request.get? if params[:page].nil? @day_gantt.empty_daygantt! @day_gantt.select_day = Date.parse(params[:select_day]) unless params[:select_day].nil? @day_gantt.time_from = Date.parse(params[:time_from]) unless params[:time_from].nil? @day_gantt.time_to = Date.parse(params[:time_to]) unless params[:time_to].nil? end else @day_gantt.set_daygantt_params(params) end params[:page] = 1 if params[:page].nil? @select_day = @day_gantt.select_day.to_date @page_title = "個人表" @time_from = @select_day.to_date + @day_gantt.time_from.to_i.hours @time_to =@select_day.to_date + @day_gantt.time_to.to_i.hours @events = [] @events += Hoge.find(:all, :conditions =>["started >= ? AND responded <= ?", @time_from, @time_to]) @events_staffs = @events.group_by{|event| event.staff_name } end
日付と範囲時間で検索、人名でグループ化しています。
モデル
/app/model/hoge_cond.rb def empty_daygantt! @select_day = Date.today @time_from=8 @time_to=22 end def set_daygantt_params(params) @select_day = params[:day_gantt][:select_day] @time_from = params[:day_gantt][:time_from] @time_to = params[:day_gantt][:time_to] end
初期値は「本日の8時から22時まで」とします。
ビュー
これを作るときに気がついた。HTMLの都合で横方向を作るのは簡単だけど、縦は難しい。
というこで、横から挑戦。
/app/views/hoge/dayview.html.erb <%- content_for :html_header do -%> <%= stylesheet_link_tag 'calendar' %> <%= calendar_date_select_includes %> <script type="text/javascript"> _translations = { "OK": "OK", "Now": "現在", "Today": "今日" } Date.weekdays = $w("日 月 火 水 木 金 土"); Date.months = $w("1 2 3 4 5 6 7 8 9 10 11 12" ); </script> <style type ="text/css"><!-- div.hour_view{ float:left; width:56px; text-align:center; padding:1px; margin:1px; border:1px; border-style:solid; border-color:silver; } div.hour_back{ float:left; width:56px; height:50px; text-align:center; color:silver; padding:1px; margin:1px; border:1px; border-left-style:solid; border-right-style:solid; border-left-color:silver; border-right-color:silver; z-index:1; } div.hour_content{ z-index:10; height:30px; position:absolute; text-align:center; margin-top:20px; border:1px; border-style:solid; border-color:green; } --> </style> <%- end -%> <h2><%= @page_title %></h2> <%- form_tag do %> <table width="100%"> <tr> <td align="left"> <%= calendar_date_select(:day_gantt, :select_day) %> <%- hours_arr=[[8,8],[9,9],[10,10],[11,11],[12,12],[13,13],[14,14],[15,15],[16,16],[17,17],[18,18],[19,19],[20,20],[21,21],[22,22]] -%> <%= select :day_gantt, :time_from, hours_arr, :selected=>@day_gantt.time_from.to_i %>から <%= select :day_gantt, :time_to, hours_arr, :selected=>@day_gantt.time_to.to_i %>まで <%= submit_tag "変更", :class => "button-small" %> </td> <td><%= @select_day %></td> </tr> </table> <%- end -%> <table width="100%" style="border:1; border-collapse: collapse;"> <tr> <th width="60px">staff<br /></th> <th >対応<br /> <!-- 時間を作る --> <%- if @day_gantt.time_to.to_i > @day_gantt.time_from.to_i hours_count = @day_gantt.time_to.to_i - @day_gantt.time_from.to_i else hours_count = 1 end start_hours = @day_gantt.time_from.to_i -%> <!-- ヘッダ時間を表示する --> <%- hours_count.times{|i| %> <div class="hour_view"><%= start_hours %></div> <%- start_hours=start_hours+1 } %> </th> </tr> <%- @events_staffs.each do |staffs, res| %> <tr> <td> <%= staffs %> </td> <td> <!-- 背景を作る --> <%- start_hours = @day_gantt.time_from.to_i hours_count.times{|i| %> <div class="hour_back"><%= start_hours %></div> <%- start_hours=start_hours+1 } %> <%- time_taiou = 0 %> <%- res.each do |i| #開始位置を作る if i.started.hour >= @day_gantt.time_from.to_i s_point = (i.started.hour - @day_gantt.time_from.to_i + 1)*60 + i.started.min else s_point = 0 end #終了位置を作る e_point_h = (i.responded - i.started)/3600 e_point_m = ((i.responded - i.started) % 3600) / 60 if e_point_h < 1 e_point = e_point_m else e_point = e_point_h*60 + e_point_m end #累計時間 time_taiou += (i.responded - i.started) %> <%- s="left:"+s_point.to_s+"px;"+"width:"+e_point.to_s+"px;" -%> <div style="<%= s %>" class="hour_content"> <%= modal_link_to truncate("■", :length=>4), {:action=>:modal_open},{:id=>i.req_id} %> <%= modal_script :id=> i.req_id %> </div> <%- end %> <div> <%- hours_t = time_taiou.divmod(3600) mins_t = hours_t[1].divmod(60) %> <%= hours_t[0].to_s%>時間<%= mins_t[0].to_s%>分 </div> </td> <</tr> <%- end %> </table>
プラグインとか使っているので、適当に取り込んでもらえれば動くはず。
1時間を60pxで計算しているので、文章を表示するスペースが足りない・・・■に苦笑
適当なCSSがわるいと思うけど、Firefox3でモーダルが消えない・・・
次は縦を考えぞ!