MultipleSelect 使い方 (1) リスト用アイテムの用意

MultipleSelect を使うと、エクセルのフィルターのような、複数アイテムの指定による検索が可能となり、検索機能が大幅に向上します。

[ 設置画面例 ]

[ アイテム用SQL例 ]

グループ化した各範囲値を結果レコードにする。concatで区切った左がselectタグのvalue、右がテキスト


 <!-- 船スペックフィルター用 -->
 <select id="selTEU1000CmbList" resultType="String">
		/* TEU 1000 */
		
		select
			concat(
			concat(truncate(v.TEU, -3), '-',truncate(v.TEU, -3) + 999), ',',
			concat(cast(truncate(v.TEU, -3) as char), ' - ',
			cast(truncate(v.TEU, -3) + 999 as char), ' X ', count(Name))
			)
		from
			vessel2 v
		group by
			truncate(v.TEU, -3)
 </select>
 <select id="selYear5CmbList" resultType="String">		
		/* Year 5 */
		
		select
			concat(
			concat(min(v.Year), '-', max(v.year)), ',',
			cast(concat(min(v.Year), ' - ', max(v.year)) as char), ' X ', count(Name)
			)
		from
			vessel2 v
		group by
			floor(v.Year / 5);
	</select>

[ SQL実行結果例 ]

0-999,0 – 999 X 545
1000-1999,1000 – 1999 X 411
2000-2999,2000 – 2999 X 165
3000-3999,3000 – 3999 X 67
4000-4999,4000 – 4999 X 287
5000-5999,5000 – 5999 X 154
6000-6999,6000 – 6999 X 118
7000-7999,7000 – 7999 X 28
8000-8999,8000 – 8999 X 229
9000-9999,9000 – 9999 X 135
10000-10999,10000 – 10999 X 83
11000-11999,11000 – 11999 X 38
12000-12999,12000 – 12999 X 14
13000-13999,13000 – 13999 X 140
14000-14999,14000 – 14999 X 78
15000-15999,15000 – 15999 X 19
16000-16999,16000 – 16999 X 9
17000-17999,17000 – 17999 X 6
18000-18999,18000 – 18999 X 26
19000-19999,19000 – 19999 X 29
20000-20999,20000 – 20999 X 31
21000-21999,21000 – 21999 X 8

[ selectタグ例 (multiple未適用) ]

MySQL information_schema の活用 テーブルステータス

information_schema にある TABLES から現在の状態を取得できます。

下のようなビューを使って、わかりやすくしてます。


CREATE 
    ALGORITHM = UNDEFINED 
    DEFINER = `root`@`localhost` 
    SQL SECURITY DEFINER
VIEW `vw_simple_table_schema` AS
    SELECT 
        `information_schema`.`tables`.`TABLE_NAME` AS `Name`,
        `information_schema`.`tables`.`TABLE_COMMENT` AS `Comment`,
        `information_schema`.`tables`.`TABLE_ROWS` AS `Rows`,
        (FLOOR((`information_schema`.`tables`.`DATA_LENGTH` / 1024)) + FLOOR((`information_schema`.`tables`.`INDEX_LENGTH` / 1024))) AS `total_length_k`,
        FLOOR((`information_schema`.`tables`.`DATA_LENGTH` / 1024)) AS `Data_length_k`,
        FLOOR((`information_schema`.`tables`.`INDEX_LENGTH` / 1024)) AS `index_length_k`,
        `information_schema`.`tables`.`CREATE_TIME` AS `Create_time`
    FROM
        `information_schema`.`tables`
    WHERE
        (`information_schema`.`tables`.`TABLE_SCHEMA` = 'ocean2')
    ORDER BY `information_schema`.`tables`.`TABLE_ROWS` DESC

各アプリケーションの管理人用ページに、下のような表を配置してます。

jqGrid セルのコンテキストメニュー

[ Javascript, CSSのセット ]


    <!-- ContextMenu -->
    <script type="text/javascript" src="Script/js/jquery.contextmenu.r2.js" charset="UTF-8"></script>
    <link rel="stylesheet" type="text/css" src="Script/css/contextmenu.css" charset="UTF-8" />

