001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.taglib; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.hayabusa.html.TabData; 021 022import static org.opengion.fukurou.util.StringUtil.nval ; 023 024import java.util.List; 025import java.util.ArrayList; 026import java.util.Locale ; 027 028/** 029 * タブペインで、項目を分割して表示するタブテーブルを作成します。 030 * 031 * ※ データの大きさによってtabLink、tabList と使い分けてください。 032 * 033 * 一つの大きなHTMLを、タブを使用することで複数の塊に分割表示できます。 034 * 分割された各タブは、一つのHTMLのため、タブ間の移動による情報の消失はありません。 035 * また、一つのHTMLのため、タブにまたがって入力した値は、すべて 一括送信することも 036 * 可能です。(Formタグで、全てのタブをまとめて記述していれば) 037 * タブテーブルは、orientation 属性で、横(horizontal)と縦(vertical)を指定できます。 038 * これは、タブの位置が異なるだけで、機能は同一です。初期値は、横(horizontal)です。 039 * 個々のタブの指定は、tab タグを使用します。 040 * 必ず一つ以上のtab タグを BODY要素に記述する必要があります。 041 * selectedIndex を指定すると、初期表示させるタブを指定できます。番号は0から始まります。 042 * 043 * @og.formSample 044 * ●形式:<og:tabTable 045 * orientation = "[horizontal/vertical]" タブの方向(横/縦) 046 * height = "[100px / 100%]" テーブルの高さ(px OR %) 047 * width = "[100px / 100%]" テーブルの幅(px OR %) 048 * selectedIndex = "[0..]" 初期表示するタブ番号 049 * > 050 * <og:tab lbl="・・・" > ... </og:tab > タブそのもの 051 * <og:tab lbl="・・・" > ... </og:tab > タブそのもの 052 * </og:tabTable > 053 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 054 * 055 * ●Tag定義: 056 * <og:tabTable 057 * orientation 【廃止】タブの方向、横型(horizontal)か縦型(vertical)を指定します(初期値:横型) 058 * height タブの高さを、% 、px 、または "auto" で指定します 059 * width タブの幅を % 、px 、または "auto" で指定します 060 * selectedIndex 初期表示するページ番号を指定します(初期値:0) 061 * style 【廃止】初期表示時のタブに与える style 属性を指定します 062 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 063 * > ... Body ... 064 * </og:tabTable> 065 * 066 * ●使用例 067 * 横型(horizontal)の場合。横型が初期値のため、無指定で使用できます。 068 * <og:tabTable> 069 * <og:tab lbl="page 1"><jsp:directive.include file="paGE1.jsp" /></og:tab> 070 * <og:tab lbl="page 2"><jsp:directive.include file="page2.jsp" /></og:tab> 071 * <og:tab lbl="page 3"><jsp:directive.include file="page3.jsp" /></og:tab> 072 * </og:tabTable> 073 * 074 * 【廃止】縦型(vertical)の場合。テーブルの高さを指定する必要があります。(px OR %) 075 * <og:tabTable orientation="vertical" height="100px" > 076 * <og:tab lbl="page 1"><jsp:directive.include file="paGE1.jsp" /></og:tab> 077 * <og:tab lbl="page 2"><jsp:directive.include file="page2.jsp" /></og:tab> 078 * <og:tab lbl="page 3"><jsp:directive.include file="page3.jsp" /></og:tab> 079 * </og:tabTable> 080 * 081 * @og.rev 3.5.6.5 (2004/08/09) 新規作成 082 * @og.rev 5.9.1.3 (2015/10/30) 大幅改造。htc依存ではなく、jQuery利用に変更。廃止タグから戻す。 083 * @og.group 画面部品 084 * 085 * @version 4.0 086 * @author Kazuhiko Hasegawa 087 * @since JDK5.0, 088 */ 089public class TabTableTag extends CommonTagSupport { 090 //* このプログラムのVERSION文字列を設定します。 {@value} */ 091 private static final String VERSION = "4.0.0.0 (2005/08/31)" ; 092 093 private static final long serialVersionUID = 400020050831L ; 094 095 private static final String CR = HybsSystem.CR ; 096// private static final String JSV = "<script language=\"JavaScript\">ots.style.height = otab.offsetHeight ;</script>"; 097 private static final String JSV = "<script type=\"text/javascript\">ots.style.height = otab.offsetHeight ;</script>"; 098 099 // 5.9.1.3 (2015/10/30) 100 private static final String JQUITAB1 = "<script type=\"text/javascript\">$('#ogjquitab').tabs("; 101 private static final String JQUITAB2 = ");</script>"; 102 103 private transient List<TabData> tabList = null; 104 private boolean orientation = true; // true:horizontal false:vertical 105 106 // 3.5.6.6 (2004/08/23) height と width の初期値変更。 107 private String height = null; 108 private String width = null; 109 private String style = null; // 3.8.6.1 (2006/10/24) 110 private int selectedIndex = -1 ; // 3.7.1.1 (2005/05/31) 初期選択されるページ番号 111 private int realIndex = -1 ; // 3.8.6.2 (2006/11/01) 実際の選択タブのページ番号 112 private int realTabCount = -1 ; // 3.8.6.2 (2006/11/01) 実際のタブのページ番号 113 114 /** 115 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 116 * 117 * @return 後続処理の指示( EVAL_BODY_BUFFERED ) 118 */ 119 @Override 120 public int doStartTag() { 121 return( EVAL_BODY_BUFFERED ); // Body を評価する。( extends BodyTagSupport 時) 122 } 123 124 /** 125 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 126 * 127 * @return 後続処理の指示 128 */ 129 @Override 130 public int doEndTag() { 131 debugPrint(); // 4.0.0 (2005/02/28) 132 if( tabList == null ) { 133 String errMsg = "BODY部に TabTag が必ず必要です。"; 134 throw new HybsSystemException( errMsg ); 135 } 136 137 jspPrint( makeTag() ); 138 139 // 5.9.1.3 (2015/10/30) 初期展開はJSにオプションを渡す必要があるためここで書く 140 jspPrint( JQUITAB1 ); 141 if( selectedIndex >= 0 ){ 142 jspPrint( "{ selected:" + selectedIndex + "}" ); 143 } 144 jspPrint( JQUITAB2 ); 145 146 return(EVAL_PAGE); 147 } 148 149 /** 150 * タグリブオブジェクトをリリースします。 151 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 152 * 153 * @og.rev 3.5.6.6 (2004/08/23) height と width の初期値変更。 154 * @og.rev 3.8.6.1 (2006/10/24) style属性を追加 155 * @og.rev 3.8.6.2 (2006/11/01) selectedIndex の初期値変更(0 ⇒ -1)。 156 */ 157 @Override 158 protected void release2() { 159 super.release2(); 160 tabList = null; 161 orientation = true; // true:horizontal false:vertical 162 height = null; 163 width = null; 164 selectedIndex = -1 ; // 3.7.1.1 (2005/05/31) 初期選択されるページ番号 165 realIndex = -1 ; // 3.8.6.2 (2006/11/01) 実際の選択タブのページ番号 166 realTabCount = -1 ; // 3.8.6.2 (2006/11/01) 実際のタブのページ番号 167 style = null; 168 } 169 170 /** 171 * 出力するタグ文字列を作成します。 172 * 173 * @og.rev 3.5.6.6 (2004/08/23) メソッドを HorizontalとVerticalに分割。 174 * @og.rev 5.9.1.3 (2015/10/30) 現段階ではorientationは無視するように変更 175 * 176 * @return タグ文字列 177 */ 178 private String makeTag() { 179 180 if( orientation ) { 181 if( height == null ) { height = "auto"; } 182 if( width == null ) { width = "auto"; } 183 return makeHorizontalTag(); 184 } 185 else { 186// if( height == null ) { height = "200px"; } 187// if( width == null ) { width = "100%" ; } 188 if( height == null ) { height = "auto"; } 189 if( width == null ) { width = "auto"; } 190 return makeVerticalTag(); 191 } 192 193 194 } 195 196 /** 197 * 出力する horizontal タグ文字列を作成します。 198 * 199 * @og.rev 3.5.6.6 (2004/08/23) メソッドを HorizontalとVerticalに分割。 200 * @og.rev 3.7.1.1 (2005/05/23) 初期表示するページ番号を指定 201 * @og.rev 3.8.6.0 (2006/08/23) IE7対応。mp:multipage の width:100%; を削除 202 * @og.rev 3.8.6.1 (2006/10/20) action属性を追加 203 * @og.rev 3.8.6.2 (2006/11/01) selectedIndex は、初めての OPENタブとします。 204 * @og.rev 5.9.1.3 (2015/10/30) htcではなくjQuery利用に変更 205 * 206 * @return タグ文字列 207 */ 208 private String makeHorizontalTag() { 209 // 注意:/**/ でマーカー付けされている行は、縦横で異なる記述が書かれています。 210 if( realIndex < 0 ) { realIndex = 0; } // 3.8.6.2 (2006/11/01) 211 212 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_LARGE ); 213 214 // 5.9.1.3 方式変更につき大幅変更tableをやめてdiv囲い 215 216// buf.append( "<table cellpadding=\"0px\" cellspacing=\"0px\"" ).append( CR ); 217// buf.append( " style=\"width:" ).append( width ).append( ";" ); 218// 219// buf.append( "\">" ).append( CR ); 220// buf.append( " <tr valign=\"top\">" ).append( CR ); 221// buf.append( " <td id=\"otab\">" ).append( CR ); 222// buf.append( " <ts:tabstrip id=\"ots\" targetid=\"omp\" style=\"height:100%\"" ).append( CR ); 223// buf.append( " tabdefaultstyle=\"border:solid 1px black;padding:3px;\"" ).append( CR ); 224// buf.append( " tabhoverstyle=\"color:blue;\"" ).append( CR ); 225// buf.append( " tabselectedstyle=\"border:solid 1px black;border-bottom:none\"" ).append( CR ); 226// buf.append( " sepdefaultstyle=\"border-bottom:solid 1px black;\"" ).append( CR ); 227// // 3.7.1.1 (2005/05/23) 追加 228// buf.append( " selectedIndex=\"" ).append( realIndex ).append( "\"" ).append( CR ); 229// buf.append( " orientation=\"horizontal\">" ).append( CR ); 230 231 buf.append( " <div id=\"ogjquitab\" style=\"width:"+ width +"; height:"+ height + "\"> " ); // 5.9.1.3 (2015/10/30) 232 233 int size = tabList.size(); 234 TabData tab ; 235 buf.append( " <ul> " ); // 5.9.1.3 (2015/10/30) 236 for( int i=0; i<size; i++ ) { 237 tab = tabList.get(i); 238 if( tab.isOpen() ) { 239 buf.append( tab.getTab( style,i ) ).append( CR ); 240 } 241 else { 242 buf.append( tab.getTab( null,i ) ).append( CR ); 243 } 244 245// if( orientation && (i != size-1) ) { 246// buf.append( "<ts:tabseparator />" ).append( CR ); 247// } 248 } 249 buf.append( " </ul> " ); // 5.9.1.3 (2015/10/30) 250 251// buf.append( "<ts:tabseparator defaultstyle=\"width:100%;height:100%\" />" ).append( CR ); 252 253// buf.append( " </ts:tabstrip>" ).append( CR ); 254// buf.append( " </td>" ).append( CR ); 255 256// buf.append( "</tr><tr style=\"height:" ).append( height ).append( "\" >" ).append( CR ); 257 258// buf.append( " <td width=\"100%\">" ).append( CR ); 259// buf.append( " <mp:multipage id=\"omp\"" ).append( CR ); 260///**/ // buf.append( " style=\"border:solid 1px black;border-top:none;padding:5px;height:100%;width:100%;\">" ).append( CR ); 261///**/ buf.append( " style=\"border:solid 1px black;border-top:none;padding:5px;height:100%;\">" ).append( CR ); 262 263 for( int i=0; i<size; i++ ) { 264 tab = tabList.get(i); 265// buf.append( tab.getTabBody() ).append( CR ); 266 buf.append( tab.getTabBody( i ) ).append( CR ); 267 } 268// buf.append( " </mp:multipage>" ).append( CR ); 269// buf.append( " </td>" ).append( CR ); 270// buf.append( " </tr>" ).append( CR ); 271// buf.append( "</table>" ).append( CR ); 272 buf.append( "</div>" ).append( CR ); 273 return buf.toString(); 274 } 275 276 /** 277 * 出力する vertical タグ文字列を作成します。 278 * 279 * @og.rev 3.5.6.6 (2004/08/23) メソッドを HorizontalとVerticalに分割。 280 * @og.rev 3.7.1.1 (2005/05/23) 初期表示するページ番号を指定 281 * @og.rev 3.8.6.0 (2006/08/23) IE7対応。mp:multipage の height:100%; を削除 282 * @og.rev 3.8.6.1 (2006/10/20) action属性を追加 283 * @og.rev 3.8.6.2 (2006/11/01) selectedIndex は、初めての OPENタブとします。 284 * @og.rev 5.9.1.3 (2015/10/30) 現状、makeHorizontalTagをそのまま返す実装としておく 285 * 286 * @return タグ文字列 287 */ 288 private String makeVerticalTag() { 289/* 290 if( realIndex < 0 ) { realIndex = 0; } // 3.8.6.2 (2006/11/01) 291 292 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_LARGE ); 293 294 buf.append( "<table cellpadding=\"0px\" cellspacing=\"0px\"" ).append( CR ); 295 buf.append( " style=\"width:" ).append( width ).append( ";" ); 296 buf.append( "height:" ).append( height ).append( ";" ); 297 298 buf.append( "\">" ).append( CR ); 299 buf.append( " <tr valign=\"top\">" ).append( CR ); 300 buf.append( " <td id=\"otab\">" ).append( CR ); 301 buf.append( " <ts:tabstrip id=\"ots\" targetid=\"omp\" style=\"height:100%\"" ).append( CR ); 302 buf.append( " tabdefaultstyle=\"border:solid 1px black;padding:3px;\"" ).append( CR ); 303 buf.append( " tabhoverstyle=\"color:blue;\"" ).append( CR ); 304 buf.append( " tabselectedstyle=\"border:solid 1px black;border-right:none\"" ).append( CR ); 305 buf.append( " sepdefaultstyle=\"border-right:solid 1px black;\"" ).append( CR ); 306 // 3.7.1.1 (2005/05/23) 追加 307 buf.append( " selectedIndex=\"" ).append( realIndex ).append( "\"" ).append( CR ); 308 buf.append( " orientation=\"vertical\">" ).append( CR ); 309 310 int size = tabList.size(); 311 TabData tab ; 312 for( int i=0; i<size; i++ ) { 313 tab = tabList.get(i); 314 if( tab.isOpen() ) { 315 buf.append( tab.getTab( style ) ).append( CR ); 316 } 317 else { 318 buf.append( tab.getTab( null ) ).append( CR ); 319 } 320 321 if( orientation && (i != size-1) ) { 322 buf.append( "<ts:tabseparator />" ).append( CR ); 323 } 324 } 325 buf.append( "<ts:tabseparator defaultstyle=\"width:100%;height:100%\" />" ).append( CR ); 326 327 buf.append( " </ts:tabstrip>" ).append( CR ); 328 buf.append( " </td>" ).append( CR ); 329 330 buf.append( " <td style=\"width:100%;height:100%;\">" ).append( CR ); 331 buf.append( " <mp:multipage id=\"omp\"" ).append( CR ); 332 // buf.append( " style=\"border:solid 1px black;border-left:none;padding:5px;height:100%;width:100%;\">" ).append( CR ); 333 buf.append( " style=\"border:solid 1px black;border-left:none;padding:5px;height:100%;\">" ).append( CR ); 334 335 for( int i=0; i<size; i++ ) { 336 tab = tabList.get(i); 337 buf.append( tab.getTabBody() ).append( CR ); 338 } 339 buf.append( " </mp:multipage>" ).append( CR ); 340 buf.append( " </td>" ).append( CR ); 341 buf.append( " </tr>" ).append( CR ); 342 buf.append( "</table>" ).append( CR ); 343 buf.append( JSV ).append( CR ); // vertical 時に IE7でサイズの取り方が異なる為の対策。 344*/ 345 // http://alphasis.info/2013/04/jquery-ui-tabs-vertical/ 346 // 縦向きにする方法も一応あるが、ややこしいので現段階では無視 347 return makeHorizontalTag(); 348 } 349 350 /** 351 * 設定する タブオブジェクトを、内部変数(List)に追加します。 352 * 353 * BODY 部に記述された タブオブジェクトを順番に追加します。 354 * タブペインのタグを出力する場合も、この順番で作成します。 355 * 356 * @og.rev 3.8.6.1 (2006/10/20) action属性を追加 357 * @og.rev 3.8.6.2 (2006/11/01) realIndex は、初めての OPENタブとします。 358 * 359 * @param data タブオブジェクト 360 */ 361 protected void addTabData( final TabData data ) { 362 if( tabList == null ) { tabList = new ArrayList<TabData>(); } 363 tabList.add( data ); 364 365 // タブが選択されていれば、その値を選択番号とする。 366 if( realIndex < 0 && data.isOpen() ) { 367 realIndex = tabList.size()-1 ; 368 } 369 } 370 371 /** 372 * selectedIndex で設定されたタブかどうかを判断して返します。 373 * 374 * このメソッド呼び出しは、各タブから1回のみ有効とします。 375 * 呼び出すたびに、内部変数 realTabCount をカウントアップします。 376 * つまり、その数が、タブの個数に対応します。 377 * タブは、DELETE と判断されるケースがあるため、実際の数より少なく登録されます。 378 * そのときに、ここで自分自身が選択されていることを判断して、実際の選択タブを 379 * JavaScript に指定するときに使用します。 380 * 381 * @og.rev 3.8.6.2 (2006/11/01) 新規作成 382 * 383 * @return 選択タブかどうか 384 */ 385 protected boolean isSelected() { 386 realTabCount ++ ; 387 return (selectedIndex == realTabCount) ; 388 } 389 390 /** 391 * 【廃止】タブの方向、横型(horizontal)か縦型(vertical)を指定します(初期値:横型)。 392 * 393 * @og.tag 394 * タブは、上にタブが並ぶ横型と左にタブが並ぶ縦型があります。 395 * この属性では、横型は、horizontal 、縦型は、vertical を指定します。 396 * 指定は、文字列の最初の一文字を見ているだけですので、HかVでも構いません。 397 * 初期値は、横型(horizontal) です。 398 * 399 * @param ori タブの方向、横型(horizontal)か縦型(vertical)を指定 400 * @deprecated クラスが廃止されました。 401 */ 402 @Deprecated public void setOrientation( final String ori ) { 403 String ori2 = nval( getRequestParameter( ori ),null ); 404 if( ori2 != null && ori2.length() > 0 ) { 405 char ch = ori2.toUpperCase(Locale.JAPAN).charAt( 0 ); 406 if( ch == 'H' ) { orientation = true; } 407 else if( ch == 'V' ) { orientation = false; } 408 else { 409 String errMsg = "orientation の指定は、H(orizontal) または、V(ertical) です。" 410 + " orientation=" + ori2 ; // 5.1.8.0 (2010/07/01) errMsg 修正 411 throw new HybsSystemException( errMsg ); 412 } 413 } 414 } 415 416 /** 417 * タブの高さを、% 、px 、または "auto" で指定します。 418 * 419 * @og.tag 420 * 縦型(orientation="vertical")の初期値は、"auto" です。 421 * 横型(orientation="horizontal")の初期値は、"200px"です。 422 * 横型の場合は、"auto" に設定すると、高さが "0" になってしまいます。 423 * 必ず、なにかの値(px)で指定する必要があります。 424 * 縦型 で "auto" に設定すると、各タブ毎に中の記述情報によって、タブの 425 * 大きさが替わります。タブを切り替えた時に、違和感がない様にするには、 426 * 高さを固定(px 指定)するとよいです。 427 * 428 * @og.rev 5.9.1.3 (2015/10/30) 復活 429 * 430 * @param ht 高さ (% 、px 、または "auto" ) 431 */ 432 public void setHeight( final String ht ) { 433 height = nval( getRequestParameter( ht ),height ); 434 } 435 436 /** 437 * タブの幅を % 、px 、または "auto" で指定します。 438 * 439 * @og.tag 440 * 縦型(orientation="vertical")の初期値は、"auto" です。 441 * 横型(orientation="horizontal")の初期値は、"100%"です。 442 * ※ 縦型の場合、幅に px で数字を設定しても、有効に作用しません。 443 * 444 * @og.rev 5.9.1.3 (2015/10/30) 復活 445 * 446 * @param wh 幅 (% 、px 、または "auto" ) 447 */ 448 public void setWidth( final String wh ) { 449 width = nval( getRequestParameter( wh ),width ); 450 } 451 452 /** 453 * 初期表示するページ番号を指定します(初期値:0)。 454 * 455 * @og.tag 456 * タブテーブルには、複数のタブを含みます。初期表示時にどのタブを 457 * 表示するかを指定します。 458 * ページ番号は、0から始まる数字です。 459 * 初期値は、0です。 460 * 461 * @og.rev 3.7.1.1 (2005/05/23) 新規作成 462 * @og.rev 5.9.1.3 (2015/10/30) 復活 463 * 464 * @param no 初期表示するページ番号(0..) 465 */ 466 public void setSelectedIndex( final String no ) { 467 selectedIndex = nval( getRequestParameter( no ),selectedIndex ); 468 } 469 470 /** 471 * 【廃止】初期表示時のタブに与える style 属性を指定します。 472 * 473 * @og.tag 474 * ts:tab 本体では、初期選択時のスタイルシートを、defaultStyle と 475 * selectedStyle で与える必要があります。これは、id 属性を設定して、 476 * 外部でスタイルシートを定義する形式で指定できません。 477 * ここで指定した style 属性 は、個別の tabTag に与える style 属性 より優先度は 478 * 低くなります。 479 * 480 * @og.rev 3.8.6.1 (2006/10/24) 新規追加 481 * 482 * @param st タブに与える 初期 style 属性 483 * @deprecated クラスが廃止されました。 484 */ 485 @Deprecated public void setStyle( final String st ) { 486 style = nval( getRequestParameter( st ),style ); 487 } 488 489 /** 490 * このオブジェクトの文字列表現を返します。 491 * 基本的にデバッグ目的に使用します。 492 * 493 * @return このクラスの文字列表現 494 */ 495 @Override 496 public String toString() { 497 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 498 .println( "VERSION" ,VERSION ) 499 .println( "height" ,height ) 500 .println( "width" ,width ) 501 .println( "selectedIndex" ,selectedIndex ) 502 .println( "Other..." ,getAttributes().getAttribute() ) 503 .fixForm().toString() ; 504 } 505}