Yahoo! UI を使った表示画面のソースコードを少し解説します
- 21,36,51行目の<div>はダイアログ用のフォームです。通常のHTMLのフォームからsubmitボタンを削除しただけです。
- 81〜95行目はテーブルに表示するJSON形式のデータ を作成する部分です。
- 98〜103行目は上で作った表にイベントハンドラーを定義する部分です。
- 105行目からは YUIコンポーネントの作成コードです。コンポーネントの大きさやボタン等の文字を定義しています。
- 106〜123行目は テーブルの作成
- 134〜162行目は ダイアログの作成
- 179〜196行目はツールチップのデータ取り込みと、ツールチップの作成Callback関数。サーバーから表示用文字列が送られてきた際に実行されます。文字列を受け取り、ツールチップを表示しています。
- 205〜220行目はツールチップ表示のイベントハンドラー。まだツールチップの表示文字列が取り込まれていなければ asyncRequest() を使ってサーバーに文字列のリクエストを送っています。
- 222〜235行目は「感謝」などのダイアログ表示のイベントハンドラー。hiddenタグの値を書き換え、ダイアログを表示しています。
- 240行目はテーブル表示エリア
こんな感じで、Yahoo! UI は案外かんたんに使えます :-)
1 <style type="text/css"> 2 span.popup_base { 3 color: #00f; 4 } 5 div.info_sw { 6 margin: 0 0 10px 10px; 7 } 8 .info_sw input { 9 margin: 0 5px 0 20px; 10 } 11 </style> 12 13 <div class="info_sw"> 14 <input type="radio" name="info" checked /><span>新着情報</span> 15 <input type="radio" name="info"/><span>検索結果</span> 16 <input type="radio" name="info"/><span>履歴情報</span> 17 <input type="radio" name="info"/><span>人気翻訳情報</span> 18 <input type="radio" name="info"/><span>人気未翻訳情報</span> 19 </div> 20 21 <div id="reqDialog"> 22 <div class="hd">翻訳リクエスト !!</div> 23 <div class="bd"> 24 <form name="dlgForm" method="POST" action="/article/request_create"> 25 <p><label>ニックネーム(オプション)</label> 26 <input id="req_nickname" name="nickname" size="10" type="text" value="<%=@user.nickname%>" /></p> 27 28 <p><label>メッセージ(オプション)</label> 29 <input id="req_comment" name="comment" size="30" type="text" value="" /></p> 30 31 <input id="req_article_id" name="article_id" type="hidden" value="1" /> 32 </form> 33 </div> 34 </div> 35 36 <div id="apprDialog"> 37 <div class="hd">感謝 ♪♪</div> 38 <div class="bd"> 39 <form name="dlgForm" method="POST" action="/article/appreciate_create"> 40 <p><label>ニックネーム(オプション)</label> 41 <input id="appr_nickname" name="nickname" size="10" type="text" value="<%=@user.nickname%>" /></p> 42 43 <p><label>メッセージ(オプション)</label> 44 <input id="appr_comment" name="comment" size="30" type="text" value="" /></p> 45 46 <input id="appr_translation_id" name="translation_id" type="hidden" value="1" /> 47 </form> 48 </div> 49 </div> 50 51 <div id="transDialog"> 52 <div class="hd">翻訳の登録</div> 53 <div class="bd"> 54 <form name="dlgForm" action="/article/translate_create" method="post"> 55 <p><label for="translation_url">翻訳形態(必須)</label> 56 <select id="translation_kind" name="translation[kind]"> 57 <option value="1">概訳</option> 58 <option value="2">意訳</option> 59 <option value="3">全訳</option></select></p> 60 61 <p><label for="translation_url">翻訳ページのURL(必須)</label> 62 <input id="translation_url" name="translation[url]" size="40" type="text" /></p> 63 64 <p><label>ニックネーム(オプション)</label> 65 <input id="nickname" name="nickname" size="10" type="text" value="<%=@user.nickname%>" /></p> 66 67 <p><label>BlogのURL(オプション)</label> 68 <input id="blog" name="blog" size="40" type="text" value="<%=@user.blog%>" /></p> 69 70 <p><label for="article_title">メッセージ(オプション)</label> 71 <input id="translation_comment" name="translation[comment]" size="30" type="text" /></p> 72 73 <input id="trans_article_id" name="article_id" type="hidden" value="1" /> 74 </form> 75 </div> 76 </div> 77 78 79 <script type="text/javascript"> 80 81 YAHOO.example.Data = { 82 bookorders: [ 83 <% for a in @articles %> 84 <% t = Translation.optimal_trans(a.translations) %> 85 { 86 req:'<span class="popup_base" onClick="popup_request(<%=a.id%>);" id="req<%=a.id%>" onmouseover="showReq(<%=a.id%>);"> ⌘ <%=star_mark(a.requests.size)%> </span>', 87 appr:'<% if t %><span class="popup_base" onClick="popup_appreciate(<%=t.id%>);" id="appr<%=t.id%>"> ⌘ <%=star_mark(t.appreciations.size)%> </span><% end %>', 88 trans:'<span class="popup_base" onClick="popup_translation(<%=a.id%>);">⌘</span> ' + 89 ' <% if t %><a href="<%=t.url%>"><%=translation_status(t.kind.to_i)%></a> <% end %>', 90 title:'<a href="<%= t ? t.url : a.link%>" id="title<%=a.id%>"><%=h a.title %></a>', 91 site:'<a href="<%=a.link%>"><%=h a.source %></a>', 92 date:'<%=short_date a.dc_date %>' 93 }, 94 <% end %> 95 ] 96 } 97 98 <% for a in @articles %> 99 <% t = Translation.optimal_trans(a.translations) %> 100 YAHOO.util.Event.addListener("req<%=a.id%>", "mouseover", showReq, "<%=a.id%>"); 101 <% if t %>YAHOO.util.Event.addListener("appr<%=t.id%>", "mouseover", showAppr, "<%=t.id%>");<% end %> 102 YAHOO.util.Event.addListener("title<%=a.id%>", "mouseover", showDesc, "<%=a.id%>"); 103 <% end %> 104 105 YAHOO.util.Event.addListener(window, "load", function() { 106 YAHOO.example.Basic = new function() { 107 var myColumnDefs = [ 108 {key:"req", label:"訳して!", sortable:true, resizeable:true}, 109 {key:"appr", label:"感謝", sortable:true, resizeable:true}, 110 {key:"trans", label:"翻訳", sortable:true, resizeable:true}, 111 {key:"title", label:"タイトル", sortable:true, resizeable:true}, 112 {key:"site", label:"サイト", sortable:true, resizeable:true}, 113 {key:"date", label:"日付", sortable:true, resizeable:true} 114 ]; 115 116 this.myDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.bookorders); 117 this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; 118 this.myDataSource.responseSchema = { 119 fields: ["trans","req","appr","title","site","date"] 120 }; 121 122 this.myDataTable = new YAHOO.widget.DataTable("list_table", myColumnDefs, 123 this.myDataSource); 124 125 YAHOO.namespace("example.container"); 126 127 var handleCancel = function() { 128 this.cancel(); 129 }; 130 var handleSubmit = function() { 131 this.submit(); 132 }; 133 134 YAHOO.example.container.dialogReq = new YAHOO.widget.Dialog("reqDialog", 135 { width : "300px", 136 modal : true, 137 visible : false, 138 constraintoviewport : true, 139 buttons : [ { text:"訳して!", handler:handleSubmit, isDefault:true }, 140 { text:"Cancel", handler:handleCancel } ], 141 postmethod : "form"} ); 142 YAHOO.example.container.dialogReq.render(); 143 144 YAHOO.example.container.dialogAppr = new YAHOO.widget.Dialog("apprDialog", 145 { width : "300px", 146 modal : true, 147 visible : false, 148 constraintoviewport : true, 149 buttons : [ { text:"ありがとう!", handler:handleSubmit, isDefault:true }, 150 { text:"Cancel", handler:handleCancel } ], 151 postmethod : "form"} ); 152 YAHOO.example.container.dialogAppr.render(); 153 154 YAHOO.example.container.dialogTrans = new YAHOO.widget.Dialog("transDialog", 155 { width : "400px", 156 modal : true, 157 visible : false, 158 constraintoviewport : true, 159 buttons : [ { text:"登録 ", handler:handleSubmit, isDefault:true }, 160 { text:"Cancel", handler:handleCancel } ], 161 postmethod : "form"} ); 162 YAHOO.example.container.dialogTrans.render(); 163 164 }; 165 }); 166 167 var tooltipHash = []; 168 169 function makeTooptipAndShow(o, prefix, title) { 170 var m = o.responseText.match(/^([0-9]+);(.*)$/); 171 if (!m) return; 172 var t = new YAHOO.widget.Tooltip(prefix + "Tooltip" + m[1], 173 {context: prefix + m[1], text: "<b>" + title + "</b><br/>" + m[2]}); 174 tooltipHash[prefix + m[1]] = t; 175 t.onContextMouseMove(o.argument, t); 176 t.doShow(o.argument); 177 } 178 179 var callbackReq = { 180 success: function(o){ 181 if (o.responseText !== undefined) makeTooptipAndShow(o, "req", "翻訳リクエスト"); 182 }, 183 argument: [] 184 }; 185 var callbackAppr = { 186 success: function(o){ 187 if (o.responseText !== undefined) makeTooptipAndShow(o, "appr", "感謝の言葉"); 188 }, 189 argument: [] 190 }; 191 var callbackDesc = { 192 success: function(o){ 193 if (o.responseText !== undefined) makeTooptipAndShow(o, "title", "概要"); 194 }, 195 argument: [] 196 }; 197 198 199 function clone_object(src) { 200 var dst = new Object; 201 for (var p in src) dst[p] = src[p]; 202 return dst; 203 } 204 205 function showReq(e, id) { 206 if (tooltipHash["req" + id]) return; 207 callbackReq.argument = clone_object(e); 208 var request = YAHOO.util.Connect.asyncRequest('GET', '/article/get_request/' + id, callbackReq); } 209 210 function showAppr(e, id) { 211 if (tooltipHash["appr" + id]) return; 212 callbackAppr.argument = clone_object(e); 213 var request = YAHOO.util.Connect.asyncRequest('GET', '/article/get_appreciate/' + id, callbackAppr); 214 } 215 216 function showDesc(e, id) { 217 if (tooltipHash["title" + id]) return; 218 callbackDesc.argument = clone_object(e); 219 var request = YAHOO.util.Connect.asyncRequest('GET', '/article/get_article/' + id, callbackDesc); 220 } 221 222 function popup_request(id) { 223 document.getElementById("req_article_id").value = id; 224 YAHOO.example.container.dialogReq.show(); 225 } 226 227 function popup_appreciate(id) { 228 document.getElementById("appr_translation_id").value = id; 229 YAHOO.example.container.dialogAppr.show(); 230 } 231 232 function popup_translation(id) { 233 document.getElementById("trans_article_id").value = id; 234 YAHOO.example.container.dialogTrans.show(); 235 } 236 237 238 </script> 239 240 <div id="list_table"></div> 241 242 <br /> 243 <br /> 244 245 <%= link_to '情報登録', :action => 'new' %>