[ contextMenuのセット ]


      <!--  Another Photos, Get Another details のコンテキストメニュー -->
      <div class="contextMenu" id="cntxtidphotos">
        <ul>
          <li id="mtphotos">
            <img src="Img/mt.png"/>
            Open Another Photos
          </li>

          <li id="mtdtlapi">
            <img src="Img/mt.png"/>
            Get detailed spec from MT
          </li>
        </ul>       
      </div>

[ コード例 ]

loadCompleteで、行走査して各行の指定位置セルに設定


          var rowId;

            $.each(rows, function (i) { 


             // === 写真ページ用コンテキストメニュー === //
              $('#' + rows[i]['id']).children('td').eq(0).contextMenu('cntxtidphotos', {
                menuStyle: {width: '200px'},
                bindings: {
                  'mtphotos': function (t) {
                    var url = PHOTOS_URL + rowId;
                    // ページフィルターログ書込み //
                    $.post("paramCheck", {});
                    window.open(url);
                  },
                  'mtdtlapi': function (t) {

                    $.ajax({
                      url: "ReqUpdtAvesselSpecMTGroovy",
                      type: "POST",
                      dataType: "json",
                      async: false,
                      data: {imo: rowId},
                      success: function (res) {

                        // リフレッシュを発生 //
                        $('#refresh_specs').click();

                      },
                    });

                  },
                },
                // これでpublicな変数が不要 //
                onContextMenu: function (event, menu) {
                  rowId = $(event.target).parent("tr").attr("id");  // = imo
                  var grid = $("#jqGrid");
                  grid.setSelection(rowId);   // 行を選ばせる
                  return true;
                }
              });

[ 画面例 ]

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

jQuery最高の教科書 [ シフトブレイン ]
価格:2838円(税込、送料無料) (2023/1/16時点)

jqGrid フッター、ヘッダーに集計値表示

[ フッター配置例 ]

[ ヘッダー配置例 ]

[ jqGrid コード例 ]

デフォルトはフッター
footerrow, userDataOnFooter を true にする


footerrow: true,
userDataOnFooter: true,

ヘッダーにしたい時は、gridComplete で DOM操作して明細行と合計行の位置を入れ替える


  // フッター合計を上にする, 境界線スタイルを変える //
  var dtlobj = $('#gview_asivlist').children('div').eq(3);   // 明細行
  var fttlobj = $('#gview_asivlist').children('div').eq(4);  // 合計行
  $(fttlobj).css({
    "border-bottom-style": "solid",
    "border-bottom-color": '#008600',
    "border-bottom-width": "2px"
  }).insertBefore($(dtlobj));

[ Servlet コード例 ]

集計値用マップ


    // +++ 結果メッセージ用 +++ //
    HashMap<String, String> usrdata = new HashMap<String, String>();

検索後、集計値を格納


  /**
   * テーブルスキーマ情報取得
   *
   * @param usrdata 合計値マップ
   * @return テーブルスキーマ型リスト
   */
  public ArrayList<TableSchema> getTableSchemaList(HashMap<String, String> usrdata) {

    List list = null;
    try (SqlSession session = sqlSessionFactory.openSession()) {

      list = session.selectList("selTableSchemaList", this);
      System.out.println("getTableSchemaList ():" + list.size());

      // フッター用 //
      // ストリームで合計を格納 //
      ArrayList<TableSchema> slist = new ArrayList(list);
      int cntRow = (int)slist.stream().count();    // 件数 long なので intにキャスト     
      int colTotal = slist.stream().mapToInt(v -> v.getCntCol()).sum();     // 列数
      int rowTotal = slist.stream().mapToInt(v -> v.getCntRow()).sum();     // 行数
      int totalTotal = slist.stream().mapToInt(v -> v.getLenTotal()).sum(); // 合計サイズ
      int dataTotal = slist.stream().mapToInt(v -> v.getLenData()).sum();   // データサイズ
      int indexTotal = slist.stream().mapToInt(v -> v.getLenIndex()).sum(); // インデックスサイズ
      
      // HashMapに追加 //
      usrdata.put("cntCol", String.valueOf(colTotal));
      usrdata.put("cntRow", String.valueOf(rowTotal));
      usrdata.put("lenTotal", String.valueOf(totalTotal));
      usrdata.put("lenData", String.valueOf(dataTotal));
      usrdata.put("lenIndex", String.valueOf(indexTotal));
      usrdata.put("comment", "    Total " + String.valueOf(cntRow) + " Tables" );
      
    }
    catch (Exception se) {
      se.printStackTrace();
    }
    return new ArrayList(list);

  }

応答JSONのセット


    // +++ 結果返却用 +++ //
    JSONResultGrid loggrid = new JSONResultGrid();
    loggrid.setPage(1);
    loggrid.setTotal(1);
    loggrid.setRows(loglist);
    loggrid.setUserdata(usrdata);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String gsonstr = gson.toJson(loggrid);

応答データ


  "userdata": {
    "cntRow": "27494440",
    "lenTotal": "4135942",
    "cntCol": "1689",
    "lenData": "2479938",
    "comment": "    Total 173 Tables",
    "lenIndex": "1656004",
    "sidx": "1"
  }

jqGrid タイトルセルに画像を配置

タイトル行の各thタグの id は、gridのid + “_” + colModelのnameプロパティ になっていて、textはcolNames配列の値となってますので、idを指定して、html を置き換えれば出来ます。

[ コード例 ]


// 国旗スパン //
var FLAG_SPAN = '<span><img src="Img/flag/TH.gif" /><span style="margin-left:4px;">HSCD</span></span>';

// HSCDに国旗をつける //
$('#' + $(this).attr('id') + '_cdHST').html(FLAG_SPAN);

[ 画面例 ]

運航港地図 と 施設港地図

googleMap利用の港地図です。

< リンク >

施設港地図

運航港地図

< 画面絵 >

運航港地図

施設港地図

< ご利用上の注意 >

運航港地図を船舶運航業務等で利用された結果生ずる、いかなる有形無形の損害については、開発者は一切の責任を負わないこととします。

データ内容につきましては、出来る限り最新の状況に追従させてますが、間に合わないこともあり、ご容赦下さい。

ケータイ用インドネシア語辞書

昔、インドネシア語を勉強してた時期があり、ふさわしい電子辞書がないので、自作しました。
国内でインドネシア語を勉強してる人、日本人インドネシア駐在員の方々、在日インドネシア人の人達にご好評で、一時期、多数のアクセスがありましたが、最近はガラケー利用者が少ないのか、時代遅れなのか、過疎な状態です。

URL : 2020年3月リニューアルしました

特徴としては、

1) 印 => 日 検索で、ローマ字が出る
2) 日 => 印 検索で、ひらがな、ローマ字が使える
3) 検索結果を一時的に記憶して、一覧で見れる

