MySQL 日付指定年齢関数

誕生年月日を渡せば、今日の年齢を返します。


CREATE DEFINER=`root`@`localhost` FUNCTION `fc_age_by_birthdate`(
	`bdate` date

)
RETURNS int(11)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '日付値指定年齢取得スカラー関数'
begin
  declare agetoday int;
  select year(current_date) - year(bdate) - (right(current_date, 5) < right(bdate, 5)) into agetoday;
  return agetoday;
  
end

DATE型値をキャストなしで部分文字列取得できます。

下は今日以外を指定した年齢取得


CREATE DEFINER=`root`@`localhost` FUNCTION `fc_age_by_birthdate_tgtdt`(
	`bdate` date,
	`tgtdt` date
)
RETURNS int(11)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '日付値指定年齢取得スカラー関数'
begin
  declare agetoday int;
  select year(tgtdt) - year(bdate) - (right(tgtdt, 5) < right(bdate, 5)) into agetoday;
  return agetoday;
  
end

[ 利用場面 ]

jqGrid インライン編集 extraparamのセット

最近、やっとわかったこととして、編集列として設定してないデータを更新用として送信する場合、以前は id に文字列表現したり、隠し列設定したりして、目的は達成できるものの、列が増えたりして、ややこしいプログラムになったりしてました。

editParams , addParams の中に extraparam をセットすれば、すっきりわかりやすくなります。

[ コード例 ]


