各種フィールドクラスとHTMLタグの関係
「dataforms.jar API解説――Fromクラスのクライアント、サーバ間の通信」で使用したプロジェクトに 新たなページ(FieldTestPage)を作成します。「SingleSelectTestField.java」「MultiSelectTestField.java」「FieldTestForm.java」は全てコーディングしますが、「FieldTestPage.java」「FieldTestPage.html」「FieldTestForm.js」は開発ツールで生成し、太字部分を追記したものです。作成の手順は以前の記事を参照してください。
package pagesample.page;
import dataforms.app.page.base.BasePage;
import dataforms.dao.Dao;
import dataforms.dao.Table;
/**
* ページクラス。
*/
public class FieldTestPage extends BasePage {
/**
* コンストラクタ。
*/
public FieldTestPage() {
this.addForm(new FieldTestForm());
}
/**
* Pageが配置されるパスを返します。
*
* @return Pageが配置されるパス。
*/
public String getFunctionPath() {
return "/pagesample";
}
/**
* 操作対象テーブルクラスを取得します。
* <pre>
* ページjavaクラス作成用のメソッドです。
* </pre>
* @return 操作対象テーブル。
*/
public Class<? extends Table> getTableClass() {
return Table.class;
}
/**
* テーブルを操作するためのDaoクラスを取得します。
* <pre>
* ページjavaクラス作成用のメソッドです。
* </pre>
* @return Daoクラス。
*/
public Class<? extends Dao> getDaoClass() {
return Dao.class;
}
}
package pagesample.page;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import dataforms.annotation.WebMethod;
import dataforms.controller.Form;
import dataforms.controller.JsonResponse;
import dataforms.controller.Response;
import dataforms.field.sqltype.DateField;
import dataforms.field.sqltype.TimeField;
import dataforms.field.sqltype.TimestampField;
import dataforms.validator.ValidationError;
import net.arnx.jsonic.JSON;
import pagesample.field.HogeFugaField;
import pagesample.field.MultiSelectTestField;
import pagesample.field.SingleSelectTestField;
/**
* フィールドテストフォーム。
*
*/
public class FieldTestForm extends Form {
/**
* Logger.
*/
private static Logger logger = Logger.getLogger(FieldTestForm.class);
/**
* コンストラクタ。
*/
public FieldTestForm() {
super(null);
this.addField(new HogeFugaField()).setComment("VarcharFieldから派生");
this.addField(new DateField("dateField")).setComment("日付");
this.addField(new TimeField("timeField")).setComment("時刻");
this.addField(new TimestampField("timestampField")).setComment("日時");
SingleSelectTestField radioField = new SingleSelectTestField("radioField");
radioField.setHtmlFieldType(dataforms.field.common.SingleSelectField.HtmlFieldType.RADIO);
this.addField(radioField).setComment("ラジオボタン");
SingleSelectTestField selectField = new SingleSelectTestField("selectField");
selectField.setHtmlFieldType(dataforms.field.common.SingleSelectField.HtmlFieldType.SELECT);
this.addField(selectField).setComment("プルダウンリスト");
MultiSelectTestField checkboxField = new MultiSelectTestField("checkboxField");
checkboxField.setHtmlFieldType(dataforms.field.common.MultiSelectField.HtmlFieldType.CHECKBOX);
this.addField(checkboxField).setComment("チェックボックス");
MultiSelectTestField multiSelectField = new MultiSelectTestField("multiSelectField");
multiSelectField.setHtmlFieldType(dataforms.field.common.MultiSelectField.HtmlFieldType.SELECT);
this.addField(multiSelectField).setComment("複数選択リスト");
}
@WebMethod
public Response submit(final Map<String, Object> p) throws Exception {
this.methodStartLog(logger, p);
List<ValidationError> errlist = this.validate(p);
Response ret = null;
if (errlist.size() == 0) {
Map<String, Object> d = this.convertToServerData(p);
logger.debug("d=" + JSON.encode(d));
ret = new JsonResponse(JsonResponse.SUCCESS, "");
} else {
ret = new JsonResponse(JsonResponse.INVALID, errlist);
}
this.methodFinishLog(logger, ret);
return ret;
}
}
package pagesample.field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dataforms.field.common.SingleSelectField;
/**
* 単一選択フィールド。
*
*/
public class SingleSelectTestField extends SingleSelectField<String> {
/**
* 項目長。
*/
private static final int LENGTH = 16;
/**
* フィールドコメント。
*/
private static final String COMMENT = "単一選択";
/**
* コンストラクタ。
*/
public SingleSelectTestField() {
super(null, LENGTH);
this.setComment(COMMENT);
}
/**
* コンストラクタ。
* @param id フィールドID。
*/
public SingleSelectTestField(final String id) {
super(id, LENGTH);
this.setComment(COMMENT);
}
/**
* 選択肢。
*/
private static final String [][]OPTION = {
{"0","AAA"},
{"1","BBB"},
{"2","CCC"},
};
@Override
public void init() throws Exception {
super.init();
List<Map<String, Object>> opt = new ArrayList<Map<String, Object>>();
for (int i = 0; i < OPTION.length; i++) {
Map<String, Object> m = new HashMap<String, Object>();
m.put("value", OPTION[i][0]);
m.put("name", OPTION[i][1]);
opt.add(m);
}
this.setOptionList(opt);
}
}
package pagesample.field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dataforms.field.common.MultiSelectField;
/**
* 複数選択フィールド
*
*
*/
public class MultiSelectTestField extends MultiSelectField<String> {
/**
* 項目長。
*/
private static final int LENGTH = 16;
/**
* フィールドコメント。
*/
private static final String COMMENT = "複数選択";
/**
* コンストラクタ。
*/
public MultiSelectTestField() {
super(null, LENGTH);
this.setComment(COMMENT);
}
/**
* コンストラクタ。
* @param id フィールドID。
*/
public MultiSelectTestField(final String id) {
super(id, LENGTH);
this.setComment(COMMENT);
}
/**
* 選択肢。
*/
private static final String [][]OPTION = {
{"0","AAA"},
{"1","BBB"},
{"2","CCC"},
};
@Override
public void init() throws Exception {
super.init();
List<Map<String, Object>> opt = new ArrayList<Map<String, Object>>();
for (int i = 0; i < OPTION.length; i++) {
Map<String, Object> m = new HashMap<String, Object>();
m.put("value", OPTION[i][0]);
m.put("name", OPTION[i][1]);
opt.add(m);
}
this.setOptionList(opt);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="mainDiv">
<form id="fieldTestForm">
<div class="formHeader">xxx</div>
<table class="responsive">
<tbody>
<tr>
<th>VarcharFieldから派生</th>
<td><input type="text" id="hogeFuga" /></td>
</tr>
<tr>
<th>日付</th>
<td><input type="text" id="dateField" /></td>
</tr>
<tr>
<th>時刻</th>
<td><input type="text" id="timeField" /></td>
</tr>
<tr>
<th>日時</th>
<td><input type="text" id="timestampField" /></td>
</tr>
<tr>
<th>ラジオボタン</th>
<td><span><input type="radio" id="radioField[0]" name="radioField"/></span></td>
</tr>
<tr>
<th>プルダウンリスト</th>
<td><select id="selectField"></select></td>
</tr>
<tr>
<th>チェックボックス</th>
<td><span><input type="checkbox" id="checkboxField[0]" name="checkboxField"/></span></td>
</tr>
<tr>
<th>複数選択リスト</th>
<td><select id="multiSelectField" size="5" multiple="multiple"></select></td>
</tr>
</tbody>
</table>
<button type="button" id="sendButton">送信</button>
</form>
</div>
</body>
</html>
/**
* @fileOverview {@link FieldTestForm}クラスを記述したファイルです。
*/
/**
* @class FieldTestForm
*
* @extends Form
*/
FieldTestForm = createSubclass("FieldTestForm", {}, "Form");
/**
* HTMLエレメントとの対応付けを行います。
*/
FieldTestForm.prototype.attach = function() {
Form.prototype.attach.call(this);
var thisForm = this;
this.find("#sendButton").click(function() {
thisForm.send();
});
};
/**
* 送信処理。
*/
FieldTestForm.prototype.send = function() {
this.submit("submit", function(r) {
logger.log("r=" + JSON.stringify(r));
});
};
このページを表示すると下図のようになります。
HogeFugaFieldに対応するHTMLタグは、前述の「HogeFugaFieldに対応するHTMLタグ」のようにidのみ指定された<input type="text"/>タグが出力されています。このテキストボックスをChromeの開発ツールで検証してみると、以下の通りnameアトリビュートにもフィールドIDと同じ文字列が設定されていることがわかります。これはField.jsの初期化処理で、nameアトリビュートが無いタグには自動的にnameアトリビュートにidと同じ文字列を指定するようになっているからです。
TextField以下のクラスに対応するHTMLタグは、<input type="text" .../>の他に<textarea ></textarea>も対応させることができます。基本的に開発ツールで生成するHTMLは<input type="text" .../>のみです。<textarea></textarea>を使用したい場合、開発ツールで出力されたHTMLを編集してください。
DateField、TimeField、TimestampFieldに対応するHTMLタグも単純な<input type="text" id="..."/>が出力されています。出力されるHTMLは単純なタグですが、DateFieldに対応するフィールドにはjQuery UIのDatepickerが自動的に設定されています。これは「DateField.java」に対応する「DateField.js」の初期化処理でこのような設定を行うようになっているからです。またTimeFieldは「111213」と入力すると、「11:12:13」と編集され、TimestampFieldは「20180410 160010」と入力すると、「2018/04/10 16:00:10」と編集するイベント処理が登録されています。
dataforms.jarには、複数の選択肢から1件を選択するSingleSelectFieldと、複数の選択肢を選択することができるMultiSelectFieldクラスが用意されています。これらのクラスはSingleSelectTestField.javaとMultiSelectTestField.javaのように、派生したクラスで選択肢を指定して使用します。SingleSelectFieldは<input type="radio" .../>または<select>...</select>に対応し、MultiSelectFieldは<input type="checkbox" .../>または<select multiple="multiple"></select>に対応します。これらのフィールドクラスはsetHtmlFieldTypeメソッドで、生成するHTMLタグを指定することができます。
ラジオボタンやチェックボックスが指定されたフィールドは、<span><input type="radio" id="radioField[0]" name="radioField"/></span> のように<span></span>で囲まれた<input ...>タグが1つだけ出力されています。「SingleSelectField.js」「MultiSelectField.js」の共通の親クラスである「SelectField.js」は、それぞれのJavaクラスで設定された選択肢を取得し、選択肢の数分のラジオボタンやチェックボックスを選択します。
ラジオボタンやチェックボックスに対応するタグの場合、idはfieldId[0]のように配列の形式で指定され、nameはfieldIdそのものが指定されています。SelectField.jsが選択肢を展開すると、下図のようになります。
プルダウンや複数選択リストボックスも、<select ...></select>のように選択肢が設定されていない状態で出力されています。この場合もSelectField.jsがjavaクラスで設定された選択肢を自動的に展開するようになっています。
MultiSelectFieldの場合、複数の値が選択可能です。そのため、送信されたデータをconvertToServerDataメソッドで変換すると、MultiSelectFieldに入力された値は配列に展開されます。
MultiSelectFieldに値を設定し、[送信]ボタンを押下すると、以下のようにログが出力され、checkboxFieldとmultiSelectFieldに対応する値が配列になっていることがわかります。
2018-05-01 22:05:46,062 DEBUG FieldTestForm - d={
"radioField":"1",
"timeField":null,
"dateField":null,
"timestampField":null,
"selectField":"0",
"checkboxField":["0","1"],
"multiSelectField":["0","1"],
"hogeFuga":""
}