だけです。

上画面例訳語を見て、初めて知った言葉、polisi tidur は、警察 : 睡眠 が日本語訳になり、面白い表現で少し笑えます。

辞書データは下サイトの運営者作成のを、使わせて頂いてます。

http://www.geocities.jp/indo_ka/bahasa/id_soft.htm

JAVA 改良版 クラス指定デバッグ出力メソッド (JSON)

デバッグする時、NetBeansのデバッグで止めてチェックしたりするのが、じゃまくさく、時間かかるので、止めてみて終了させる必要ない場合用に、System.out.println() で見れるようにしてます。

昔作った、obj.getClass().getDeclaredFields()でのループ型で配列がとれない欠点があり、JSON出力にしてます。
null, getterのないフィールドがとれない欠点がありますが、PHPの var_dump() みたいなこと出来て便利です。

[ 出力例 ]


===============================
Time : 2019-01-08 19:16:29.204
Class : vesselsch.Polygon
Comment : ポリゴン追加
-------------------------------
{
  "lats": [
    35.68114829375634,
    35.680799702175534,
    35.6783595184685,
    35.67561015535696,
    35.67561015535696,
    35.67700460322533,
    35.677771539167104,
    35.678956789306746,
    35.679026509354955,
    35.68114829375634,
    35.68114829375634
  ],
  "lons": [
    139.97815035776364,
    139.98261355356442,
    139.98287104562985,
    139.98201273874508,
    139.9794378180908,
    139.97892283395993,
    139.9801244635986,
    139.9801244635986,
    139.97840784982907,
    139.97815035776364,
    139.97815035776364
  ],
  "id_poly": 0,
  "nm_poly": "1916",
  "cd_unlo": "JPFNB",
  "tp_poly": "CY",
  "nm_route": "",
  "cnt_corner": 0,
  "latmid": 0.0,
  "lonmid": 0.0,
  "m_depth": 0.0
}

