SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

dataforms.jar API解説――フィールドクラスとHTMLタグの関係

各種フィールドクラスとHTMLタグの関係

 「dataforms.jar API解説――Fromクラスのクライアント、サーバ間の通信」で使用したプロジェクトに 新たなページ(FieldTestPage)を作成します。「SingleSelectTestField.java」「MultiSelectTestField.java」「FieldTestForm.java」は全てコーディングしますが、「FieldTestPage.java」「FieldTestPage.html」「FieldTestForm.js」は開発ツールで生成し、太字部分を追記したものです。作成の手順は以前の記事を参照してください。

FieldTestPage.java
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;
  }

}

FieldTestForm.java
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;
  }
}
SingleSelectTestField.java
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);
  }
}
MultiSelectTestField.java
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);
  }
}
    
FieldTestPage.html
<!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>

FieldTestForm.js
/**
 * @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));
  });
};    

 このページを表示すると下図のようになります。

FieldTestPageの表示結果

 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を編集してください。

hogeFugaフィールドの検証結果

 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":""
}

次のページ
数値フィールドクラス

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

高柳 正彦(タカヤナギ マサヒコ)

経験年数30年を超えた、システムエンジニアです。一応管理職のはずですが、未だにコードを書いています。この仕事を長々とやっていると、それなりにノウハウがたまってきます。そのノウハウをまとめたものができないかと思い、独自のフレームワークを作り始めました。そのフレームワークもそれなりに使えるようになってき...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10783 2018/05/15 17:58

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー