001package org.opengion.plugin.column;
002
003import org.opengion.fukurou.util.Attributes;
004import org.opengion.fukurou.util.TagBuffer;
005import org.opengion.fukurou.util.XHTMLTag;
006import org.opengion.hayabusa.common.HybsSystem;
007import org.opengion.hayabusa.db.AbstractEditor;
008import org.opengion.hayabusa.db.CellEditor;
009import org.opengion.hayabusa.db.DBColumn;
010import org.opengion.hayabusa.db.Selection;
011
012/**
013 * DATALIST_R エディターは、コードリソースから取得した値より、datalistを作成して
014 * 入力候補となるデータリストを定義する編集用エディタークラスです。
015 * datalist は、HTML5 から採用されたタグです。
016 * 
017 * 入力フィールドとdatalistタグの関係付は、カラムIDに、"カラムID.sel" で結びつけます。
018 * 
019 * <input name="カラムID" list="カラムID.sel" />
020 * <div style="display:none;">
021 *   <datalist id="カラムID.sel">
022 *     <option value="KEY1">LABEL1</option>
023 *     <option value="KEY2">LABEL2</option>
024 *     <option value="KEY3">LABEL3</option>
025 *   </datalist>
026 * </div>
027 * 
028 * divタグは、HTML5 非対応ブラウザを使用した場合、datalist の option がそのまま
029 * テキストとして見えてしまうのを避けるためです。
030 * 
031 * @og.rev 5.9.18.1 (2017/03/24)
032 * @og.group データ編集
033 * 
034 * @version 5.9.18.1
035 * @author T.OTA
036 * @since JDK6.0
037 *
038 */
039public class Editor_DATALIST_R extends AbstractEditor {
040        private static final String     VERSION                 = "5.9.18.1 (2017/03/24)";
041        private static final String     DIV1                    = "<div style=\"display:none;\">";
042        private static final String     DIV2                    = "</div>";
043
044        /** セレクションオブジェクト */
045        protected Selection                     selection;
046        private Selection                       bkSel                   = null;                                                 // Selection オブジェクトのキャッシュ機能
047        private final boolean           seqFlag;
048        private final TagBuffer         selTagBuffer    = new TagBuffer();
049
050        /**
051         * デフォルトコンストラクター。
052         * このコンストラクターで、基本オブジェクトを作成します。
053         * 
054         */
055        public Editor_DATALIST_R() {
056                selection = null;
057                seqFlag = false;
058        }
059
060        /**
061         * コンストラクター。
062         * 
063         * @param clm DBColumnオブジェクト
064         */
065        private Editor_DATALIST_R( final DBColumn clm ) {
066                super( clm );
067                tagBuffer.add( XHTMLTag.inputAttri( attributes ) );
068                seqFlag = "SEQ".equals( clm.getEditorParam() );
069
070                String disabled = clm.isWritable() ? null : "disabled";
071
072                Attributes selAttri = new Attributes();
073                selAttri.set( "disabled", disabled );
074
075                selAttri.addAttributes( clm.getEditorAttributes() );
076                selTagBuffer.add( XHTMLTag.selectAttri( selAttri ) );
077
078                selection = clm.getSelection();
079        }
080
081        /**
082         * 各オブジェクトから自分のインスタンスを返します。
083         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
084         * まかされます。
085         * 
086         * @param       clm DBColumnオブジェクト
087         * 
088         * @return CellEditorオブジェクト
089         */
090        @Override
091        public CellEditor newInstance( final DBColumn clm ) {
092                return new Editor_DATALIST_R( clm );
093        }
094
095        /**
096         * データの編集用文字列を返します。
097         * 
098         * @param value 入力値
099         * 
100         * @return データの編集用文字列
101         */
102        @Override
103        public String getValue( String value ) {
104                // input タグの作成
105                TagBuffer intag = new TagBuffer( "input" );
106                intag.add( "name", name );
107                if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) {
108                        intag.add( "id", name );
109                }
110                intag.add( "list", name + ".sel" );
111                intag.add( "value", value );
112                intag.add( "size", size1 );
113                intag.add( tagBuffer.makeTag() );
114                intag.add( optAttr );
115
116                // datalist タグの作成
117                TagBuffer dltag = new TagBuffer( "datalist" );
118                dltag.add( "id", name + ".sel" );
119                dltag = getOption( dltag, value, false ); // キャッシュは使用しない
120
121                // display:none は、datalist の optionのBODY部が、HTML5以外では表示されてしまうのを防ぐため。
122                return intag.makeTag() + HybsSystem.CR + DIV1 + dltag.makeTag() + DIV2 + HybsSystem.CR;
123        }
124
125        /**
126         * name属性を変えた、データ表示/編集用のHTML文字列を作成します。
127         * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し、
128         * リクエスト情報を1つ毎のフィールドで処理できます。
129         *
130         * @param       row             行番号
131         * @param       value   入力値
132         * 
133         * @return      データ表示/編集用の文字列
134         */
135        @Override
136        public String getValue( int row, String value ) {
137                String name2 = name + HybsSystem.JOINT_STRING + row;
138
139                // Selection オブジェクトのキャッシュ機能 (true:使用可能)
140                boolean useSelCache = value != null && value.indexOf( ':' ) < 0;
141
142                String listId = useSelCache ? name : name2; // キャッシュを使用する場合は、共通の name を使う。
143
144                // input タグの作成
145                TagBuffer intag = new TagBuffer( "input" );
146                intag.add( "name", name2 );
147                if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) {
148                        intag.add( "id", name2 );
149                }
150                intag.add( "list", listId + ".sel" );
151                intag.add( "value", value );
152                intag.add( "size", size2 );
153                intag.add( tagBuffer.makeTag() );
154                intag.add( optAttr );
155
156                // datalist タグの作成
157                TagBuffer dltag = new TagBuffer( "datalist" );
158                dltag.add( "id", listId + ".sel" );
159                dltag = getOption( dltag, value, useSelCache );
160
161                // キャッシュが効くと、getOptionの戻り値は、nullになる。
162                if( dltag != null ) {
163                        return intag.makeTag( row, value ) + HybsSystem.CR + DIV1 + dltag.makeTag( row, value ) + DIV2 + HybsSystem.CR;
164                }
165                else {
166                        return intag.makeTag( row, value ) + HybsSystem.CR;
167                }
168        }
169
170        /**
171         * コードリソースから取得した、選択肢(オプション)をTagBuffer に反映します。
172         * 
173         * 第3引数は、Selection オブジェクトのキャッシュ機能を使用するかどうかを指定します。
174         * true で、使用する事を前提に、チェックを行います。
175         * 
176         * @param       buf                     タグ文字列のバッファー
177         * @param       value           選択されている値
178         * @param       useSelCache     Selection オブジェクトのキャッシュ
179         * 
180         * @return      buf     オプションタグ
181         */
182        private TagBuffer getOption( final TagBuffer buf, final String value, final boolean useSelCache ) {
183
184                if( useSelCache ) {
185                        if( selection == bkSel ) { return null; }
186                        bkSel = selection;
187                }
188
189                buf.setBody( selection.getOption( value, seqFlag ) );
190
191                return buf;
192        }
193}