SHOEISHA iD

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

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

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

特集記事

dataforms.jar API解説――HtmlTableクラス

カラム固定機能

 業務システムを作っていると、テーブルに多くの項目を表示するケースがあります。そうすると画面に表示しきれずにスクロールさせることになります。この際に大抵出てくるのが「Excelのウインドウ枠の固定のように先頭の数カラムを固定し、残りもカラムのみ横スクロールさせたい」といった要望です。この場合、固定部ヘッダテーブル、スクロール部ヘッダテーブル、固定部データテーブル、スクロール部データテーブルの4つのテーブルを用意し、スクロール位置を同期させるスクリプトを作っていました。しかし、別のテーブルのカラム幅を合わせる必要が出てくるため面倒な実装になります。

 しかし最近、CSS3の"position: sticky;"が実装されたブラウザが出てきました。これを使えば1つのテーブルでカラム固定テーブルを実装することができます。

 そこで、HtmlTableクラスにsetFixedColumnsというメソッドを用意しました。以下のBlockScrollTableForm.javaの太字部分で左から4カラムを固定する設定を行っています。

BlockScrollTableForm.java
package pagesample.page;

import dataforms.controller.Form;
import dataforms.field.base.FieldList;
import dataforms.field.base.TextField;
import dataforms.field.sqltype.IntegerField;
import dataforms.field.sqltype.NumericField;
import dataforms.htmltable.EditableHtmlTable;

/**
 * ブロックスクロールテーブルを配置したフォーム。
 *
 */
public class BlockScrollTableForm extends Form {
  /**
   * コンストラクタ。
   */
  public BlockScrollTableForm() {
    super(null);
    FieldList flist = new FieldList();
    flist.addField(new TextField("text1")).setComment("テキスト1");
    flist.addField(new TextField("text2")).setComment("テキスト2");
    flist.addField(new TextField("text3")).setComment("テキスト3");
    flist.addField(new TextField("text4")).setComment("テキスト4");
    flist.addField(new TextField("text5")).setComment("テキスト5");
    flist.addField(new TextField("text6")).setComment("テキスト6");
    flist.addField(new TextField("text7")).setComment("テキスト7");
    flist.addField(new TextField("text8")).setComment("テキスト8");
    flist.addField(new TextField("text9")).setComment("テキスト9");
    flist.addField(new TextField("text10")).setComment("テキスト10");
    flist.addField(new IntegerField("integer1")).setComment("整数");
    flist.addField(new NumericField("numeric1", 10, 2)).setComment("数値");
    EditableHtmlTable table = new EditableHtmlTable("simpleTable", flist);
    table.setFixedColumns(4);
    this.addHtmlTable(table);
  }
}

 BlockScrollTableFormを配置したページを以下のように作成します。

BlockScrollTablePage.java
package pagesample.page;

import dataforms.app.page.base.BasePage;
import dataforms.dao.Dao;
import dataforms.dao.Table;


/**
 * ページクラス。
 */
public class BlockScrollTablePage extends BasePage {
  /**
   * コンストラクタ。
   */
  public BlockScrollTablePage() {
    this.addForm(new BlockScrollTableForm());
  }

  /**
   * Pageが配置されるパスを返します。
   *
   * @return Pageが配置されるパス。
   */
  public String getFunctionPath() {
    return "/pagesample";
  }

  ・・・ 中略 ・・・
}

 このページクラスからBlockScrollTablePage.htmlを自動生成します。固定カラム数が指定されたテーブルを生成した場合、各カラムの幅が自動的に設定されます。ただし、テーブルの高さの指定は行われないため、縦スクロールを使用する場合は以下の太字部分のようにテーブルの高さを指定します。カラムの幅はカラム名の文字数などから適当に決定するので、レイアウトに問題がある場合はhtmlを直接修正してください。固定カラム数を指定した場合、各カラムの幅の指定は必須になります。既にhtmlを生成した後固定カラム数を指定した場合、テーブル中のtdの幅を全て設定する必要があります。

BlockScrollTablePage.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title></title>
  </head>
  <body>
    <div id="mainDiv">
      <form id="blockScrollTableForm">
        <div class="formHeader">xxx</div>
        <table class="responsive">
          <tbody>
          </tbody>
        </table>
        <div class="hScrollDiv">
          <table id="simpleTable" class="editableTable" style="height: 300px;">
            <thead>
              <tr>
                <th colspan="2" nowrap>
                  
                </th>
                <th nowrap>
                  No.
                </th>
                <th>
                  テキスト1
                </th>
                <th>
                  テキスト2
                </th>
                <th>
                  テキスト3
                </th>
                <th>
                  テキスト4
                </th>
                <th>
                  テキスト5
                </th>
                <th>
                  テキスト6
                </th>
                <th>
                  テキスト7
                </th>
                <th>
                  テキスト8
                </th>
                <th>
                  テキスト9
                </th>
                <th>
                  テキスト10
                </th>
                <th>
                  整数
                </th>
                <th>
                  数値
                </th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td class="buttonColumn">
                  <input type="button" id="simpleTable[0].addButton" value="+"/>
                </td>
                <td class="buttonColumn">
                  <input type="button" id="simpleTable[0].deleteButton" value="-"/>
                </td>
                <td style="text-align: right;" class="rowno">
                  <span id="simpleTable[0].no"></span>
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text1" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text2" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text3" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text4" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text5" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text6" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text7" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text8" />
                </td>
                <td style="width: 98px;">
                  <input type="text" id="simpleTable[0].text9" />
                </td>
                <td style="width: 112px;">
                  <input type="text" id="simpleTable[0].text10" />
                </td>
                <td style="width: 56px;">
                  <input type="text" id="simpleTable[0].integer1" />
                </td>
                <td style="width: 56px;">
                  <input type="text" id="simpleTable[0].numeric1" />
                </td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <th class="buttonColumn">
                  <input type="button" id="simpleTable.addButton" value="+"/>
                </th>
                <th colspan="14">
                </th>
              </tr>
            </tfoot>
          </table>
        </div>
      </form>

    </div>
  </body>
</html>

 このページを表示し情報を入力してスクロールさせたのが下図になります。

ブロックスクロールテーブルの動作

 この機能はChromeやSafari、Firefoxの場合"position: sticky;"を利用するためスムーズに動作します。Microsoft Edgeは"position: sticky;"は実装されているのですが、ChromeやFirefoxと微妙に動作が異なるため、縦スクロール時のヘッダ位置の調整はJavaScriptで行っています。そのため縦スクロールの終了のタイミングで、ヘッダの位置が調整されます。IEは"position: sticky;"がサポートされていないので、全てスクリプトで各セルの位置調整を行っています。そのためスクロール終了のタイミングで各セルの位置調整が行われます。

さいごに

 今までの記事で、dataforms.jarの特徴であるJavaとJavaScriptクラスの連携について解説してきました。これらのクラスの構造を理解すると、開発ツールで作成したとりあえず動作するプログラムに対し、わずかな変更でさまざまな機能を追加することができます。

 これからのdataforms.jarの開発の予定ですが、Apache FOPを使用したPDFレポート機能の追加や、開発ツールの充実を予定しています。ぜひ試してみてください。

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

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10793 2018/06/14 14:00

イベント

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

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

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

メールバックナンバー