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.plugin.column; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.common.HybsSystemException; 020import org.opengion.hayabusa.db.AbstractEditor; 021import org.opengion.hayabusa.db.CellEditor; 022import org.opengion.hayabusa.db.DBColumn; 023import org.opengion.hayabusa.db.Selection; 024import org.opengion.hayabusa.db.SelectionFactory; 025import org.opengion.fukurou.util.StringFormat; 026import org.opengion.fukurou.util.XHTMLTag; 027import org.opengion.fukurou.util.TagBuffer; 028 029/** 030 * カラムの編集パラメーターのSQL文の実行結果より、datalistを作成して 031 * 入力候補となるデータリストを定義する編集用エディタークラスです。 032 * datalist は、HTML5 から採用されたタグです。 033 * 034 * 編集パラメータには、datalistを作成するための、SQL文を記述します。 035 * このSQL文は、select KEY,LABEL from xx ・・・ という構文で、KEY部分とLABEL部分が 036 * 選択されます。 037 * datalist 自身が、HTML5からの新機能なので、現時点では、これ以上の機能はありません。 038 * 将来的に、DBMENU などと同様に、第三カラム以降を利用可能になると思いますので、 039 * 今は使わないでください。(将来の機能追加時に互換性問題を引き起こすかもしれませんので) 040 * 041 * 入力フィールドとdatalistタグとの関係付は、カラムIDに、"カラムID.sel" で結びつけます。 042 * 043 * <input name="カラムID" list="カラムID.sel" /> 044 * <div style="display:none;"> 045 * <datalist id="カラムID.sel"> 046 * <option value="KEY1">LABEL1</option> 047 * <option value="KEY2">LABEL2</option> 048 * <option value="KEY3">LABEL3</option> 049 * </datalist> 050 * </div> 051 * 052 * divタグは、HTML5 非対応ブラウザを使用した場合、datalist の option がそのまま 053 * テキストとして見えてしまうのを避けるためです。 054 * 055 * 一覧表出力時の getValue( int ,String ) 処理では、Selection オブジェクトの 056 * キャッシュ機能を利用して、同一Selection オブジェクトの間は、datalist は、 057 * 1度しか、出力しない様に制御しています。これにより、共有のdatalist を使用する為、 058 * HTMLの出力データ量を抑えることが可能になります。 059 * (キャッシュを利用しないと100行出力すると100個のdatalistを出力する事になります。) 060 * (同様の機能を持つ INDBMENU では、行ごとにプルダウンデータを作成しています。) 061 * ただし、行単位にSQLの条件を変える機能(AAA:BBB:CCC:DDD引数)が指定された場合は、 062 * 行ごとに出力します。 063 * 064 * 各カラムの値(value値)に、AAA:BBB:CCC:DDD という値を設定できます。これは、 065 * $1,$2,$3,$4 に割り当てなおして、QUERYを実行します。また、$1 は、本来の値として、 066 * メニューの初期値設定等に使用します。上記の例では、AAA が値で、それ以降は、 067 * 引数になります。 068 * 又、$Cには自分自身のカラム名を割り当てます。 069 * この機能を使用すれば、動的メニューを行ごとに条件を変えて作成することが 070 * 可能になります。 071 * 例:select KEY,LABEL from xx where KUBUN='$2' and CDK='$3' 072 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 073 * 変数は、""(ゼロ文字列)として、扱われます。 074 * 075 * カラムの表示に必要な属性は, DBColumn オブジェクト より取り出します。 076 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。 077 * 078 * @og.rev 5.7.4.3 (2014/03/28) 新規作成 079 * @og.group データ編集(HTML5) 080 * 081 * @version 4.0 082 * @author Kazuhiko Hasegawa 083 * @since JDK5.0, 084 */ 085public class Editor_DATALIST extends AbstractEditor { 086 //* このプログラムのVERSION文字列を設定します。 {@value} */ 087 private static final String VERSION = "5.7.6.2 (2014/05/16)" ; 088 089 // 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 090 private static final String DIV1 = "<div style=\"display:none;\">" ; 091 private static final String DIV2 = "</div>" ; 092 093 private final String query ; 094 private final String dbid ; 095 private final String lang ; 096 097 private Selection bkSel= null; // 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 098 099 /** 100 * デフォルトコンストラクター。 101 * このコンストラクターで、基本オブジェクトを作成します。 102 * 103 */ 104 public Editor_DATALIST() { 105 // super(); 106 query = null; 107 dbid = null; 108 lang = null; 109 } 110 111 /** 112 * コンストラクター。 113 * 114 * @param clm DBColumnオブジェクト 115 */ 116 private Editor_DATALIST( final DBColumn clm ) { 117 super( clm ); 118 tagBuffer.add( XHTMLTag.inputAttri( attributes ) ); 119 120 query = clm.getEditorParam(); 121 dbid = clm.getDbid(); 122 lang = clm.getLang(); // 4.0.0 (2006/11/15) 123 124 // 3.5.5.9 (2004/06/07) 125 if( query == null || query.length() == 0 ) { 126 String errMsg = "DATALIST Editor では、編集パラメータは必須です。" 127 + " name=[" + name + "]" + HybsSystem.CR ; 128 throw new HybsSystemException( errMsg ); 129 } 130 } 131 132 /** 133 * 各オブジェクトから自分のインスタンスを返します。 134 * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に 135 * まかされます。 136 * 137 * @param clm DBColumnオブジェクト 138 * 139 * @return CellEditorオブジェクト 140 */ 141 public CellEditor newInstance( final DBColumn clm ) { 142 return new Editor_DATALIST( clm ); 143 } 144 145 /** 146 * データの編集用文字列を返します。 147 * 148 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 149 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 150 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 151 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 152 * 変数は、""(ゼロ文字列)として、扱われます。 153 * 又、$Cには自分自身のカラム名を割り当てます。 154 * 155 * @og.rev 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 156 * @og.rev 5.7.6.2 (2014/05/16) list属性とid属性の結びつきを、name+".sel" に変更 157 * 158 * @param value 入力値 159 * 160 * @return データの編集用文字列 161 */ 162 @Override 163 public String getValue( final String value ) { 164 // input タグの作成 165 TagBuffer intag = new TagBuffer( "input" ); 166 intag.add( "name" , name ); 167 if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { 168 intag.add( "id" , name ); 169 } 170// intag.add( "list" , "dl_" + name ); // datalistタグとの関係付けるためのキーワード 171 intag.add( "list" , name + ".sel" ); // datalistタグとの関係付けるためのキーワード 172 intag.add( "value" , value ); 173 intag.add( "size" , size1 ); 174 intag.add( tagBuffer.makeTag() ); 175 intag.add( optAttr ); 176 177 // datalist タグの作成 178 TagBuffer dltag = new TagBuffer( "datalist" ); 179// dltag.add( "id" , "dl_" + name ); // inputタグとの関係付けるためのキーワード 180 dltag.add( "id" , name + ".sel" ); // inputタグとの関係付けるためのキーワード 181 182 dltag = getOption( dltag,value,false ); // キャッシュは使用しない。 183 184 // display:none は、datalist の optionのBODY部が、HTML5 以外では表示されてしまうのを防ぐため。 185 return intag.makeTag() + HybsSystem.CR + 186 DIV1 + dltag.makeTag() + DIV2 + HybsSystem.CR; 187 } 188 189 /** 190 * name属性を変えた、データ表示/編集用のHTML文字列を作成します。 191 * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し, 192 * リクエスト情報を1つ毎のフィールドで処理できます。 193 * 194 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 195 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 196 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 197 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 198 * 変数は、""(ゼロ文字列)として、扱われます。 199 * 又、$Cには自分自身のカラム名を割り当てます。 200 * 201 * @og.rev 5.7.5.0 (2014/04/04) datalist 使用時は、display:none にして、HTML5未対応のブラウザに備える。 202 * @og.rev 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 203 * @og.rev 5.7.6.2 (2014/05/16) list属性とid属性の結びつきを、name+".sel" に変更 204 * 205 * @param row 行番号 206 * @param value 入力値 207 * 208 * @return データ表示/編集用の文字列 209 */ 210 @Override 211 public String getValue( final int row,final String value ) { 212 String name2 = name + HybsSystem.JOINT_STRING + row ; 213 214 // 5.7.5.0 (2014/04/04) Selection オブジェクトのキャッシュ機能 (true:使用可能) 215 boolean useSelCache = value != null && value.indexOf( ':' ) < 0 ; 216 217 String listId = useSelCache ? name : name2; // キャッシュを使用する場合は、共通の name を使う。 218 219 // input タグの作成 220 TagBuffer intag = new TagBuffer( "input" ); 221 intag.add( "name" , name2 ); 222 if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { 223 intag.add( "id" , name2 ); 224 } 225// intag.add( "list" , "dl_" + listId ); // datalistタグとの関係付けるためのキーワード 226 intag.add( "list" , listId + ".sel" ); // datalistタグとの関係付けるためのキーワード 227 intag.add( "value" , value ); 228 intag.add( "size" , size2 ); 229 intag.add( tagBuffer.makeTag() ); 230 intag.add( optAttr ); 231 232 // datalist タグの作成 233 TagBuffer dltag = new TagBuffer( "datalist" ); 234// dltag.add( "id" , "dl_" + listId ); // inputタグとの関係付けるためのキーワード 235 dltag.add( "id" , listId + ".sel" ); // inputタグとの関係付けるためのキーワード 236 237 dltag = getOption( dltag,value,useSelCache ); 238 239 // キャッシュが効くと、getOption の戻り値は、null になる。 240 if( dltag != null ) { 241 return intag.makeTag( row,value ) + HybsSystem.CR + 242 DIV1 + dltag.makeTag( row,value ) + DIV2 + HybsSystem.CR ; 243 } 244 else { 245 return intag.makeTag( row,value ) + HybsSystem.CR ; 246 } 247 } 248 249 /** 250 * 初期値が選択済みの 選択肢(オプション)をTagBuffer に反映します。 251 * このオプションは、引数の値を初期値とするオプションタグ作成し、TagBuffer 252 * に値を設定して返します。 253 * 254 * 第3引数は、Selection オブジェクトのキャッシュ機能を使用するかどうか指定します。 255 * true で、使用する事を前提に、チェックを行います。 256 * DBMENU など、他のメソッドでは、ラベル(短)の使用有無として使用しているため、異なります。 257 * 258 * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、 259 * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に 260 * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。 261 * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない 262 * 変数は、""(ゼロ文字列)として、扱われます。 263 * 又、$Cには自分自身のカラム名を割り当てます。 264 * 265 * @param buf タグ文字列のバッファー 266 * @param value 選択されている値 267 * @param useSelCache Selection オブジェクトのキャッシュ機能を使用するかどうか。 268 * 269 * @return オプションタグ 270 */ 271 private TagBuffer getOption( final TagBuffer buf,final String value,final boolean useSelCache ) { 272 273 StringFormat format = new StringFormat( query, value, name ); 274 String newQuery = format.format(); 275 String newValue = format.getValue(); 276 277 Selection selection = SelectionFactory.newDBSelection( newQuery, dbid, lang ); 278 279 if( useSelCache ) { 280 if( selection == bkSel ) { return null; } 281 bkSel = selection ; 282 } 283 284 buf.setBody( selection.getOption( newValue, false ) ); 285 286 return buf; 287 } 288}