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 static org.opengion.fukurou.util.StringUtil.nval; 019 020import java.io.IOException; 021import java.io.ObjectInputStream; 022import java.io.ObjectOutputStream; 023 024import org.opengion.fukurou.util.Options; 025import org.opengion.hayabusa.common.HybsSystem; 026 027/** 028 * フォームの入力欄などで入力候補となるデータリストを定義するHTML拡張タグです。 029 * HTML5 から、新たに追加された要素です。 030 * 031 * データリスト内の選択肢は、optionタグ、queryOptionタグによって指定します。 032 * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。 033 * 034 * @og.formSample 035 * ●形式:<og:datalist id="…" /> 036 * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません) 037 * 038 * ●Tag定義: 039 * <og:datalist 040 * id ○【TAG】入力候補を表示するフォームの list 属性に設定する id (必須) 041 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 042 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 043 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 044 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 045 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 046 * > ... Body ... 047 * </og:datalist> 048 * 049 * ●使用例 050 * <og:input type="text" name="tokyo" autocomplete="on" list="tokyo.sel" /> 051 * 052 * <og:datalist id="tokyo.sel" > 053 * <og:option value="渋谷" /> 054 * <og:option value="新宿" /> 055 * <og:option value="池袋" /> 056 * </og:datalist>< 057 * 058 * @og.group 【HTML5】選択データ制御 059 * @og.rev 5.7.1.0 (2013/12/06) 新規追加 060 * 061 * @version 6.0 062 * @author Kazuhiko Hasegawa 063 * @since JDK5.0, 064 */ 065public class DatalistTag extends CommonTagSupport implements OptionAncestorIF { 066 //* このプログラムのVERSION文字列を設定します。 {@value} */ 067 private static final String VERSION = "5.7.6.2 (2014/05/16)" ; 068 069 private static final long serialVersionUID = 576220140516L ; 070 071 private transient Options option = new Options(); 072 073 private String id = null; // フォームと関連付けるid 074 075 /** 076 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 077 * 078 * @return 後続処理の指示( EVAL_BODY_INCLUDE ) 079 */ 080 @Override 081 public int doStartTag() { 082 if( useTag() ) { 083 return EVAL_BODY_INCLUDE ; // Body インクルード( extends TagSupport 時) 084 } 085 return SKIP_BODY ; // Body を評価しない 086 } 087 088 /** 089 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 090 * 091 * @og.rev 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合、INDBMENU を作成します。 092 * 093 * @return 後続処理 094 */ 095 @Override 096 public int doEndTag() { 097 debugPrint(); // 4.0.0 (2005/02/28) 098 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 099 if( useTag() ) { 100 StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 101 102 // 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合の処理 103 String ieHTML5 = (String)getSessionAttribute( HybsSystem.IE_HTML5_KEY ); 104 if( "FALSE".equalsIgnoreCase( ieHTML5 ) ) { 105 String inName = id.endsWith( ".sel" ) ? id.substring( 0,id.length()-4 ) : id ; 106 107 rtn.append("<select id='").append( id ) 108 .append( "' style='position:absolute;' onChange='selChanged(this);' >" ) 109 .append( option.getOption() ) 110 .append( "</select>" ) 111 .append( "<script type='text/javascript'>makeInputMenu('" ) 112 .append( inName ).append( "');</script>" ); 113 } 114 else { 115 // display:none は、datalist の optionのBODY部が、HTML5 以外では表示されてしまうため。 116 rtn.append("<div style='display:none;'>" ) 117 .append("<datalist id='").append( id ).append( "' >" ) 118 .append( option.getOption() ) 119 .append( "</datalist>" ) 120 .append( "</div>" ); 121 } 122 123 jspPrint( rtn.toString() ); 124 } 125 return EVAL_PAGE ; 126 } 127 128 /** 129 * タグリブオブジェクトをリリースします。 130 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 131 * 132 */ 133 @Override 134 protected void release2() { 135 super.release2(); 136 option = new Options(); 137 id = null; 138 } 139 140 /** 141 * データリストの選択項目を追加します。 142 * 143 * datalist タグのBODY要素の OptionTag よりアクセスされます。 144 * 145 * @param opt オプションタグ文字列 146 */ 147 public void addOption( final String opt ) { 148 option.add( opt ); 149 } 150 151 /** 152 * 【HTML】要素に対して固有の名前(id)をつける場合に設定します。 153 * 154 * @og.tag 155 * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。 156 * 157 * ※ 158 * 内部事情で、inputタグ(columnタグ)の list属性 に設定するキーも、id属性に設定するキーも、 159 * inputタグ(columnタグ)の name属性+".sel" を標準的に使用してください。 160 * 161 * @param id 固有の名前 162 */ 163 @Override 164 public void setId( final String id ) { 165 this.id = nval( getRequestParameter( id ), null ); 166 } 167 168 /** 169 * 値を外部から取り出します。 170 * 171 * OptionTag で、value を取り出して、内部の値と同じ場合は、選択状態にします。 172 * 173 * @og.rev 3.5.4.0 (2003/11/25) 新規作成 174 * 175 * @return 内部に設定された値 176 */ 177 public String getValue() { 178 // ここでは、何もしません。 179 return null; 180 } 181 182 /** 183 * 複数選択可能時に全選択を設定するかどうかを返します。 184 * 185 * これは、上位入れ子のタグの OptionTag で、multipleAll を取り出して、 186 * true であれば、全選択に設定します。 187 * 188 * @og.rev 3.8.0.9 (2005/10/17) 新規作成 189 * 190 * @return 全選択:true / 通常:false 191 */ 192 public boolean isMultipleAll() { 193 // ここでは、何もしません。 194 return false; 195 } 196 197 /** 198 * パラメーター変換({@XXXX}の置き換えをしない状態のパラメーターをセットします。 199 * 200 * @og.rev 5.1.7.0 (2010/06/01) 新規作成(動的プルダウン実装見直し) 201 * @og.rev 5.5.4.0 (2012/07/02) 予約語対応 202 * 203 * @param param パラメーター 204 */ 205 public void setRawParam( final String param ) { 206 // ここでは、何もしません。 207 } 208 209 /** 210 * シリアライズ用のカスタムシリアライズ書き込みメソッド 211 * 212 * @serialData 一部のオブジェクトは、シリアライズされません。 213 * 214 * @param strm ObjectOutputStreamオブジェクト 215 * @throws IOException シリアライズに関する入出力エラーが発生した場合 216 */ 217 private void writeObject( final ObjectOutputStream strm ) throws IOException { 218 strm.defaultWriteObject(); 219 } 220 221 /** 222 * シリアライズ用のカスタムシリアライズ読み込みメソッド 223 * 224 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 225 * 226 * @serialData 一部のオブジェクトは、シリアライズされません。 227 * 228 * @param strm ObjectInputStreamオブジェクト 229 * @see #release2() 230 * @throws IOException シリアライズに関する入出力エラーが発生した場合 231 * @throws ClassNotFoundException クラスを見つけることができなかった場合 232 */ 233 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 234 strm.defaultReadObject(); 235 option = new Options(); 236 } 237 238 /** 239 * このオブジェクトの文字列表現を返します。 240 * 基本的にデバッグ目的に使用します。 241 * 242 * @return このクラスの文字列表現 243 */ 244 @Override 245 public String toString() { 246 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 247 .println( "VERSION" ,VERSION ) 248 .println( "id" ,id ) 249 .println( "Other..." ,getAttributes().getAttribute() ) 250 .fixForm().toString() ; 251 } 252}