// -- 編集 -- // 
editParams: {

  extraparam: {
    idUser: function () {
      return userid;
    }
  },
// -- 追加 -- //
addParams: {

  addRowParams: {
    extraparam: {
      cdJan: function () {
        return subgrid_table_id.split("_")[1];
      },
      idUser: function () {
        return userid;
      }
    },

編集送信データ例
idUser の列はないが、ちゃんと送信されたのがわかる

画面例

jqGrid 罫線 フォント色の動的設定

 

 

 

 

固定的に列のフォント色なんかを設定したい場合は、colModel の classes に CSSのクラス名なんかを設定しておけば、コーディングする必要ないですが、

動的なことする場合は、loadComplete で DOMのCSS設定したりします。

[ サンプルコード ]


// == グリッドデータ取得 == //
var rows = $(this).getRowData();

// == userdata取得 == //
var userdata = $(this).jqGrid('getGridParam', 'userData');

// 区切線用 //
var ulineidxary = [];

if (userdata['sidx'] == 'dceta' || userdata['sidx'] == 'vessel' || userdata['sidx'] == 'berth') {
  var rowsary = $(this).getRowData();
  var wcntary = [];
  $.each(rowsary, function (i, itm) {
    //wcntary.push(itm['dcetawdiff']);
    wcntary.push(itm[lineMap[userdata['sidx']]]);
  });

  $.each(wcntary, function (i, itm) {
    if (i > 0 && wcntary[i] != wcntary[i - 1]) {
      ulineidxary.push(i - 1);
    }
  });
  //$('#divdbg').text(ulineidxary);

}

// ++ 全行走査 ++ //
$.each(rows, function (i, itm) {
	 // VOY列右をに縦線を引く //
	$("#" + rows[i]['id'] + " td").eq(2).css("border-right-color", "#224444");
	
	// 週区切り線 //
	if (ulineidxary.indexOf(i) != -1) {
	  $("#" + rows[i]['id'] + " td").css("border-bottom-color",
	          !isDarkTheme ? "#004400" : "#99DD99");
	}
	
	// 船スペックタイトル //
	td = $('#' + rows[i]['id']).children('td').eq(1);
	$(td).attr('title', rows[i]['cnt'] + ' Records exists by this vessel.' + '\n' +
	        rows[i]['vesselspec']);
	
	// カレントポジションリンク用IMOタイトル //
	curimo = rows[i]['vesselspec'].replace("\n", "").slice(-8);
	td = $('#' + rows[i]['id']).children('td').eq(2);
	$(td).attr('title', curimo);
	
	// バース日がETAより大きい場合、赤文字ワーニング //
	etaschMD = !isOld ? rows[i]['dceta'].slice(0, 5) : rows[i]['dceta'].slice(3, 8);
	berthMD = rows[i]['tmberth'].slice(0, 5);
	
	if (berthMD > etaschMD) {
	  td = $('#' + rows[i]['id']).children('td').eq(BERTHTIME_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#ff0000' : '#ff90ff');
	}
	// 早いのは青表示 //
	if (berthMD < etaschMD) { td = $('#' + rows[i]['id']).children('td').eq(BERTHTIME_COLIDX); $(td).css('color', !isDarkTheme ? '#0000aa' : '#00ffff'); } // 入港日差 遅れを赤表示 // if (rows[i]['difdceta'] > 0) {
	  td = td = $('#' + rows[i]['id']).children('td').eq(ETADIFF_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#ff0000' : '#ff90ff');
	  //$(td).css('color', 'red');
	}
	// 入港日差 早いのは青表示 //
	if (rows[i]['difdceta'] < 0) {
	  td = td = $('#' + rows[i]['id']).children('td').eq(ETADIFF_COLIDX);
	  $(td).css('color', !isDarkTheme ? '#0000aa' : '#00ffff');
	}
	
	// SKIP行 //
	if (rows[i]['tmport'].indexOf('SKIP') != -1) {
	  $("#" + rows[i]['id'] + " td").addClass('td_lv');
	}
	
});	

画面例

jqGrid colModel, colNames (基本)

jqGridのcolNames, colModel については、下サンプルのようにプロパティで設定します。
先に変数に入れて、それを指定してもよいです。

本家 API : http://www.trirand.com/jqgridwiki/doku.php?id=wiki:colmodel_options

[ colModelインライン記述例 ]


datatype: "json",
loadui: 'block',
reloadAfterSubmit: true,
colNames: ['', 'Name', 'Home URL', 'My URL', 'Exp', 'Imp', 'LastUpdate', '', ''],
colModel: [
  {name: 'ico', width: '20px', align: 'center', classes: 'curpo'},
  {name: 'ope', width: '40px', align: 'left', classes: 'curpo'},

  {name: 'url', width: '120px', align: 'left', editable: true},
  {name: 'myurl', width: '120px', align: 'left', editable: true},

  {name: 'expcnt', width: '20px', align: 'right'},
  {name: 'impcnt', width: '20px', align: 'right'},
  {name: 'tmLastupdt', width: '50px', align: 'left', classes: 'tmcol'},
  {name: 'id', index: 'id', width: '0px', align: 'left',
    hidden: true,
    editrules: {edithidden: true}},
  {name: 'opeforedit', width: '0px', align: 'left', editable: true}
],
multiselect: false,

変数指定例


      var colnames = ['SKNo.', 'InvoiceNo.', '工場',  '揚港', 'コンテナNo.', '保税地域',
        '仕入額$', '仕入額\\', '納品日', '納品場所', '支払日', '請求額(課税)', '請求額(非課税)',
        '消費税', '税関名', '関税', '申告番号', '',
        '輸入諸掛(社内)', '輸入諸掛金額', '海上運賃', 'その他諸掛', '保険', '控除後売上', '粗利',
        '備考',  '最終更新', '', '', '', ''];

      var colmodel = [
        // SK No. //
        {name: 'noSK', index: 'NO_SK', width: '38px', align: 'left'},
        // Invoice No. //
        {name: 'noInv', index: 'NO_INV', width: '60px', align: 'left'},
        // 工場 //
        {name: 'nmFact', index: 'NM_FACT', width: '38px', align: 'left'},
        // DCPort //
        {name: 'nmDc', index: 'NM_DC', width: '20px', align: 'left'},
        // コンテナNo //
        {name: 'nmCont', index: 'NM_CONT', width: '64px', align: 'left'},

        // CYCFS 2018-09-28 //
        {name: 'cdTerminal', index: 'CD_TERMINAL', width: '40px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=cycfs',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },

        // ドル仕入額 //
        {name: 'amSuplusd', index: 'AM_SUPL_USD', width: '30px', align: 'right', editable: true,
          editrules: {number: true, minValue: 0, maxValue: 9999999}
        },
        // 円仕入額 //
        {name: 'amSupljpy', index: 'AM_SUPL_JPY', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 納品日 //
        {name: 'dtDeliv', index: 'DT_DELIV_LONG', width: '30px', align: 'center', "classes": "dtcol"},
        // 納品場所 //
        {name: 'nmDeliv', index: 'NM_DELIV', width: '50px', align: 'left'},
        // 支払日 //
        {name: 'dtPayment', index: 'DT_PAYMENT_LONG', width: '30px', align: 'center', editable: true, "classes": "dtcol"},
        // 課税請求 //
        {name: 'amInwithtax', index: 'AM_IN_WITH_TAX', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 非課税請求 //
        {name: 'amInnotax', index: 'AM_IN_NO_TAX', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 消費税 //
        {name: 'amTaxc', index: 'AM_TAXC', width: '30px', align: 'right'

        },
        // 税関名 //
        {name: 'nmCustom', index: 'NM_CUSTOM', width: '36px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=custom',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },
        // 関税 //
        {name: 'amTarrif', index: 'AM_TARRIF', width: '30px', align: 'right', editable: true, sotrable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 申告番号 //
        {name: 'noNotify', index: 'NO_NOTIFY', width: '56px', align: 'left', editable: true},
        // 通関チェック //
        {name: 'isCustomed', index: 'IS_CUSTOMED', width: '8px', align: 'center',
          editable: true,
          edittype: "checkbox", editoptions: {value: "1:0"}
        },
        // 輸入諸掛営業所名 //
        {name: 'nmDiv', index: 'NM_DIV', width: '38px', align: 'left', editable: true,
          edittype: "select",
          editoptions: {
            required: true,
            dataUrl: 'GetSelectTag?tp=divsk',
            defaultValue: function (setval) {
              //setval = lastselIdxMap['cdCust'];
              return setval;
            }
          }
        },
        // 輸入諸掛金額 //
        {name: 'amOutdiv', index: 'AM_OUT_DIV', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 海上運賃 //
        {name: 'amFreight', index: 'AM_FREIGHT', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // その他諸掛 //
        {name: 'amOther', index: 'AM_OTHER', width: '30px', align: 'right', editable: true},
        // 保険 //
        {name: 'amIns', index: 'AM_INS', width: '30px', align: 'right', editable: true,
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 控除後売上 //
        {name: 'amInfinal', index: 'AM_IN_FINAL', width: '30px', align: 'right', "classes": "cntcol",
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 粗利 //
        {name: 'amProfit', index: 'AM_PROFIT', width: '30px', align: 'right', "classes": "cntcol",
          editrules: {integer: true, minValue: 0, maxValue: 99999999}
        },
        // 備考 //
        {name: 'nmRemark', index: 'NM_REMARK', width: '40px', align: 'left', editable: true},
        // 最終更新 //
        {name: 'tmLastupdt', index: 'TM_LASTUPDT', width: '56px', align: 'center', classes: 'tmcol'},
        // 隠し列 //
        {name: 'id', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'dtDelivlong', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'dtPaymentlong', width: '0px', editable: true, edithidden: true, hidden: true},
        {name: 'txtOthers', width: '0px', editable: true, edithidden: true, hidden: true}
      ];

編集可能で列が多くなったりすると、ややこしく扱いにくくなるので、データベースから読み込んだりしてます。
データベースでの設定については、別途説明します。

jqGrid インライン編集 編集

[ コードサンプル ]


// ナビゲータの設定 //
	$("#opemaster").jqGrid('navGrid', "#opemasterpager",
        {edit: true, add: false, del: false});

// ++ インライン編集の設定 ++ //
$("#opemaster").jqGrid('inlineNav', "#opemasterpager", {
  edit: true,
  editicon: "ui-icon-pencil",
  // 編集 // 
  editParams: {
    oneditfunc: function (id) {     //選択行の編集時

      // フォーカス //
      $('#' + id + '_url').focus();
    },
    // 保存した後 //
    aftersavefunc: function (restxt) {
    },
    // 更新成功した時 //
    successfunc: function (resjsn, id) {

      // My URLはローカルストレージに保存する //
      //alert(JSON.stringify(resjsn));
      var resmap = JSON.parse(resjsn.responseText);
      //alert(resmap);

      if (resmap['myurl'] != null) {
        myurlMap[resmap['ope']] = resmap['myurl'];
        //alert(JSON.stringify(myurlMap));
        if (localStorage) {
          localStorage.setItem('vesselsch_myurlmap', JSON.stringify(myurlMap));
        }
      }
      // reloadAfterPostが効かないので入れる //
      $(this).jqGrid('setGridParam', {}).trigger('reloadGrid');
      //}
    }
  }
});

 

画面例

colModel


colNames: ['', 'Name', 'Home URL', 'My URL', 'Exp', 'Imp', 'LastUpdate', '', ''],
colModel: [
  {name: 'ico', width: '20px', align: 'center', classes: 'curpo'},
  {name: 'ope', width: '40px', align: 'left', classes: 'curpo'},

  {name: 'url', width: '120px', align: 'left', editable: true},
  {name: 'myurl', width: '120px', align: 'left', editable: true},

  {name: 'expcnt', width: '20px', align: 'right'},
  {name: 'impcnt', width: '20px', align: 'right'},
  {name: 'tmLastupdt', width: '50px', align: 'left', classes: 'tmcol'},
  {name: 'id', index: 'id', width: '0px', align: 'left',
    hidden: true,
    editrules: {edithidden: true}},
  {name: 'opeforedit', width: '0px', align: 'left', editable: true}
],

/* editable にした列が送信される */

送信データ例

jqGrod 折り畳み状態の永続化

たくさんのグリッドを配置したページでは、あまり見ないのは折り畳んでおくとすっきりしますが、次回使う時、開いた状態で始まるとわかりにくく、使いにくいので、ローカルストレージに保存して前回最終折り畳み状態を再現できるようにします。

[ コードサンプル ]


      //  各グリッド折り畳み状態 //
      /* キーはグリッドid, hiddngid が true or false 既定は全部trueで折り畳み   */
      var gdhiddenMap = {delayskip: true, pctgt: true, pchst: true, mtapi: true, usradd: true, tgtbps: true,
        tableschemalist: true, tableloglist: true, batlog: true,
        pcsum: true, apidoc: true, pcncann: true, svpdsterr: true, polydel: true, polyfacildel: true,
        bareaupdt: true, actcy: true};
        
      // ローカルストレージから読む //
      if (localStorage) {
        if (localStorage.getItem('vesselsch_gdstate_logshow') != null) {
          var hdnmap = JSON.parse(localStorage.getItem('vesselsch_gdstate_logshow'));
          /*for (key in gdhiddenMap) {
           if (hdnmap[key] !== undefined) {
           gdhiddenMap[key] = hdnmap[key];
           }
           }*/
          // これでも出来るが、あまり変わりないような //
          $.map(gdhiddenMap, function (value, index) {
            if (hdnmap[index] !== undefined) {
              gdhiddenMap[index] = hdnmap[index];
            }
          });
        }
      }
      
      
      /* jgGrid プロパティ設定 */
      hiddengrid: gdhiddenMap['delayskip'], // 折り畳み
      	
      /* jqGrid onHeaderClick イベントでローカルストレージに保存する */
      // -- 折り畳みを変えた時 -- //
          onHeaderClick: function () {
            var gdstate = $(this).jqGrid('getGridParam', 'gridstate');
            var thisid = $(this).attr('id');
            gdhiddenMap[thisid] = gdstate == 'hidden';
            localStorage.setItem('vesselsch_gdstate_logshow', JSON.stringify(gdhiddenMap));
          },	

Chromeの開発ツールで状態をチェックする

jqGrid セルに画像を配置

loadCompleteで行走査して、指定列番セルにhtmlで設定してます。


const var ANCH_SPAN = '<span style="margin-left:4px"/><img src="Img/port.png" /></span>';

              // 国旗 //
              // tdのセット //
              td = $('#' + rows[i]['id']).children('td').eq(FLG_COLIDX);
              if (rows[i]['cdCntry'] != '') {
                $(td).html(
                        '<span style="margin-left:2px"/><img src="Img/flag/' + rows[i]['cdCntry'] + '.gif" /></span>')
              }
              else if (rows[i]['lastpcres'].indexOf(' ANCH ') != -1) {
                $(td).html(ANCH_SPAN);
              }
              else {
                $.each(ANCH_ARY, function (j, itm) {
                  if (rows[i]['lastpcres'].indexOf(itm) != -1) {
                    $(td).html(ANCH_SPAN);
                  }
                });
              }

              // 入出港アイコン //
              td = $('#' + rows[i]['id'] + ' td').eq(ARVDEP_COLIDX);
              if (rows[i]['lastpcres'] != '') {
                $(td).html('<span style="margin-left:4px;margin-right:4px;"><img src="Img/ope/' +
                        (rows[i]['lastpcres'].slice(0, 3)) + '.png"/></span>');
              }

・動的設定はhidden列でしてる
・htmlが長くなるのはconstでセットするとよい

< 画面例 >

jqGrid グループヘッダー

列タイトルを2行にしてグループにする方法

[ コードサンプル ]


        // ==== グループヘッダー ==== //
        $("#pcsum").jqGrid('setGroupHeaders', {
          useColSpanStyle: true,
          groupHeaders: [
            {startColumnName: 'tgtarv', numberOfColumns: 5, titleText: 'Target'},
            {startColumnName: 'resarv', numberOfColumns: 5, titleText: 'Response'},
            {startColumnName: 'costarv', numberOfColumns: 5, titleText: 'Cost (s)'},
            {startColumnName: 'totaltgt', numberOfColumns: 3, titleText: 'Total'}
          ]
        });

画面例

jqGrid ツールバーにリフレッシュボタンを配置

頻繁に最新状況を見たい時とか、既定ではリフレッシュボタンが下にだけあるので、スクロールするのが面倒くさいので、上にもあると便利なので、つけるコードです。

[ コードサンプル ]


            // リフレッシュボタンを付ける //         
            var TOOLBAR_REFRESH_DIV = "<div style='float:right;margin-right:16px;' id='tbarrefreshpc'>";
            var TOOLBAR_REFRESH_BTN = "<span class='ui-icon ui-icon-refresh curpo' id='tbarrefreshbtnpc'></span>";
            $('#t_pctgt').append(TOOLBAR_REFRESH_DIV);
            $('#tbarrefreshpc').html(TOOLBAR_REFRESH_BTN);
            $('#tbarrefreshpc').attr('title', $('#refresh_pctgt').attr('title'));
            // ナビゲーションバーのボタンクリックを発生させる //
            $('#tbarrefreshbtnpc').on('click', function () {
              $('#refresh_pctgt').click();
            });

[ 画面例 ]