jQuery-ui Dialog 使い方

[ Javascript, CSSのセット ]

jQuery-ui と テーマのCSS をセットします。他のjQuery-uiプラグインでも同じ


  <!-- jQuery本体 -->
  <script type="text/javascript" src="Script/js/jquery-3.2.1.min.js"></script>
  <script type="text/javascript" src="Script/js/jquery-migrate-3.0.0.min.js"></script>

  <!-- jQuery-ui -->
  <script type="text/javascript" src="Script/js/jquery-ui-1.9.2.custom.min.js"></script>
  
  <!-- jQuery-ui themes -->
  <link rel="stylesheet" type="text/css" href="Script/css/jquery-ui-themes-1.8.23/themes/${themanm}/jquery-ui.css" charset="UTF-8"/>
  <link rel="stylesheet" type="text/css" href="Script/css/jquery-ui-themes-1.8.23/themes/${themanm}/jquery.ui.all.css" charset="UTF-8"/>

[ コード例 (表示)]

下のようなのを外出しのjsに記述

単純ダイアログ


/**
 * 汎用単純ダイアログ ボタンテキスト指定
 * @param {type} obj divのid
 * @param {type} title タイトル
 * @param {type} msg メッセージ
 * @param {type} btntxt ボタンのテキスト
 * @returns {undefined} なし
 */
function simpleDialog2(obj, title, msg, btntxt) {
  var btns = {};
  btns[btntxt] = function () {
    $(this).dialog("close");
  };
  $(obj).html(msg);
  $(obj).dialog({
    title: title,
    modal: false,
    buttons: btns
  });
}

YES/NO ダイアログ、サイズ指定付


/**
 * 汎用確認ダイアログ サイズ指定
 * @param {type} obj divのid
 * @param {type} title タイトル
 * @param {type} msg htmlメッセージ
 * @param {type} btntxt1 左ボタン
 * @param {type} btntxt2 右ボタン
 * @param {type} func Yesの場合の関数を参照渡し
 * @param {type} w 幅
 * @param {type} h 高さ
 * @returns {undefined} なし
 */
function confirmDialogWithWH(obj, title, msg, btntxt1, btntxt2, func, w, h) {

  var btns = {};
  btns[btntxt1] = function () {
    $(this).dialog("close");
    func();
  };
  btns[btntxt2] = function () {
    $(this).dialog("close");
  };
  $(obj).html(msg);
  $(obj).dialog({
    title: title,
    modal: false,
    width: w, height: h,
    open: function () {
      // フォーカスボタンのセット //
      $(this).siblings(".ui-dialog-buttonpane").find('button:eq(1)').focus();

    },
    buttons: btns
  });

}

[ コード例 (ページ) ]

YESで実行したい処理は、確認ダイアログ表示の前に入れる


 var exec = function () {
   // ここに処理を入れる //
 };
 
 // 確認を入れる //
 confirmDialogWithWH($('#alertdialog'), '経緯度解除確認',
         nm + '<br><br>' + cellcontent + '\n',
         'する', 'しない', exec, 350, 200);
