2 * Copyright (c) 2009 The openGion Project.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 * either express or implied. See the License for the specific language
14 * governing permissions and limitations under the License.
16 package org.opengion.hayabusa.taglib;
18 import org.opengion.fukurou.system.OgRuntimeException; // 6.4.2.0 (2016/01/29)
19 import static org.opengion.fukurou.util.StringUtil.nval;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
24 import org.opengion.fukurou.util.Options;
25 //import org.opengion.hayabusa.common.HybsSystem; // 8.5.2.0 (2023/07/14) Delete
26 import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17)
29 * フォームの入力欄などで入力候補となるデータリストを定義するHTML拡張タグです。
30 * HTML5 から、新たに追加された要素です。
32 * データリスト内の選択肢は、optionタグ、queryOptionタグによって指定します。
33 * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。
36 * ●形式:<og:datalist id="…" />
37 * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません)
41 * id ○【TAG】入力候補を表示するフォームの list 属性に設定する id (必須)
42 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
43 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
44 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
45 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
46 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
47 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
49 * </og:datalist>
52 * <og:input type="text" name="tokyo" autocomplete="on" list="tokyo.sel" />
54 * <og:datalist id="tokyo.sel" >
55 * <og:option value="渋谷" />
56 * <og:option value="新宿" />
57 * <og:option value="池袋" />
58 * </og:datalist>
60 * ただし、値なしのOptionを含めても(addNoValue="true")、HTML5の仕様上、
63 * @og.group 【HTML5】選択データ制御
64 * @og.rev 5.7.1.0 (2013/12/06) 新規追加
67 * @author Kazuhiko Hasegawa
70 public class DatalistTag extends CommonTagSupport implements OptionAncestorIF {
71 /** このプログラムのVERSION文字列を設定します。 {@value} */
72 private static final String VERSION = "8.5.2.0 (2023/07/14)" ;
73 private static final long serialVersionUID = 852020230714L ;
75 private transient Options option = new Options();
82 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
84 public DatalistTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
87 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
89 * @return 後続処理の指示( EVAL_BODY_INCLUDE )
92 public int doStartTag() {
93 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
95 ? EVAL_BODY_INCLUDE // Body インクルード( extends TagSupport 時)
96 : SKIP_BODY ; // Body を評価しない
100 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
102 * @og.rev 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合、INDBMENU を作成します。
103 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
104 * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
109 public int doEndTag() {
110 debugPrint(); // 4.0.0 (2005/02/28)
111 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
113 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
115 final String errMsg = "idは必須です。" ;
116 throw new OgRuntimeException( errMsg );
119 final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
121 // // 5.7.6.2 (2014/05/16) IEのHTML5機能が無効の場合の処理 8.5.2.0 (2023/07/14) Delete
122 // final String ieHTML5 = (String)getSessionAttribute( HybsSystem.IE_HTML5_KEY );
123 // if( "FALSE".equalsIgnoreCase( ieHTML5 ) ) {
124 // final String inName = id.endsWith( ".sel" ) ? id.substring( 0,id.length()-4 ) : id ;
126 // rtn.append("<select id='").append( id )
127 // .append( "' style='position:absolute;' onChange='selChanged(this);' >" )
128 // .append( option.getOption() )
129 // // 8.1.0.0 (2021/12/28) HTML5 準拠に見直し(<script> type属性削除)
130 //// .append( "</select><script type='text/javascript'>makeInputMenu('" )
131 // .append( "</select><script>makeInputMenu('" )
132 // .append( inName ).append( "');</script>" );
135 // // display:none は、datalist の optionのBODY部が、HTML5 以外では表示されてしまうため。
136 // rtn.append("<div style='display:none;'><datalist id='")
137 // .append( id ).append( "' >" )
138 // .append( option.getOption() )
139 // .append( "</datalist></div>" );
141 rtn.append("<datalist id='")
142 .append( id ).append( "' >" )
143 .append( option.getOption() )
144 .append( "</datalist>" );
146 jspPrint( rtn.toString() );
152 * タグリブオブジェクトをリリースします。
153 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
157 protected void release2() {
159 option = new Options();
164 * データリストの選択項目を追加します。
166 * datalist タグのBODY要素の OptionTag よりアクセスされます。
168 * @param opt オプションタグ文字列
169 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
171 @Override // OptionAncestorIF
172 public void addOption( final String opt ) {
177 * メニュー項目の最後の項目を削除します。
179 * select タグのBODY要素の OptionTag よりアクセスされます。
181 * @og.rev 6.8.0.0 (2017/06/02) メニュー項目の最後の項目を削除。
183 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#removeLast()
185 @Override // OptionAncestorIF
186 public void removeLast() {
191 * 【HTML】要素に対して固有の名前(id)をつける場合に設定します。
194 * データリスト の id 属性は、フォームの list 属性と同じキーを指定する事で関連付けします。
197 * 内部事情で、inputタグ(columnタグ)の list属性 に設定するキーも、id属性に設定するキーも、
198 * inputタグ(columnタグ)の name属性+".sel" を標準的に使用してください。
203 public void setId( final String id ) {
204 this.id = nval( getRequestParameter( id ), null );
210 * OptionTag で、value を取り出して、内部の値と同じ場合は、選択状態にします。
212 * @og.rev 5.7.1.0 (2013/12/06) 新規追加
215 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
217 @Override // OptionAncestorIF
218 public String getValue() {
224 * 複数選択可能時に全選択を設定するかどうかを返します。
226 * これは、上位入れ子のタグの OptionTag で、multipleAll を取り出して、
227 * true であれば、全選択に設定します。
229 * @og.rev 5.7.1.0 (2013/12/06) 新規追加
232 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
234 @Override // OptionAncestorIF
235 public boolean isMultipleAll() {
241 * パラメーター変換({@XXXX}の置き換えをしない状態のパラメーターをセットします。
245 * @og.rev 5.7.1.0 (2013/12/06) 新規追加
247 * @param param パラメーター
248 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#addOption( String )
250 @Override // OptionAncestorIF
251 public void setRawParam( final String param ) {
256 * セレクトメニューの場合、キー:ラベル形式で表示するかどうか[true/false/null]を返します。
258 * これは、上位入れ子のタグの OptionTag で、addKeyLabel を取り出して、
259 * true であれば、キー:ラベル形式 のオプションを、#addOption( String ) で
262 * @og.rev 6.0.4.0 (2014/11/28) キー:ラベル形式で表示するかどうか。新規追加
265 * @see #addOption( String )
266 * @see org.opengion.hayabusa.taglib.OptionAncestorIF#getAddKeyLabel()
268 @Override // OptionAncestorIF
269 public String getAddKeyLabel() {
275 * シリアライズ用のカスタムシリアライズ読み込みメソッド
277 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
279 * @serialData 一部のオブジェクトは、シリアライズされません。
281 * @param strm ObjectInputStreamオブジェクト
283 * @throws IOException シリアライズに関する入出力エラーが発生した場合
284 * @throws ClassNotFoundException クラスを見つけることができなかった場合
286 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
287 strm.defaultReadObject();
288 option = new Options();
292 * このオブジェクトの文字列表現を返します。
293 * 基本的にデバッグ目的に使用します。
295 * @return このクラスの文字列表現
299 public String toString() {
300 return ToString.title( this.getClass().getName() )
301 .println( "VERSION" ,VERSION )
303 .println( "Other..." ,getAttributes().getAttribute() )
304 .fixForm().toString() ;