[ コード例 ]


      // JSONデコードはリフレクションで行う //  
      Polygon PL = new Polygon();
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      Type type = new TypeToken<Polygon>() {
      }.getType();
      PL = gson.fromJson(jsn, type);
      // デバッグ出力 //
      FieldValuePrint fvp = new FieldValuePrint(PL, "ポリゴン追加");

[ 出力用クラス ]


package vesselsch;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang.time.DateFormatUtils;

/**
 * 指定クラスJSON出力
 * @author 田中尚
 */
public class FieldValuePrint {
  
  private Object obj;
  private String comment;
  
  /**
   * 引数付コンストラクタ
   * @param obj クラスオブジェクト 
   */
  public FieldValuePrint(Object obj) {  
    this.obj = obj;
    this.printToJSON();
  }
  
  /**
   * 引数付コンストラクタ
   * @param obj クラスオブジェクト
   * @param comment コメント
   */
  public FieldValuePrint(Object obj, String comment) {  
    this.obj = obj;
    this.comment = comment;
    this.printToJSON();
  }
  
  /**
   * クラスのフィールド名、フィールド値一覧チェック出力
   *
   */
  public void printToJSON() {

    // JSON出力 //
    Gson gsondbg = new GsonBuilder().setPrettyPrinting().create();
    System.out.println("===============================");
    System.out.println("Time : " + DateFormatUtils.format(new java.util.Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
    System.out.println("Class : " + this.obj.getClass().getCanonicalName());
    if (this.comment != null) {
      System.out.println("Comment : " + this.comment);
    }
    System.out.println("-------------------------------");
    System.out.println(gsondbg.toJson(this.obj));

  }

}

[ 送信データ画面例 ]

JAVA クラス指定デバッグ出力メソッド

デバッグする時、NetBeansのデバッグで止めてチェックしたりするのが、じゃまくさく、時間かかるので、止めてみて終了させる必要ない場合用に、System.out.println() で見れるようにしてます。

[ 出力例 ]

===============================
Class : vesselsch.Polygon
——————————-
lats : [D@de31cc6
lons : [D@2cdf0ade
polynm : null
latsList : null
lonsList : null
id_poly : 0
nm_poly : 謎の海域ふな
cd_unlo : JPFNB
tp_poly : OT
nm_route :
cnt_corner : 0
latmid : 0.0
lonmid : 0.0
m_depth : 0.0
===============================

配列型がとれてないので、改良予定

[ クラス例 ]


package vesselsch;

import java.util.ArrayList;
import java.util.Arrays;


/**
 * GoogleMap 多角形型
 * @author 田中尚
 */
public class Polygon {
  
  private double[] lats;      // 座標緯度
  private double[] lons;      // 座標経度
  private String polynm;
  
  private ArrayList<Double> latsList = null;    // 未使用
  private ArrayList<Double> lonsList = null;    // 未使用
  
  private int id_poly;
  private String nm_poly;
  private String cd_unlo;
  private String tp_poly;
  private String nm_route;
  
  private short cnt_corner;
  private double latmid;
  private double lonmid;
  
  private float m_depth;       // 水深

[ 埋め込み例 ]

JSONリクエストのセット状況


    // JSONデコードはリフレクションで行う // 
    PolygonDtl POD = new PolygonDtl();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    Type type = new TypeToken<PolygonDtl>() {
    }.getType();
    POD = gson.fromJson(jsn, type);

    // Javascriptで"が消せないので //
    //POD.setCd_facil(POD.getCd_facil().replaceAll("\"", ""));
    if (POD.getCd_facil() != null) {
      if (POD.getCd_facil().equals("")) {
        POD.setCd_facil("ZZZZZ");
      }
      else {
        POD.setCd_facil(POD.getCd_facil().substring(0, 5));
      }
    }

    // -- debug
    MyBatisParent mb = new MyBatisParent();
    mb.printFieldValueList(POD);