[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

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

jQuery-ui Dialog について

ページで確認用ダイアログ、カスタムフォームなどを配置するための jQuery-ui のプラグインです。LightBoxと同じく、星の数ほどありますが、jQuery-ui 標準でシンプルなコードで済み、将来的不安がない事、業務アプリとしては、おしゃれなのは不要と判断し、採用してます。

本家 Home : https://jqueryui.com/dialog/

本家ドキュメント : http://api.jqueryui.com/dialog/

[ 画面例 ]

シングルボタン

マルチボタン

応用例 (ログインフォーム)

応用例 (テキストエリアの入力値送信)

応用例 (ファイルアップロード)

応用例 (登録フォーム)

jQuery-ui LightBox 使い方

公式ホーム

[ Javascript, CSSのセット ]


  <script type="text/javascript" src="Script/js/lightbox.js" charset="UTF-8"></script>
  <link rel='stylesheet' href='Script/css/lightbox.css' />

[ コード例 ]

リンクタグの属性に、rel=’lightbox[imagegroup]’ を入れることで、LightBox がアフェクトする


        // サムネイル画像読込完了した時 //
        loadComplete: function () {

          // ストレッチ画像とライトボックスリンク //
          var IMG_HTML = "<a href='%HSRC%' rel='lightbox[imagegroup]' target='new' class='stshide'>" +
                  "<Img src='%SRC%' width='200px' height='150px' style='object-fit: contain;'></img></a>";


          // 画像表示とライトボックスリンク //
          /* html を置換て、LightBoxのリンクに行けるようにする */
          imguri = 'tmpimages/' + thumbdir + '/' + $(this).text();
          imguriact = 'tmpimages/' + thumbdir + '/' + $(this).text().slice(2);

          html = IMG_HTML.replace('%SRC%', imguri).replace('%HSRC%', imguriact);
          $(this).html(html);

jQuery-ui LightBox について

サムネイル画像とかで、クリックすると画像がふわっと現れるようにする、jQuery-uiのプラグインです。
同様のプラグインは他にも、星の数ほどありますが、特に画像を販売目的で使うわけでないので、落ち着いてシンプルな仕様のLightBoxを採用しています。

本家 Home : https://lokeshdhakar.com/projects/lightbox2/

説明ページ : https://kigiroku.com/frontend/lightbox.html

[ 画面例 ]

MultipleSelect 使い方 (4) Java

大まかな流れとしては、

  1. サーブレットで各マルチセレクト条件値CSVテキストをリクエストパラメータで受信
  2. サーブレットで、1.がnullであるか判別してフラグにして、操作用クラスにセットする
  3. マルチセレクト条件値CSVテキストは、リストにして操作用クラスにセットする
  4. 操作用クラスの検索処理メソッドで、最初にセットされた項目別フラグがtrueの場合、一時テーブルの削除追加を行う
  5. MyBatisの指定idの検索SQLを実行する際に、フラグがtrueの場合、一時テーブルをジョインしたSQL、falseの場合ジョインしないSQLを実行

となります。

MultipleSelect 使い方 (3) MyBatis SQL

検索条件を各項目の一時テーブルに入れて、ジョインするかしないかは、パラメータで指示してます。

[ SQL例 ]


 <!-- 船スペックマスタリスト --> 
 <!-- 使用 -->
  <select id="selVesselSpecList2" parameterType="ParamVesselSpec" resultType="VesselSpec">
    select * from (
		select
			v.ukfld as id, v.ukfld as imo,
			
			v.Name as vessel, 
      coalesce(fc_acc6m(v.Name), '') as acc6m,
    
			coalesce(en.cnt_en, 0) as cnt_en, 
      coalesce(`in`.cnt_in, 0) as cnt_in,     
			coalesce(eo.cnt_eo, 0) as cnt_eo, 			
			coalesce(io.cnt_io, 0) as cnt_io, 
      coalesce(ua.cnt_ua, 0) as cnt_ua, 
			
			v.TEU, v.`Year`, v.Speed, v.GrossT, v.DeadW, v.`call`, v.Cntry,  
		
			v.tm_add, v.tm_updt, 
			greatest(v.tm_add, v.tm_updt, coalesce(mt.TM_ADD, '2000-01-01 00:00:00')) as tm_lastupdt,
		
			v.is_manadd,
    
      coalesce(mt.LENGTH_OVERALL, 0) as `length`,
			coalesce(mt.BREADTH_EXTREME, 0) as width,
			coalesce(mt.DRAUGHT, 0) as draught,
    
      coalesce(round(mt.LENGTH_OVERALL, 0), 0) as `length_int`,
			coalesce(round(mt.BREADTH_EXTREME, 0), 0) as width_int,
			coalesce(round(mt.DRAUGHT, 0), 0) as draught_int,
    
			COALESCE(mt.LIQUID_OIL, 0) AS liquid_oil,
			COALESCE(mt.FUEL_CONSUMPTION, '') AS fuel_consumption,
			COALESCE(mt.OWNER, '') AS owner,			
			COALESCE(mt.MANAGER, '') AS manager,
			COALESCE(mt.MANAGER_OWNER, '') AS manager_owner    
			
			
		from 
			vessel2 v
    
      left outer join vessel_mt mt on (v.ukfld = mt.IMO) 
    
      <if test="!isTEUselAll">
        inner join tmp_imo_teu tt on (
        v.ukfld = tt.IMO and tt.ID_SESSION = #{idSession} and tt.NM_GRID = 'specs' 
        )
      </if>
      <if test="!isYearselAll">
        inner join tmp_imo_year yt on (
        v.ukfld = yt.IMO and yt.ID_SESSION = #{idSession} and yt.NM_GRID = 'specs' 
        )        
      </if>
      <if test="!isSpeedselAll">
        inner join tmp_imo_speed st on (
        v.ukfld = st.IMO and st.ID_SESSION = #{idSession} and st.NM_GRID = 'specs' 
        )        
      </if>
      
      <if test="!isLengthselAll">
        inner join tmp_imo_length lg on (
        mt.IMO = lg.IMO and lg.ID_SESSION = #{idSession} and lg.NM_GRID = 'specs' 
        )        
      </if>
      <if test="!isWidthselAll">
        inner join tmp_imo_width wd on (
        mt.IMO = wd.IMO and wd.ID_SESSION = #{idSession} and wd.NM_GRID = 'specs' 
        )        
      </if>
      <if test="!isDraughtselAll">
        inner join tmp_imo_draught dr on (
        mt.IMO = dr.IMO and dr.ID_SESSION = #{idSession} and dr.NM_GRID = 'specs' 
        )        
      </if>
      
    
			left outer join (
			select imo, count(*) as cnt_en from sch_export_source group by imo
			) en 
			on (v.ukfld = en.imo)
			
			left outer join (
			select imo, count(*) as cnt_in from sch_import_source group by imo
			) `in` 
			on (v.ukfld = `in`.imo)
		      
      left outer join (
			select imo, count(*) as cnt_eo from sch_export_source_old group by imo
			) eo 
			on (v.ukfld = eo.imo)
      
      left outer join (
			select imo, count(*) as cnt_io from sch_import_source_old group by imo
			) io 
			on (v.ukfld = io.imo)    
      
			left outer join (
			select u.vessel, count(u.id) as cnt_ua from sch_useradd u group by vessel
			) ua on (v.Name = ua.vessel)             
      
    where 
      1 = 1 and v.Name like concat('%', #{vsllk}, '%') and
      ukfld like concat('%', #{imolk}, '%')
      <if test="isModOnly">
        and is_manadd = 1
      </if>
    ) a
    order by
      ${sidx} ${sord}  
    limit ${skip}, ${pgrec}  
  </select>

[ 使っているテーブル ]

船マスタ


CREATE TABLE `vessel2` (
	`Name` VARCHAR(36) NOT NULL DEFAULT '' COMMENT '船名',
	`call` VARCHAR(9) NOT NULL DEFAULT '' COMMENT '無線局呼出符号',
	`Year` SMALLINT(6) NOT NULL DEFAULT '0' COMMENT '建造年',
	`Speed` FLOAT NOT NULL DEFAULT '0' COMMENT '速力',
	`TEU` SMALLINT(6) NOT NULL DEFAULT '0' COMMENT '積載TEU',
	`GrossT` INT(11) NOT NULL DEFAULT '0' COMMENT 'グロス重量',
	`DeadW` INT(11) NOT NULL DEFAULT '0' COMMENT '重量重量',
	`Cntry` VARCHAR(2) NOT NULL DEFAULT '' COMMENT '船籍国コード',
	`ukfld` INT(11) NOT NULL DEFAULT '0' COMMENT 'IMOコード',
	`tm_add` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '追加時刻',
	`tm_updt` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00' COMMENT '最終更新時刻',
	`is_manadd` TINYINT(4) NOT NULL DEFAULT '0' COMMENT 'ユーザー更新フラグ',
	`ChgName` VARCHAR(36) NOT NULL DEFAULT '0' COMMENT '参照結合用変換船名',
	PRIMARY KEY (`ukfld`),
	INDEX `vessel2_Name` (`Name`),
	INDEX `vessel2_ChgName` (`ChgName`)
)
COMMENT='船マスタ (利用)'
COLLATE='utf8_general_ci'
ENGINE=MyISAM

一時テーブル (一部)

・ID_SESSION はTomcatのセッションIDでユーザー別
・ほっておくと肥大するので、夜中に全レコード削除


CREATE TABLE `tmp_imo_teu` (
	`ID` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'シーケンス番号',
	`ID_SESSION` VARCHAR(70) NOT NULL DEFAULT '' COMMENT 'WEBサーバーセッションID',
	`NM_GRID` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'jqGridグリッドID',
	`IMO` INT(11) NOT NULL DEFAULT '0' COMMENT 'IMOコード',
	`TM_ADD` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '追加時刻',
	PRIMARY KEY (`ID`),
	INDEX `tmp_imo_ID_SESSION` (`ID_SESSION`),
	INDEX `tmp_imo_NM_GRID` (`NM_GRID`),
	INDEX `tmp_imo_IMO` (`IMO`)
)
COMMENT='船スペック検索用IMO一時テーブル'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=5627
;

CREATE TABLE `tmp_imo_year` (
	`ID` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'シーケンス番号',
	`ID_SESSION` VARCHAR(70) NOT NULL DEFAULT '' COMMENT 'WEBサーバーセッションID',
	`NM_GRID` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'jqGridグリッドID',
	`IMO` INT(11) NOT NULL DEFAULT '0' COMMENT 'IMOコード',
	`TM_ADD` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '追加時刻',
	PRIMARY KEY (`ID`),
	INDEX `tmp_imo_ID_SESSION` (`ID_SESSION`),
	INDEX `tmp_imo_NM_GRID` (`NM_GRID`),
	INDEX `tmp_imo_IMO` (`IMO`)
)
COMMENT='船スペック検索用IMO一時テーブル'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

[ 一時テーブル削除追加用SQL ]

・テーブル名を ${tmptbl} のパラメータで渡すことで、まとめてます。


 <!-- マルチセレクト用一時テーブル更新 -->
 <!-- 削除 -->
 <delete id="delIMOTmpAll" parameterType="MyBatisParent">
   delete from ${tmptbl} where ID_SESSION = #{idSession} and NM_GRID = #{nmGrid}
 </delete>
 <!-- 追加 -->
 <insert id="insAIMOTmp" parameterType="MyBatisParent">
   insert into ${tmptbl}
   (ID_SESSION, NM_GRID, IMO)
   select #{idSession}, #{nmGrid}, 
   ukfld
   from ${vslmsttbl}
   where ${vslColumn} between #{insMinVal} and #{insMaxVal}
 </insert>
 <insert id="insAIMOTmpmt" parameterType="MyBatisParent">
   insert into ${tmptbl}
   (ID_SESSION, NM_GRID, IMO)
   select #{idSession}, #{nmGrid}, IMO
   from ${vslmsttbl}
   where ${vslColumn} between #{insMinVal} and #{insMaxVal}
 </insert>

MultipleSelect 使い方 (2) Javascript の設定

[ js, cssのセット ]


    <!-- MultipleSelect -->
    <script type="text/javascript" src="Script/jquery.multiple.select.js"></script>
    <link rel='stylesheet' href='CSS/multiple-select.css' />

[ コードサンプル ]


      // マルチセレクト全選択数用 //
      /* この変数は、外のfunctionで使うのでload前	 :/
      var teuselAllCnt;
      var yearselAllCnt;
      var speedselAllCnt;
      var lengthselAllCnt;
      var widthselAllCnt;
      var draughtselAllCnt;

        
        // マルチプルセレクト //
        $('#teusel, #yearsel, #speedsel, #lengthsel, #widthsel, #draughtsel').multipleSelect({
          //$('#filesel, #sheetsel, #suplsel, #psnsel').multipleSelect({
          allSelected: 'All',
          //height: '500px'
        });

        // 全選択して項目数を調べる //
        $('#teusel').multipleSelect('checkAll');
        $('#yearsel').multipleSelect('checkAll');
        $('#speedsel').multipleSelect('checkAll');
        $('#lengthsel').multipleSelect('checkAll');
        $('#widthsel').multipleSelect('checkAll');
        $('#draughtsel').multipleSelect('checkAll');

        teuselAllCnt = $('#teusel').multipleSelect('getSelects', 'value').length;
        yearselAllCnt = $('#yearsel').multipleSelect('getSelects', 'value').length;
        speedselAllCnt = $('#speedsel').multipleSelect('getSelects', 'value').length;
        lengthselAllCnt = $('#lengthsel').multipleSelect('getSelects', 'value').length;
        widthselAllCnt = $('#widthsel').multipleSelect('getSelects', 'value').length;
        draughtselAllCnt = $('#draughtsel').multipleSelect('getSelects', 'value').length;


/****** ロード時は常に全選択状態なので、全選択フラグを全部オンにする */

        // **** 船スペックグリッド **** //
        $("#specs").jqGrid({
          url: "GetVesselSpecList",
          //editurl: "paramCheck",
          editurl: "UpdateAVesselSpec",
          mtype: 'post',
          datatype: "json",
          serializeGridData: function (postData) {
            //postData['mindt'] = '2017-12-01';
            //postData['idsql'] = 'selDailyBatchLogList';
            postData['vsllk'] = vsllklast;
            postData['imolk'] = imolklast;
            postData['isTEUSelAll'] = '1';
            postData['isYearSelAll'] = '1';
            postData['isSpeedSelAll'] = '1';
            postData['isLengthSelAll'] = '1';
            postData['isWidthSelAll'] = '1';
            postData['isDraughtSelAll'] = '1';
            postData['teuselext'] = "";
            postData['yearselext'] = "";
            postData['speedselext'] = "";
            postData['lengthselext'] = "";
            postData['widthselext'] = "";
            postData['draughtselext'] = "";
            postData['isModOnly'] = '0';

            //postData['rows'] = rownum; 
            return postData;
          },

/*************************************************************/
	
        // == フィルターボタンを押した時 == //
        $('#fltbtn').on('click', function () {

          var teuselcnt = $('#teusel').multipleSelect('getSelects', 'value').length;
          var yearselcnt = $('#yearsel').multipleSelect('getSelects', 'value').length;
          var speedselcnt = $('#speedsel').multipleSelect('getSelects', 'value').length;
          var lengthselcnt = $('#lengthsel').multipleSelect('getSelects', 'value').length;
          var widthselcnt = $('#widthsel').multipleSelect('getSelects', 'value').length;
          var draughtselcnt = $('#draughtsel').multipleSelect('getSelects', 'value').length;

          // グリッドの更新 //
          $('#specs').jqGrid('setGridParam', {
            page: 1,
            serializeGridData: function (postData) {
              
              // 単純なので、JSONにしないで配列文字列にして送信 //
              /* 最後に "" を必ずつける */
              postData['teuselext'] = $('#teusel').multipleSelect("getSelects", "value") + "";
              postData['yearselext'] = $('#yearsel').multipleSelect("getSelects", "value") + "";
              postData['speedselext'] = $('#speedsel').multipleSelect("getSelects", "value") + "";
              postData['lengthselext'] = $('#lengthsel').multipleSelect("getSelects", "value") + "";
              postData['widthselext'] = $('#widthsel').multipleSelect("getSelects", "value") + "";
              postData['draughtselext'] = $('#draughtsel').multipleSelect("getSelects", "value") + "";

              // 全選択 or Not を送信用 //
              postData['isTEUSelAll'] = teuselcnt == teuselAllCnt ? '1' : '0';
              postData['isYearSelAll'] = yearselcnt == yearselAllCnt ? '1' : '0';
              postData['isSpeedSelAll'] = speedselcnt == speedselAllCnt ? '1' : '0';
              postData['isLengthSelAll'] = lengthselcnt == lengthselAllCnt ? '1' : '0';
              postData['isWidthSelAll'] = widthselcnt == widthselAllCnt ? '1' : '0';
              postData['isDraughtSelAll'] = draughtselcnt == draughtselAllCnt ? '1' : '0';

              postData['vsllk'] = $('#nameinp').val();
              postData['imolk'] = $('#imoinp').val();
              return postData;
            }
          }).trigger('reloadGrid');

          // ローカルストレージに保存 //
          // これは使ってないが、今後の為 //
          if (localStorage) {
            var savemap = {};
            savemap['teuselext'] = $('#teusel').multipleSelect("getSelects", "value");
            savemap['yearselext'] = $('#yearsel').multipleSelect("getSelects", "value");
            savemap['speedselext'] = $('#speedsel').multipleSelect("getSelects", "value");
            savemap['lengthselext'] = $('#lengthsel').multipleSelect("getSelects", "value");
            savemap['widthselext'] = $('#widthsel').multipleSelect("getSelects", "value");
            savemap['draughtselext'] = $('#draughtsel').multipleSelect("getSelects", "value");
            savemap['vsllk'] = $('#nameinp').val();
            savemap['imolk'] = $('#imoinp').val();
            localStorage.setItem('vesselsch_specs_filter', JSON.stringify(savemap));
          }

        });

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未適用) ]

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時点)