/*
   manages initialize and finalize
*/
// 定数の定義
var httpXMLRequest_DefaultTimerTimeoutSec = 60; //タイムアウトの秒数
var httpXMLRequest_IsShowProcessTime = false;

// メニュー二重押し防止用の変数
var clickedMenu = false;

// グローバル変数の定義
var tips = new Array();
var httpObj = false;
var timerId = '';
var timerBeginTime;
var timerTimeoutSec;
var failedFuncRef;
var isReplaceFirstYearOfImperialEra = true;
var wareki_date_a = new Array(
      new Date(1868,  9-1,  8),
      new Date(1912,  7-1, 30),
      new Date(1926, 12-1, 25),
      new Date(1989,  1-1,  8),
      new Date(2019,  5-1,  1)
);
var wareki_regexp_a = new Array(
      new RegExp("明[治]?", "g"),
      new RegExp("大[正]?", "g"),
      new RegExp("昭[和]?", "g"),
      new RegExp("平[成]?", "g"),
      new RegExp("令[和]?", "g")
);
var wareki_fullname_a = new Array("明治", "大正", "昭和", "平成", "令和");
var wareki_shortcharpattern_a = new Array("Mm", "Tt", "Ss", "Hh", "Rr");

/* 日本では1873年(明治6年)1月1日より、太陽暦となる。 */
var wareki_date_start = new Date(1873, 1-1, 1);

var month_mmm_table = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
var youbi_ddd_table = new Array("sun","mon","tue","wed","thu","fri","sat");
var youbi_dddd_table =
    new Array("Sunday","Monday","Tuesday","Wednesday",
              "Thursday","Friday","Saturday");
var youbi_aaa_table = new Array("日","月","火","水","木","金","土");
var warekiFullnameStr = "明治|大正|昭和|平成|令和";
var warekiFullnameRegExpStr = "(?:" + warekiFullnameStr + ")";
var warekiShortnameRegExpStr = "(?:[MmTtSsHhRr])";
var dateFormatRegExpStr = {
  "gggee年MM月dd日": "^(" + warekiFullnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月(\\d{1,2})日$",
  "ggge年M月d日": "^(" + warekiFullnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月(\\d{1,2})日$",
  "ggge年MM月": "^(" + warekiFullnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月$",
  "ggge年M月": "^(" + warekiFullnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月$",
  "ggge年": "^(" + warekiFullnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年$",
  "ge年MM月dd日": "^(" + warekiShortnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月(\\d{1,2})日$",
  "ge年M月d日": "^(" + warekiShortnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月(\\d{1,2})日$",
  "ge年MM月": "^(" + warekiShortnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月$",
  "ge年M月": "^(" + warekiShortnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年(\\d{1,2})月$",
  "ge年": "^(" + warekiShortnameRegExpStr + "\\d{1,2}|" + warekiFullnameRegExpStr + "元)年$",
  "ge": "^(" + warekiShortnameRegExpStr + "\\d{1,2})$",
  "ge-MM-dd": "^(" + warekiShortnameRegExpStr + "\\d{1,2})-(\\d{1,2})-(\\d{1,2})$",
  "ge-M-d": "^(" + warekiShortnameRegExpStr + "\\d{1,2})-(\\d{1,2})-(\\d{1,2})$",
  "ge-MM": "^(" + warekiShortnameRegExpStr + "\\d{1,2})-(\\d{1,2})$",
  "ge-M": "^(" + warekiShortnameRegExpStr + "\\d{1,2})-(\\d{1,2})$",
  "ge/MM/dd": "^(" + warekiShortnameRegExpStr + "\\d{1,2})/(\\d{1,2})/(\\d{1,2})$",
  "ge/M/d": "^(" + warekiShortnameRegExpStr + "\\d{1,2})/(\\d{1,2})/(\\d{1,2})$",
  "ge/MM": "^(" + warekiShortnameRegExpStr + "\\d{1,2})/(\\d{1,2})$",
  "ge/M": "^(" + warekiShortnameRegExpStr + "\\d{1,2})/(\\d{1,2})$",
  "yyyy年MM月dd日": "^(\\d{1,4})年(\\d{1,2})月(\\d{1,2})日$",
  "yyyy年M月d日": "^(\\d{1,4})年(\\d{1,2})月(\\d{1,2})日$",
  "yyyy-MM-dd": "^(\\d{1,4})-(\\d{1,2})-(\\d{1,2})$",
  "yyyy-M-d": "^(\\d{1,4})-(\\d{1,2})-(\\d{1,2})$",
  "yyyy/MM/dd": "^(\\d{1,4})/(\\d{1,2})/(\\d{1,2})$",
  "yyyy/M/d": "^(\\d{1,4})/(\\d{1,2})/(\\d{1,2})$",
  "yy/MM/dd": "^(\\d{1,2})/(\\d{1,2})/(\\d{1,2})$",
  "yyyy.MM.dd": "^(\\d{1,4})\\.(\\d{1,2})\\.(\\d{1,2})$",
  "yyyy.M.d": "^(\\d{1,4})\\.(\\d{1,2})\\.(\\d{1,2})$",
  "yyyyMMdd": "^(\\d{1,4})(\\d{1,2})(\\d{1,2})$",
  "yyyy年MM月": "^(\\d{1,4})年(\\d{1,2})月$",
  "yyyy年M月": "^(\\d{1,4})年(\\d{1,2})月$",
  "yyyy-MM": "^(\\d{1,4})-(\\d{1,2})$",
  "yyyy-M": "^(\\d{1,4})-(\\d{1,2})$",
  "yyyy/MM": "^(\\d{1,4})/(\\d{1,2})$",
  "yyyy/M": "^(\\d{1,4})/(\\d{1,2})$",
  "yyyy.MM": "^(\\d{1,4})\\.(\\d{1,2})$",
  "yyyy.M": "^(\\d{1,4})\\.(\\d{1,2})$",
  "yyyyMM": "^(\\d{1,4})(\\d{1,2})$",
  "yyyyM": "^(\\d{1,4})(\\d{1,2})$",
  "yyyy年": "^(\\d{1,4})年$",
  "yyyy": "^(\\d{1,4})$",
  "yyyy-MM-dd HH:mm:ss": "^(\\d{1,4})-(\\d{1,2})-(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$",
  "yyyy/MM/dd HH:mm:ss": "^(\\d{1,4})/(\\d{1,2})/(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$",
  "yyyy.MM.dd HH:mm:ss": "^(\\d{1,4})\\.(\\d{1,2})\\.(\\d{1,2}) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$",
  "yyyy年MM月dd日 HH:mm:ss": "^(\\d{1,4})年(\\d{1,2})月(\\d{1,2})日 (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$",
  "yyyy年M月d日 HH:mm:ss": "^(\\d{1,4})年(\\d{1,2})月(\\d{1,2})日 (\\d{1,2}):(\\d{1,2}):(\\d{1,2})$",
  "dd-MMM-yyyy": "^(\\d{1,2})-(\\w{3}|\\d{1,2})-(\\d{1,4})$",
  "dd-MM-yyyy": "^(\\d{1,2})-(\\d{1,2})-(\\d{1,4})$"
};

var browser_locale = "";

// 国際化リソースファイル
var res;
function setLocale(locale) {
    if (locale != undefined) {
        dojo.registerModulePath("apphome", "../..");
        dojo.requireLocalization("apphome", "common", locale);
        res = dojo.i18n.getLocalization("apphome", "common", locale);
        browser_locale = locale;
    }
}



/**
 * グローバルリンクの左隣にボタンを表示する
 */
const createButtonBeforeGlobalLink = (attr) => {
  /**
   * HTML文字列から生成した要素を返す
   */
  const getDomFromTemplate = (domStr) => {
    const template = document.createElement("template");
    template.innerHTML = domStr;
    return document.importNode(template.content, true);
  }

  const button = getDomFromTemplate(`<button id="${attr.id}">${attr.label}</button>`);
  const pagetitleContainer = document.querySelector("div.pagetitleContainer");
  const jfcgloballink = document.getElementById("jfcgloballink");
  if (!(button && pagetitleContainer && jfcgloballink)) {
    return;
  }
  pagetitleContainer.insertBefore(button, jfcgloballink);

  require(["wagby/Button"], (Button) => {
    const props = {
      "showLabel": attr.label && attr.label !== "",
      "faIconClass": attr.iconClass,
    };
    if (attr.style) {
      props.style = attr.style;
    }
    const btn = new Button(props, attr.id);
    if (!btn) {
      return;
    }
    if (attr.title) {
      btn.set("title", attr.title);
    }
    if (attr.onClick) {
      btn.onClick = attr.onClick;
    }
  });
}

/**
 * 画面IDに紐づくマニュアルページがある場合、マニュアルアイコンを表示する
 */
const setShowManualButton = (manualPage, SCREENID_MANUALPAGE) => {
  // マニュアルページディレクトリ
  const manualBaseDir = "system/manual";

  // 画面IDを取得する
  // サブウィンドウ検索画面、グローバルリンクがない画面は
  // ヘルプボタンを配置しない
  const globallink = document.getElementById("jfcgloballink");
  if (!globallink) {
    return;
  }
  const isMenuScreen = document.location.pathname.includes("/mainMenu.do") &&
    !document.location.search.startsWith("?name=");
  const screenId = getScreenId();
  if (!isMenuScreen && (screenId === "" || screenId.startsWith("searchList"))) {
    return;
  }

  // 画面IDからマニュアルページの画面IDキーを取得する
  const getManualPageNum = (screenId) => {
    if (isMenuScreen || screenId === "") {
      return "";
    }
    const key = Object.keys(SCREENID_MANUALPAGE).find((key) => screenId.includes(key));
    if (!key) {
      return "";
    }
    // 画面IDキーからマニュアルページを取得する
    return `${manualPage.endsWith(".pdf") ? "#page=" : ""}${SCREENID_MANUALPAGE[key]}`;
  }
  // 個別の画面毎のマニュアルページがある場合、マニュアルページを取得する
  const manualPageNum = getManualPageNum(screenId);
  // マニュアルページのURL
  const manualURL = `${manualBaseDir}/${manualPage}${manualPageNum}`;

  // グローバルリンクの左隣にマニュアル表示ボタンを配置
  createButtonBeforeGlobalLink({
    "id": "jfcBtnShowManual",
    "label": "",
    "iconClass": "fas fa-book",
    "style": "font-size: smaller; margin-left: 0;",
    "title": res.TITLE_BTN_SHOWMANUAL,
    "onClick": () => {
      MANUAL_WINDOW_HANDLE = window.open(manualURL, "MANUAL", "width=880, height=900, directories=no, location=no, menubar=no, scrollbars=yes, status=no, toolbar=no, resizable=yes");
    }
  });
}

function Initializer() {
}
Initializer.initList = new Array();
Initializer.addInit = function(fnc) {
   Initializer.initList.push(fnc);
}
Initializer.addCustomizeInit = function(fnc) {
  var deleteIndex = 0;
  for (deleteIndex; deleteIndex<Initializer.initList.length; deleteIndex++) {
    if (Initializer.initList[deleteIndex].name === "init") {
      break;
    }
  }
  Initializer.initList.splice(deleteIndex, 1);
  Initializer.addInit(fnc);
}
Initializer.init = function() {
   for (i in Initializer.initList) {
      (Initializer.initList[i])();
   }
}
Initializer.finList = new Array();
Initializer.addFin = function(fnc) {
   Initializer.finList.push(fnc);
}
Initializer.fin = function() {
   for (i in Initializer.finList) {
      (Initializer.finList[i])();
   }
}

function doConfirm(f, msg) {
  return doConfirm(f, msg, false);
}
function doConfirm(f, msg, b) {
  if (confirm(msg)) {
    if (b)
      buttonOff();
    return true;
  } else {
    return false;
  }
}

function buttonOn() {
  setButtonDisabled(false);
}
function buttonOff() {
  setButtonDisabled(true);
}
var disabledPropertyOfButtons = {};
function setButtonDisabled(disabled) {
  require(["dojo/query", "dijit/registry"], function(query, registry) {
    query("span[role='button']").forEach(function(button) {
      var widget = registry.byId(button.id);
      if (widget) {
        if (disabled) {
          if (!widget.get("disabled")) {
            disabledPropertyOfButtons[button.id] = true;
            widget.set("disabled", true);
          }
        } else {
          if (window.disabledPropertyOfButtons[button.id]) {
            widget.set("disabled", false);
            delete disabledPropertyOfButtons[button.id];
          }
        }
      }
    });
  });
}

var rejfcpkey = new RegExp('_ulp\\$002fitem\\$005b[0-9]*\\$005d\\$002f\\$0040(jfcpkey|jfcpkeygroupnum)$');
function doClearWidgetValue(widget) {
  if (!widget) {
    return;
  }
  var widgetBaseClass = widget.baseClass;
  if (widget.type === "submit" || widget.type === "button" ||
      widgetBaseClass === "dijitTabContainerTop" || widgetBaseClass === "" ||
      widget.name.match(rejfcpkey)) {
    return;
  }
  if (widgetBaseClass.indexOf("dijitRadio") !== -1 || widgetBaseClass.indexOf("dijitCheckBox") !== -1) {
    // ラジオ、チェックボックスのクリア
    widget.set("checked", false);
  } else if (widgetBaseClass.indexOf("dijitDateTextBox") !== -1) {
    // 日付のクリア
    widget.set("displayedValue", "");
  } else if (widgetBaseClass.indexOf("dijitSelect") !== -1 ||
             (widgetBaseClass.indexOf("dijitTextBox") !== -1 && !widget.get("readOnly"))) {
    // リストボックス、テキストボックス(読み込み専用以外)、サジェストのクリア
    widget.set("value", "");
    // サジェストの場合
    if (widget.declaredClass.indexOf("FilteringSelect") !== -1) {
      widget.set("_lastValueReported", "");
      widget.item = null;
      widget.textbox.value = "";
    }
  } else if (widgetBaseClass.indexOf("dijitTextBox") !== -1 &&
             widget.id.lastIndexOf("_", 0) === 0 && widget.id.endsWith("_content")) {
    // 検索画面の値をクリア
    // 検索画面で値が設定されるテキストボックスは id が「_」で始まり「_content」で終わる
    var lengthWithoutContent = widget.id.length - "_content".length;
    if ((lengthWithoutContent > 0) && (widget.id.lastIndexOf("_content") === lengthWithoutContent)) {
      widget.set("value", "");
    }
  }
}

function doClear(f) {
  f.reset();
  require(["dojo/_base/array", "dojo/query", "dijit/registry"], function(array, query, registry){
    // 引数の form 下の Dojo Widget を全てクリアする
    var widgets = getAllWidgets();
    for (var i=0,l=widgets.length; i<l; i++) {
      var widget = widgets[i];
      doClearWidgetValue(widget);
    }
    // リッチテキストエリアのクリア
    query('div[class="dijitEditor"]').forEach(function(node) {
      registry.byId(node.id).set("value", "");
    });
    // ファイル型のクリア
    query('input[name$="_jshclear"]').forEach(function(node) {
      node.value = "aaa";
    });
  });

  eval("individualClear(\""+f.name+"\");");
  return true;
}
// bodyタグのonloadイベントが行われたことを示す
// フックをセットします。
function setOnloadHook() {
   dc = null;
   if (document.getElementsByTagName) {
      dc = document
   } else
   if (document.all.getElementsByTagName) {
      dc = document.all;
   }

   elemArray = dc.getElementsByTagName("body");
   if (elemArray == null || elemArray.length == 0) {
      return;
   }
   bElem = elemArray[0];

   bElem["isLoaded"] = true;
}

Initializer.addInit(setOnloadHook);

// bodyタグのonloadイベントが行われたことを示す
// フックがセットされているか確認します。
// フックがセットされていればtrueを返します。
function isOnloadHook() {
   dc = null;

   if (document.getElementsByTagName) {
      dc = document
   } else
   if (document.all.getElementsByTagName) {
      dc = document.all;
   }

   elemArray = dc.getElementsByTagName("body");
   if (elemArray == null || elemArray.length == 0) {
      return false;
   }
   bElem = elemArray[0];
   if (bElem["isLoaded"] == null) {
       return false;
   }
   return bElem["isLoaded"];
}

//--表示属性set(表示)
function showLAYER(layName){
    if (! isOnloadHook()) {
        return;
    }

    if(document.getElementById) {        //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.visibility='visible'
    } else
    if(document.all) {               //e4用
      document.all(layName).style.visibility='visible'
    } else
    if(document.layers) {            //n4用
      document.layers[layName].visibility='show'
    }
}
//--表示属性set(非表示)
  function hideLAYER(layName){
    if(document.getElementById) {         //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.visibility='hidden'
    } else
    if(document.all) {              //e4用
      document.all(layName).style.visibility='hidden'
    } else
    if(document.layers) {           //n4用
      document.layers[layName].visibility='hide'
    }
}

//ポップアップメニューを表示する。
function showMenuLAYER(layName){
    if (! isOnloadHook()) {
        return;
    }

    if(document.getElementById) {        //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.visibility='visible'
      if (isIE() && getIEVersion() < 7) {
        openShim(document.getElementById(layName));
      }
    } else
    if(document.all) {               //e4用
      document.all(layName).style.visibility='visible'
    } else
    if(document.layers) {            //n4用
      document.layers[layName].visibility='show'
    }
}
//ポップアップメニューを非表示にする。
function hideMenuLAYER(layName){
    if(document.getElementById) {         //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.visibility='hidden'
      if (isIE() && getIEVersion() < 7) {
        closeShim(document.getElementById(layName));
      }
    } else
    if(document.all) {              //e4用
      document.all(layName).style.visibility='hidden'
    } else
    if(document.layers) {           //n4用
      document.layers[layName].visibility='hide'
    }
}

// IE5.5以降のウィンドウコントロール(コンボボックス)はHTML要素の
// 上に表示されます。そのためポップアップメニューがコンボボックスの
// 下にもぐりこむ現象が発生します。これを防ぐために、ポップアップ
// メニュと同じ位置、同じ大きさのiframe要素を置き、その上に
// ポップアップメニューを表示します。
// このiframe要素を使った技術はシム(Shim:クサビ)技術と呼ばれています。

function openShim(menu)
{

    if (menu==null) return;
    var shim = getShim(menu);
    if (shim==null) {
        shim = createMenuShim(menu,getShimId(menu));
    }

    menu.style.zIndex = 100;

    shim.style.width = menu.offsetWidth;
    shim.style.height = menu.offsetHeight;
    shim.style.top = menu.offsetTop;
    shim.style.left = menu.offsetLeft;
    shim.style.zIndex = menu.style.zIndex - 1;
    shim.style.position = "absolute";
    shim.style.display = "block";
}


function closeShim(menu)
{
    if (menu==null) return;
    var shim = getShim(menu);
    if (shim!=null) shim.style.display = "none";
}

// シムを生成します。
function createMenuShim(menu)
{
    if (menu==null) return null;

    var shim = document.createElement("<iframe src='javascript:false;' "+
                                      "scrolling='no' frameborder='0'"+
                                      "style='position:absolute; top:0px;"+
                                      "left:0px; display:none'></iframe>");
    shim.name = getShimId(menu);
    shim.id = getShimId(menu);

    if (menu.offsetParent==null || menu.offsetParent.id=="") {
        window.document.body.appendChild(shim);
    } else {
        menu.offsetParent.appendChild(shim);
    }

    return shim;
}

// シムのidを作成します。
function getShimId(menu)
{
    if (menu.id==null) return "__shim";
    return "__shim"+menu.id;
}

//生成ずみのシムを取得します。
function getShim(menu)
{
    return document.getElementById(getShimId(menu));
}


//--背景色set
function setBGCOLOR(layName,color){
    //opera6 は透明が効かないのでページ背景色と同色(ここではwhite)へ便宜修正
    if(color=='')(navigator.userAgent.search("Opera(\ |\/)6")!= -1)
          ?color='white':color='transparent'; //←このwhiteを背景色に書換える
    if(document.getElementById)         //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.backgroundColor =color
    else if(document.all)               //e4用
      document.all(layName).style.backgroundColor=color
    else if(document.layers){           //n4用
      if(color=='transparent')color=null
        document.layers[layName].bgColor=color
    }
}
//--背景画像set
  function setBGIMG(layName,image){
    if(document.getElementById)         //e5,e6,n6,n7,m1,o6,o7,s1用
      document.getElementById(layName).style.backgroundImage
         = (image=='')?'':'url('+image+')'
    else if(document.all)               //e4用
      document.all(layName).style.backgroundImage='url('+image+')'
    else if(document.layers)            //n4用
      document.layers[layName].background.src=(image=='')?null:image
}
//--マウスX座標get
function getCmnMouseX(e){
    if(navigator.userAgent.search(
             "Opera(\ |\/)6") != -1 )   //o6用
        return e.clientX
    else if(document.all)               //e4,e5,e6用
        return document.body.scrollLeft+event.clientX
    else if(document.layers ||
            document.getElementById)    //n4,n6,n7,m1,o7,s1用
        return e.pageX
}
//--マウスY座標get
function getCmnMouseY(e){
    if(navigator.userAgent.search(
             "Opera(\ |\/)6") != -1 )   //o6用
        return e.clientY
    else if(document.all)               //e4,e5,e6用
        return document.body.scrollTop+event.clientY
    else if(document.layers ||
            document.getElementById)    //n4,n6,n7,m1,o7,s1用
        return e.pageY
}
//--HTML出力
function outputLAYER(layName,html){
    if(document.getElementById){        //e5,e6,n6,n7,m1,o7,s1用
		document.getElementById(layName).innerHTML=html
		if (isIE() && getIEVersion() < 7) {
			//IE7以前のバージョンではコンボボックスが透過するバグがあるため、
			//shim をセットする
			setShim2Element(layName);
		}
    } else if(document.all){            //e4用
        document.all(layName).innerHTML=html
    } else if(document.layers) {        //n4用
        with(document.layers[layName].document){
            open()
            write(html)
            close()
        }
    }
}
//--レイヤー移動
function moveLAYER(layName,x,y){
    if(document.getElementById){        //e5,e6,n6,n7,m1,o6,o7,s1用
        document.getElementById(layName).style.left = x
        document.getElementById(layName).style.top  = y
    } else if(document.all){            //e4用
        document.all(layName).style.pixelLeft = x
        document.all(layName).style.pixelTop  = y
    } else if(document.layers)          //n4用
        document.layers[layName].moveTo(x,y)
}
//--レイヤーオブジェクトを取得
//  (必ずonload後に実行すること)
function getLayOj(layName){
    if(document.getElementById)         //e5,e6,n6,n7,m1,o6,o7,s1用
      return document.getElementById(layName)
    else if(document.all)               //e4用
      return document.all(layName)
    else if(document.layers)            //n4用
      return document.layers[layName]
}
//ウインドウ有無確認関数
//e4,e5,e6,n4,n6,n7,m1,o6,o7,s1用
function win_closed(winOj) {
      var ua = navigator.userAgent
      if( !!winOj )
          if( ( ua.indexOf('Gecko')!=-1 || ua.indexOf('MSIE 4')!=-1 )
               && ua.indexOf('Win')!=-1 )
               return winOj.closed
          else return typeof winOj.document  != 'object'
      else return true
}

function includeClickTag(srcElement, rootElement) {
  if (srcElement == null || srcElement === rootElement) {
    return false;
  }
  var tag = srcElement.tagName;
  if (isClickTag(tag)) {
    return true;
  }
  return includeClickTag(srcElement.parentNode, rootElement);
}

function isClickTag(tag) {
  if (tag == 'INPUT' || tag == 'A' || tag == 'IMG' || tag == 'BUTTON' || tag == 'FORM') {
    return true;
  }
  return false;
}

function jumpto(url) {
    window.opener.location = url;
}
function getTipsMessage(key) {
  return tips[key];
}
function showTipsMessage(key) {
  var msg = getTipsMessage(key);
  if (!msg) {
    return;
  }
  var height = 90 + (msg.length / 40) * 30;
  var w = window.open("", "_help", "width=400,height=" + height + ",resizable,scrollbars");
  var d = w.document;
  d.open("text/html");
  d.write('<style type="text/css">');
  d.write('.helpMsg { font-size: 14px; font-family: "Lucida Grande", "Hiragino Kaku Gothic ProN", Meiryo, sans-serif; white-space: pre-wrap; }');
  d.write('</style>');
  d.write('<div class="helpMsg">');
  d.write(msg);
  d.write('</div>');
  d.write('<br>');
  d.write('<div align="center">');
  d.write('<input type="button" onClick="window.close(self);" value="' + res.BUTTON_CLOSE + '">');
  d.write('</div>');
  d.close();
}

function SystemError() {
  return true;
}

window.onerror = SystemError;

function setCookie(setname, setdata, setexpires) {
  var str = setname + "=" + encodeURIComponent(setdata);
  if (setexpires) {
    var t = new Date();
    t.setTime(t.getTime()+(setexpires*1000*60*60*24));
    var expt = t.toGMTString();
    str += ";expires=" + expt;
  }
  document.cookie = str;
}

function getCookie(getname) {
  var cName = getname + "=";
  var getdata = null;
  var cCookie = document.cookie+";";
  var start = cCookie.indexOf(cName);
  if (start != -1) {
    var end = cCookie.indexOf(";", start);
    getdata = decodeURIComponent(cCookie.substring(start+cName.length, end));
  }
  return getdata;
}

function displayHTML(event, layName, html) {
    var x = getCmnMouseX(event);
    var y = getCmnMouseY(event);
    moveLAYER(layName, x+20, y+10);
    outputLAYER(layName, html);
    showLAYER(layName);

}

// 引数に与えられたURLにHTTPリクエストを行ない、値をタグ要素にセットする
function httpXMLRequest(
    target_url, param, method, functionReference, failedFunctionReference)
{
    // タイマーが動作中の場合は、タイマーをストップする。
    if (timerId != '') {
        clearInterval(timerId);
        timerId = '';
    }
    // HTTPリクエストを送信中の場合は、HTTPリクエストを中断する
    if (httpObj != false) {
        httpObj.abort();
        httpObj = false;
    }
    // 処理失敗時の関数参照を格納する
    failedFuncRef = failedFunctionReference;
    // httpObjの作成
    try {
        if(window.XMLHttpRequest) {
            httpObj = new XMLHttpRequest();
        } else if(window.ActiveXObject) {
            httpObj = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
            httpObj = false;
        }
    } catch(e) {
        httpObj = false;
    }
    if(! httpObj) {
        // httpObjの作成に失敗した場合
        showAlertDialog('not supported your web browser!!');
        failedFuncRef();
        return false;
    }
    // タイマーをセット
    timerTimeoutSec = httpXMLRequest_DefaultTimerTimeoutSec;
    timerBeginTime = new Date().getTime();
    timerId = setInterval('timeoutCheck()', 1000);

    // HTTPリクエストを送信
    httpObj.open(method, target_url, true);
    httpObj.onreadystatechange = function() {
        if (typeof(httpObj) != 'undefined' && httpObj.readyState == 4) {
            // タイマーをストップする
            if (timerId != '') {
                clearInterval(timerId);
                timerId = '';
            }
            var timerEndTime = new Date().getTime();

            if (httpObj.status == 200) {
                // リクエストの受信に成功した場合
                functionReference(httpObj.responseXML);
                if (httpXMLRequest_IsShowProcessTime) {
                  showAlertDialog('process time '+(timerEndTime-timerBeginTime)+'ms');
                }
                httpObj = false;
            } else {
                // リクエストの受信に失敗した場合
                failedFuncRef();
                var alertmsg = 'httpXMLRequest '+httpObj.status + ' : ' + httpObj.statusText;
                if (httpXMLRequest_IsShowProcessTime) {
                    alertmsg =
                        alertmsg + '\n' +
                        'process time '+(timerEndTime-timerBeginTime)+'ms';
                }
                window.status = alertmsg;
                httpObj = false;
                return false;
            }
        }
    };
    if (param != '') {
        httpObj.setRequestHeader(
            'Content-Type', 'application/x-www-form-urlencoded');
    }
    httpObj.send(param);
    return true;
}

// タイムアウト処理
function timeoutCheck() {
    timerTimeoutSec --;
    if(timerTimeoutSec <= 0) {
        // タイムアウトした場合
        // タイマーをストップする
        if (timerId != '') {
            clearInterval(timerId);
            timerId = '';
        }
        var timerEndTime = new Date().getTime();

        // HTTPリクエストを中断する
        if (httpObj != false) {
            httpObj.abort();
            httpObj = false;
        }

        // エラーメッセージを表示
        failedFuncRef();
        if (httpXMLRequest_IsShowProcessTime) {
          showAlertDialog(
                'Http connection timeout!!\n'+
                'process time '+(timerEndTime-timerBeginTime)+'ms');
        }
        return false;
    }
}

function addListener(elem, eventType, func, cap) {
  if(elem.addEventListener) {
    elem.addEventListener(eventType, func, cap);
  } else if(elem.attachEvent) {
    elem.attachEvent('on' + eventType, func);
  } else {
    showAlertDialog('not supported your web browser!!');
    return false;
  }
}

function getFieldboxPosition(id) {
  // 繰り返しコンテナの見出しは、CSS のクラスが field_box となっている div 要素
  // 内部に押下されたボタンが存在している繰り返しコンテナを取得する
  var fieldbox;
  var query = "input[name='" + id + "']";
//  dojo.query("div[class='field_box']").forEach(function(node) {
  dojo.query("fieldset").forEach(function(node) {
    var button = dojo.query(query, node)[0];
    if (button) {
      fieldbox = node;
    }
  });
  // タブが設定されている場合は、fieldbox がタブ内に存在しているか確認する
  var tabContainer;
  dojo.query("div[class~='dijitTabContainer']").forEach(function(node) {
    var button = dojo.query(query, node)[0];
    if (button) {
      tabContainer = node;
    }
  });
  var scrollPosition;
  if (fieldbox) {
    var scrollTop = fieldbox.offsetTop - 10; // コンテナの見出しが見えるように 10px 上部へ補正する
    if (tabContainer){
      // タブ内に繰り返しコンテナが存在している場合、タブの表示位置だけ補正する
      scrollTop += tabContainer.offsetTop + 20; // コンテナの見出しが見えるように 20px 上部へ補正する
    }
    var scrollLeft = fieldbox.scrollLeft;
    scrollPosition = {
      'scrollTop': scrollTop,
      'scrollLeft': scrollLeft
    };
  }
  return scrollPosition;
}

function getWindowPosition() {
  var scrollPosition;
  var scrollTop;
  var scrollLeft;
  // 繰り返しコンテナの枠が取得できなかった場合
  // Dojo レイアウトの有無で window、div の位置を取得する
  var dojoLayout = document.getElementById("dojolayout");
  if (dojoLayout) {
    // マルチペイン(Dojo レイアウト)の場合
    var container = document.getElementById('centerarea');
    scrollTop = container.scrollTop;
    scrollLeft = container.scrollLeft;
  } else {
    // シングルペインの場合
    scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
  }
  if (scrollTop !== undefined && scrollLeft !== undefined) {
    scrollPosition = {
      scrollTop: scrollTop,
      scrollLeft: scrollLeft
    };
  }
  return scrollPosition;
}

function setScrollPosition(id) {
  require(["dojo/cookie"], function(cookie) {
    removeScrollPosition();
    var scrollTop = 0;
    var scrollLeft = 0;
    var scrollPosition;

    // isScrollToFieldbox 関数でスクロール位置をコンテナの見出しにするかどうか切り替える
    if (isScrollToFieldbox()) {
      scrollPosition = getFieldboxPosition(id);
    }
    // スクロール位置がウィンドウまたは、繰り返しコンテナの見出し位置が取得できなかった場合
    if (!isScrollToFieldbox() || !scrollPosition) {
      scrollPosition = getWindowPosition();
    }
    if (scrollPosition) {
      scrollTop = scrollPosition.scrollTop;
      scrollLeft = scrollPosition.scrollLeft;
    }
    // 垂直スクロール量
    cookie("__jfc_cookie_scrollTop", scrollTop);
    // 水平スクロール量
    cookie("__jfc_cookie_scrollLeft", scrollLeft);
    //スクロール先になるボタンのIDをクッキーにセットする
    cookie("scrollAnchorId", changeContainerRemoveButtonId(id));
  });
}

function changeContainerRemoveButtonId(id) {
  // 押下されたボタンがコンテナの削除ボタンでない場合、id を返す
  if (!id || id.indexOf('btnRemove_') === -1) {
    return id;
  }
  // コンテナの1番目の削除ボタンでない場合、id を返す
  var results = id.match(/btnRemove_((.*_005b)(\d)(_005d))/);
  if (!results || results.length !== 5 || results[3] !== "0") {
    return id;
  }
  // コンテナの削除ボタンの数を確認する
  var removeButtons;
  var queryString = "input[name^='btnRemove_" + results[2] + "'][name$='" + results[4] + "']";
  require(['dojo/query'], function(query) {
    removeButtons = query(queryString);
  });
  if (removeButtons.length === 1) {
    // コンテナの項目がない場合、追加ボタンにフォーカスをあてる
    // 追加ボタンがない場合、画面の先頭の入力項目にフォーカスがあたる
    return 'btnAdd_' + results[1];
  } else {
    // コンテナの項目が存在する場合、1番目の削除ボタンにフォーカスをあてる
    return 'btnRemove_' + results[2] + '1' + results[4];
  }
}

function scrollPosition(callback) {
  require(["dijit/registry", "dojo/cookie"], function(registry, cookie) {
    var obj = getScrollTargetObject(registry, cookie);
    if (obj) {
      setTimeout(function() {
        if (obj.id && (obj.id.lastIndexOf("btnAdd_", 0) === 0
                       || obj.id.lastIndexOf("sortNormal_", 0) === 0
                       || obj.id.lastIndexOf("sortReverse_", 0) === 0)) {
          scrollSavedWindowPosition(registry, cookie);
        }
        obj.focus();
        //クッキーからスクロール先のIDを削除
        removeScrollPosition(cookie);
      }, 30);
    } else {
      if (!scrollSavedWindowPosition(registry, cookie)) {
        if (callback) {
          callback();
        }
        //クッキーからスクロール先のIDを削除
        removeScrollPosition(cookie);
      }
    }
  });
}

function getScrollTargetObject(registry, cookie) {
  var id = cookie("scrollAnchorId");
  if (!id) {
    return null;
  }
  var obj = registry.byId(id);
  if (obj) {
    if (!obj.focus || obj.get("disabled") || obj.get("readOnly")) {
      return null;
    }
  } else {
    obj = document.getElementById(id);
    if (!obj || !obj.focus || obj.disabled || obj.readonly) {
      return null;
    }
  }
  return obj;
}

function scrollSavedWindowPosition(registry, cookie) {
  // サブウィンドウ検索画面ではクッキーに保存されたスクロール位置は利用しない
  if (document.location.pathname.includes("/searchList")) {
    return false;
  }
  var scrollTop = parseInt(cookie("__jfc_cookie_scrollTop"), 10);
  var scrollLeft = parseInt(cookie("__jfc_cookie_scrollLeft"), 10);
  if (!scrollTop) {
    return false;
  }
  if (!scrollLeft) {
    scrollLeft = 0;
  }
  // Dojo のレイアウトを使用しているか
  var dojoLayout = registry.byId("dojolayout");
  if (dojoLayout) {
    var container = document.getElementById("centerarea");
    container.scrollTop = scrollTop;
    container.scrollLeft = scrollLeft;
  } else {
    window.scrollTo(scrollLeft, scrollTop);
  }
  return true;
}

function removeScrollPosition(cookie) {
  require(["dojo/cookie"], function(cookie) {
    cookie("__jfc_cookie_scrollTop", 0);
    cookie("__jfc_cookie_scrollLeft", 0);
    cookie("scrollAnchorId", "");
  });
}

// スクロール位置を繰り返しコンテナの見出しにするかどうか
// mycommon.js でこの関数をオーバーライドして動作を変更する
function isScrollToFieldbox() {
  return false;
}

function masterInputCheck(f) {
  var error_fields = "";

  for (var i=0; i<f.length; i++) {
    var e = f.elements[i];
    // item[-1]/content のように index が -1 のものはチェック対象外
    if (e.name.match(/^master_lp\$item\[([0-9]+)\]\$content$/g)) {
      if ((e.value == null) || (e.value == "")) {
        error_fields += "\n            " + res.ERROR_MSG_CODE + " " + RegExp.$1;
        continue;
      }
    }
  }
  if (error_fields.length > 0) {
    var msg = res.ERROR_MSG_HISSU_1 + "\n";
    msg += res.ERROR_MSG_HISSU_2 + "\n\n"
    msg += error_fields + "\n";
    showAlertDialog(msg);
    return false;
  }

  return true;
}

function focusFirstElement() {
  const d = window.document;
  if (d.URL.indexOf("#", 0) > 0) {
    removeScrollPosition();
    return;
  }
  const focusFirstElementFunc = () => {
    if (window.myFocusFirstElement) {
      window.myFocusFirstElement();
      return;
    }
    var widgets = getAllInputWidgets();
    // タブインデックスでソートする
    sortWidgetsByTabindex(widgets);
    for (var i=0,l=widgets.length; i<l; i++) {
      var widget = widgets[i];
      if ((widget.type === "text" || widget.type === "textarea"  || widget.type === "password" ||
           widget.type === "radio" || widget.type === "checkbox" || widget.declaredClass === "wagby.DateTimeTextBox" ||
           widget.declaredClass === "wagby.DateTimeSelect") &&
          !(widget.get("disabled") || widget.get("readOnly") || widget.get("tabIndex") === "-1")) {
        widget.focus();
        break;
      }
    }
  }
  // 入力可・付加制御が設定されている場合、入力制御完了後にフォーカスをセットする処理を実行する
  if (window.createCtrlDisableManager) {
    require(["dojo/topic"], (topic) => {
      const topicHandle = topic.subscribe("CtrlDisableManager", (message) => {
        if (message === "done") {
          scrollPosition(focusFirstElementFunc);
          topicHandle.remove();
        }
      });
    });
  } else {
    scrollPosition(focusFirstElementFunc);
  }
}

function sortWidgetsByTabindex(widgets) {
  if (!widgets || widgets.length === 0) {
    return;
  }
  widgets.sort(function(a, b) {
    try {
      var aTabIndex = parseInt(a.tabIndex, 10);
      var bTabIndex = parseInt(b.tabIndex, 10);
      return aTabIndex - bTabIndex;
    } catch(e) {
    }
    return 0;
  });
}

/**
 * テキストフィールドなどに入力された文字列について、
 * パディングを行います。
 *
 * パディング文字は、文字列の左側につきます。
 *
 * event   イベント
 * padChar パディング文字
 * size    パディングの結果文字列の長さ
 */
function padding(widget, padChar, size) {
  if (!widget || !widget.get) {
    return;
  }
  if (!padChar || padChar === "" || !size || size <= 0) {
    return;
  }
  var value = widget.get("displayedValue");
  if (!value || value === "") {
    return;
  }
  var str = _zenkakuNum2hankaku(value);
  // パディング文字をつけます。
  while (str.length < size) {
    str = padChar + str;
  }
  // 余分についたパディング文字を取り除きます。
  while (str.length > size) {
    if (str.charAt(0) != padChar) {
      break;
    } else {
      str = str.substring(1);
    }
  }
  widget.set("value", str);
}

/**
 * テキストフィールドなどに入力された日付を
 * 規定のフォーマットに変換します。
 */
function normalizeDate(widget) {
  if (!widget) {
    return;
  }
  try {
    var formattedDateValue = formatDate(createDateObject(widget.get("displayedValue")));
    widget.set("value", formattedDateValue);
  } catch (e){
    // 変換に失敗した場合はそのままにしておく。
  }
}

/**
 * テキストフィールドなどに入力された日付を
 * 指定した日付のフォーマットに変換します。
 *
 * @param event
 * @param format
 */
function setDateWithFormat(widget, format) {
  if (!widget || widget.get("value") === "") {
    return;
  }
  var dateFormat = format || "yyyy-MM-dd";
  try {
    widget.set("value", _setDateWithFormat(widget.get("value"), dateFormat));
  } catch (excptn){
    // 変換に失敗した場合はそのままにしておく。
  }
}

function _setDateWithFormat(/* string */ value, /* string */ dateFormat) {
  if (!value || value === "") {
    return "";
  }
  var formattedValue = "";
  var datearray;
  datearray = createDateArray(value, false, dateFormat) ;
  if (datearray == null || datearray.length == 0 || datearray[0] == -1 ) {
    return formattedValue;
  }

  var dateJson;
  dateJson = convDateJSON(datearray);

  var dateText;
  dateText = formatYYYYMMddhhmmss(
    dateJson.year, dateJson.month, dateJson.day_of_month,
    dateJson.hour, dateJson.minute, dateJson.second);

  try {
    formattedValue = formatDateObject(createDateObject(dateText), dateFormat);
  } catch (excptn) {
  }
  return formattedValue;
}

/*
 * @return "YYYY-MM-dd hh:mm:ss"
 */
function formatYYYYMMddhhmmss(
     /* int */ year,
     /* int */ month,
     /* int */ day,
     /* int */ hour,
     /* int */ minute,
     /* int */ second) {

  var s = year;
  if (month == null) {
      // yyyy
      return s;
  }
  s = s + '-' + month;
  if (day == null) {
      // yyyy-MM
      return s;
  }
  s = s + '-' + day;
  if (hour == null) {
      // yyyy-MM-dd
      return s;
  }
  s = s + ' ' + hour;
  if (minute == null) {
      // yyyy-MM-dd hh
      return s;
  }
  s = s + ':' + minute;
  if (second == null) {
      // yyyy-MM-dd hh:mm
      return s;
  }
  // yyyy-MM-dd hh:mm:ss
  s = s + ':' + second;
  return s;

}

/*
 * @return "YYYY-MM-dd"
 */
function formatYYYYMMdd(
     /* int */ year,
     /* int */ month,
     /* int */ day) {

  var s = year;
  if (month == null) {
      // yyyy
      return s;
  }
  s = s + '-' + month;
  if (day == null) {
      // yyyy-MM
      return s;
  }
  s = s + '-' + day;
  return s;
}

function convDateJSON(/* Array of int*/ datearray) {

  var year = datearray[0];

  var month;
  if (datearray[1] != -1) {
      month = datearray[1];
  } else {
      month = 1;
  }

  var day_of_month;

  if (datearray[2] != -1) {
      day_of_month = datearray[2];
      var lastday = getLastDayOfThisMonth(year,month-1);
      if (lastday < day_of_month) {
          day_of_month = lastday;
      }
  } else {
      day_of_month = 1;
  }
  var hour = 0;
  if (datearray[3] != -1) {
    hour = datearray[3];
  }
  var minute = 0;
  if (datearray[4] != -1) {
    minute = datearray[4];
  }
  var second = 0;
  if (datearray[5] != -1) {
    second = datearray[5];
  }
  return {year:year,
      month:month,
      day_of_month:day_of_month,
      hour:hour,
      minute:minute,
      second:second};
}


/**
 * イベントが発生したHTMLの要素を返します。
 *
 */
function getEventSrc(event) {
  if (! event) {
    return null;
  }
  if (event.srcElement) {
    // IE 6, Opera 9
    return event.srcElement;
  } else
  if (event.target) {
    // FireFox 2
    return event.target;
  }
}

/**
 * Dateオブジェクトの情報から、フォーマットされた日付字列を作成します。
 */
function formatDate(date) {
  // 年月日を分ける文字
  sep = "-";

  s = "" + date.getFullYear() + sep;
  if (date.getMonth() < 10 - 1) {
    s = s + "0";
  }
    s = s + (date.getMonth() + 1) + sep;
  if (date.getDate() < 10) {
    s = s + "0";
  }
  s = s + date.getDate();
  return s;
}

/**
 * 文字列を年、月、日に分解して、Dateオブジェクトを返します。
 *
 * 返戻されるオブジェクトの属性year,month,dayがそれぞれ
 * 年、月、日にあたります。
 *
 * 不正な西暦の場合はExceptionをthrowします。
 */
function convText2Date(text) {
  if (!text || text.trim() === "" || text === "undefined-undefined-undefined" || text === "Invalid Date") {
    return;
  }
  var before = text;

  // '-','/','年','月','日'をスペースに置換します。

  text = text.replace(/[年月日\/-]/g, " ");
  text = _zenkakuNum2hankaku(text);
  text = replaceWarekiNengouFullnameToShortchar(text);
  // 前後のスペースを取り除きます。
  text = text.replace(/^ +/, "");
  text = text.replace(/ +$/, "");

  // 1個以上のスペースを1つのスペースに置換します。
  text = text.replace(/ +/g, " ");

  // スペースで区切ってトークンを得る
  elems = text.split(" ");
  var date = new Date();
  var year = date.getFullYear();
  var month = date.getMonth() + 1 ;
  var day = date.getDate();
  var hour = 0;
  var minute = 0;
  var second = 0;

  switch (elems.length) {
    case 1:
      var dateText = elems[0];
      if (dateText.length === 8) {
        year = dateText.slice(0, 4);
        month = dateText.slice(4, 6);
        day = dateText.slice(6, 8);
      } else {
        year = _getYearFor3Token(dateText);
        month = 1;
        day = 1;
      }
      break;
    case 2:
      // 和暦年月の場合
      if ((new RegExp(warekiShortnameRegExpStr + "\\d{1,2}")).test(elems[0])) {
        year = _getYearFor3Token(elems[0]);
        month = parseInt(elems[1],10);
        day = 1;
      } else {
        month = parseInt(elems[0],10);
        day = parseInt(elems[1],10);
      }
      break;
    case 3:
      year = _getYearFor3Token(elems[0]);
      month = parseInt(elems[1],10);
      day = parseInt(elems[2],10);
      break;
    case 4:
      // 日付と時刻の場合、最後の配列要素にはコロンを含む文字列が入る
      if (elems[3].indexOf(":") > 0) {
        year = _getYearFor3Token(elems[0]);
        month = parseInt(elems[1],10);
        day = parseInt(elems[2],10);
        var dateTime = convText2Date_time(elems[3], new Date(year, month - 1, day));
        hour = dateTime.getHours();
        minute = dateTime.getMinutes();
        second = dateTime.getSeconds();
      } else {
        year = _getYearFor4Token(elems[0], elems[1]);
        month = parseInt(elems[2],10);
        day = parseInt(elems[3],10);
      }
      break;
    default:
      throw res.EXCEPTION_MSG_UNEXPECTED + before;
  }

  if (month < 1 || month > 12) {
      throw res.EXCEPTION_MSG_ILLEGAL_MONTH + month;
  }

  if (day < 1 || day > 31) {
      throw res.EXCEPTION_MSG_ILLEGAL_DATE + day;
  }
  ret = new Date(year, month - 1, day, hour, minute, second);
  if (month-1 != ret.getMonth() || day != ret.getDate()) {
      throw res.EXCEPTION_MSG_ILLEGAL_MONTH_OR_DATE + month+"-"+day;
  }
  return ret;
}

function convText2Date_time(text, date1) {
    if (!text || !date1) {
        return;
    }
    var rObj;

    rObj = new RegExp('([012]?[0-9])[:時]([0-5]?[0-9])[:分]([0-5]?[0-9])[秒]?');
    if (text.match(rObj)) {
        // HH:mm:ss
        return new Date(
            date1.getFullYear(), date1.getMonth(), date1.getDate(),
            RegExp.$1, RegExp.$2, RegExp.$3);
    }

    rObj = new RegExp('([012]?[0-9])[:時]([0-5]?[0-9])[分]?');
    if (text.match(rObj)) {
        // HH:mm
        return new Date(
            date1.getFullYear(), date1.getMonth(), date1.getDate(),
            RegExp.$1, RegExp.$2, 0);
    }

    rObj = new RegExp('([012][0-9])([0-5][0-9])([0-5][0-9])');
    if (text.match(rObj)) {
        // HHmmss
        return new Date(
            date1.getFullYear(), date1.getMonth(), date1.getDate(),
            RegExp.$1, RegExp.$2, RegExp.$3);
    }

    rObj = new RegExp('([012][0-9])([0-5][0-9])');
    if (text.match(rObj)) {
        // HHmm
        return new Date(
            date1.getFullYear(), date1.getMonth(), date1.getDate(),
            RegExp.$1, RegExp.$2, 0);
    }

    return date1;
}

/**
 * 全角数字を半角に変換します。
 */
function _zenkakuNum2hankaku(str) {
  var zNums = "０１２３４５６７８９";
  var ret = ""
  var i;
  for (i = 0; i < str.length;i++) {
    if (zNums.indexOf(str.charAt(i)) >= 0) {
      ret = ret + zNums.indexOf(str.charAt(i));
    } else {
      ret = ret + str.charAt(i);
    }
  }
  return ret;
}

/**
 * 3トークンの場合の西暦を取得します。
 *
 * <p> str 年を示します。</p>
 * 不正な西暦の場合はExceptionをthrowします。
 */
function _getYearFor3Token(str) {
    return _getYearArrayFor3Token(str)[0];
}

/**
 * 3トークンの場合の西暦を取得します。
 *
 * <p> str 年を示します。</p>
 * 不正な西暦の場合はExceptionをthrowします。
 */
function _getYearArrayFor3Token(str) {
  var i;
  var year;
  var lastMatch;
  for (i=0;i<wareki_date_a.length;i++) {
    var warekiletter = new RegExp("^["+wareki_shortcharpattern_a[i]+"]([0-9]+|元)([^0-9])");
    if (warekiletter.test(str)) {
        var ra = warekiletter.exec(str);
        var re = ra[0].substring(0, ra[0].length - ra[2].length);
        lastMatch = new Array(re, ra[1]);
    } else {
        warekiletter = new RegExp("^["+wareki_shortcharpattern_a[i]+"]\\s*([0-9]{1,2}|元)");
        if (warekiletter.test(str)) {
            //RegExp.$1がstr.match("^[Hh][0-9]+")の結果を記録する。
            lastMatch = warekiletter.exec(str);
        } else {
            continue;
        }
    }
    var warekiYear;
    if (RegExp.$1 === "元") {
      warekiYear = 1;
    } else {
      warekiYear = parseInt(RegExp.$1,10);
    }
    year = wareki_date_a[i].getFullYear() - 1 + warekiYear;

    return new Array(year, lastMatch);
  }
  var re4letter = new RegExp("(^[0-9]{4})");
  var re2letter = new RegExp("(^[0-9]{2})");
  if (re4letter.test(str)){
    lastMatch = re4letter.exec(str)
    year = parseInt(lastMatch);
  } else
  if (re2letter.test(str)){
    // 2桁入力
    var curr = new Date();
    // 現在から75年前を基準とする。
    var baseYear = curr.getFullYear() - 75 ;
    lastMatch = re2letter.exec(str);
    var input = parseInt(lastMatch,10);
    for (year = baseYear;year < baseYear + 100;year++) {
      if (year % 100 == input) {
        break;
      }
    }
  } else {
    throw res.EXCEPTION_MSG_CANTGET_YEAR + str;
  }
  return new Array(year, lastMatch);
}

/**
 * 4トークンの場合の西暦を取得します。
 *
 * <p> era 年号を示します。</p>
 * <p> str 年を示します。</p>
 */
function _getYearFor4Token(era, str) {
  var i;
  for (i=0;i<wareki_date_a.length;i++) {
    if (era.match("^["+wareki_shortcharpattern_a[i]+"]")) {
      return wareki_date_a[i].getFullYear() - 1 + parseInt(str,10);
    }
  }
  throw res.EXCEPTION_MSG_CANTGET_YEAR + era + str;
  return year;
}

/**
 * 指定された文字列内の長い和暦を短い和暦に置き換えます。
 */
function replaceWarekiNengouFullnameToShortchar(s) {
  var i;
  for (i=0;i<wareki_regexp_a.length;i++) {
    s = s.replace(wareki_regexp_a[i], wareki_shortcharpattern_a[i].charAt(0));
  }
  return s;
}

/**
 * 指定された和暦年号コードと西暦年から和暦の年を取得します。
 * 和暦年号コードが負の数の場合は、西暦の年を返します。
 */
function getWarekiYear(code,fullyear) {
  if (code < 0) {
    return fullyear;
  }
  return fullyear-(wareki_date_a[code].getFullYear()-1);
}
/**
 * 指定された日付から和暦年号コードを取得します。
 * 和暦に該当しない場合は、-1を返します。
 */
function getWarekiNengouCode(d) {
  if (d < wareki_date_start) {
    return -1;
  }
  var i;
  for (i=0;i<wareki_date_a.length-1;i++) {
    if (d >= wareki_date_a[i] && d < wareki_date_a[i+1]) {
      return i;
    }
  }
  i=wareki_date_a.length-1;
  if (d >= wareki_date_a[i]) {
    return i;
  }
  return -1;
}
/**
 * 指定された西暦年から和暦年号コードを取得します。
 * 和暦に該当しない場合は、-1を返します。
 */
function getWarekiNengouCodeByYear(fullyear) {
  if (fullyear < wareki_date_start.getFullYear()) {
    return -1;
  }
  var i;
  for (i=0;i<wareki_date_a.length-1;i++) {
    if (fullyear >= wareki_date_a[i].getFullYear() && fullyear < wareki_date_a[i+1].getFullYear()) {
      return i;
    }
  }
  i=wareki_date_a.length-1;
  if (fullyear >= wareki_date_a[i].getFullYear()) {
    return i;
  }
  return -1;
}

/*
 * 日付文字を日付オブジェクトに変換します。
 *
 * 不正な西暦の場合はExceptionをthrowします。
 */
function createDateObject(text, dateFormat) {
    var ret;
    var da = createDateArray(text, true, dateFormat);
    var year = da[0];
    var month = da[1]-1;
    if (month < 0) {
        month = 0;
    }
    var day = da[2];
    if (da[2] == -1) {
        day = 1;
    }
    if (da[3] == -1 && da[4] == -1 && da[5] == -1) {
        ret = new Date(year,month,day);
        if (month != ret.getMonth() || day != ret.getDate()) {
            throw res.EXCEPTION_MSG_ILLEGAL_MONTH_OR_DATE + month+"-"+day;
        }
        return ret;
    }

    var hour = da[3];
    if (da[2] == -1) {
        hour = 0;
    }
    var minutes = da[4];
    if (da[4] == -1) {
        minutes = 0;
    }
    var seconds = da[5];
    if (da[5] == -1) {
        seconds = 0;
    }

    ret = new Date(year,month,day,hour,minutes,seconds);
    if (month != ret.getMonth() || day != ret.getDate()) {
        throw res.EXCEPTION_MSG_ILLEGAL_MONTH_OR_DATE + month+"-"+day;
    }
    if (hour != ret.getHours() || minutes != ret.getMinutes() ||
        seconds != ret.getSeconds())
    {
        throw res.EXCEPTION_MSG_ILLEGAL_TIME_OR_MINUTE_OR_SECOND + hour+":"+minutes+":"+seconds
    }
    return ret;
}

/*
 * 日付文字を年月日を格納した配列に変換します。
 *
 * 不正な西暦や、strictがtrueで完全一致しない場合はExceptionをthrowします。
 *
 * 例：1999-1-1 -> { 1999, 1, 1 }
 * 例：1999     -> { 1999, -1, -1 }
 * 例：1999-aaa -> { 1999, -1, -1 } (strictがfalse)
 * 例：1999-aaa -> Exceptionがthrowされる (strictがtrue)
 *
 * @param text 評価する文字列
 * @param strict 完全一致による評価を行うかどうか
 * @return 年、月、日の数値を格納した配列。値が存在しない場合は -1 となる。
 */
function createDateArray(text, strict, dateFormat) {
    if (!text || text === "") {
      return [];
    }
    if (!(text instanceof Date) && dateFormat) {
      var dateArray = createDateArrayWithDateFormat(text, dateFormat);
      if (dateArray) {
        return dateArray;
      }
    }
    if (text instanceof Date) {
      const inputDate = text;
      if (!isNaN(inputDate)) {
        var dateArray = new Array(inputDate.getFullYear(), inputDate.getMonth() + 1, inputDate.getDate(), inputDate.getHours(), inputDate.getMinutes(), inputDate.getSeconds());
        return dateArray;
      }
    } else {
      // 前後のスペースを取り除きます。
      text = text.replace(/^\s+/, "");
      text = text.replace(/\s+$/, "");

      // 全角数値を半角数値に変換します。
      text = _zenkakuNum2hankaku(text);

      text = replaceWarekiNengouFullnameToShortchar(text);
    }

    var year;
    if (text.match("^([0-9]{1,2})[^0-9年nNyY]") || text.match("^([0-9]{1,2})$")) {
        var i = parseInt(RegExp.$1,10);
        if (i >= 1 && i <= 12) {
            // 年は今年とし、月の入力として扱う。
            var curr = new Date();
            year = curr.getFullYear();
            text = "-" + text;
        } else {
            var ar = _getYearArrayFor3Token(text);
            year = ar[0]
            text = text.substring(ar[1][0].length);
        }
    } else {
        var ar = _getYearArrayFor3Token(text);
        year = ar[0]
        text = text.substring(ar[1][0].length);
    }
    var month;
    var day;
    var hour = -1;
    var minute = -1;
    var second = -1;
    var ret;

    var sepy = "[^0-9]"; // [-\/年]
    var sepm = "[^0-9]"; // [-\/月]
    var sepd = "[^0-9]";
    var seph = "[^0-9]";
    var sepMin = "[^0-9]";
    var pattern_ymdhms1 = sepy+"([01]?[0-9])"+sepm+"([0-3]?[0-9])"+sepd+"([0-2]?[0-9])"+seph+"([0-5]?[0-9])"+sepMin+"([0-5]?[0-9])";
    var pattern_ymdhm1 = sepy+"([01]?[0-9])"+sepm+"([0-3]?[0-9])"+sepd+"([0-2]?[0-9])"+seph+"([0-5]?[0-9])";
    var pattern_ymdh1 = sepy+"([01]?[0-9])"+sepm+"([0-3]?[0-9])"+sepd+"([0-2]?[0-9])";
    var pattern_ymd1 = sepy+"([01]?[0-9])"+sepm+"([0-3]?[0-9])[日]?";
    var pattern_ym1 = sepy+"([01]?[0-9])"+sepm+"?";
    var pattern_ymdhms2 = "([01][0-9])([0-3][0-9])([0-2][0-9])([0-5][0-9])([0-5][0-9])";
    var pattern_ymdhm2 = "([01][0-9])([0-3][0-9])([0-2][0-9])([0-5][0-9])";
    var pattern_ymdh2 = "([01][0-9])([0-3][0-9])([0-2][0-9])";
    var pattern_ymd2 = "([01][0-9])([0-3][0-9])";
    var pattern_ym2 = "([01][0-9])";
    if (strict) {
        // 日付に完全一致するかを評価する
    	pattern_ymdhms1 = "^"+pattern_ymdhms1+"$";
    	pattern_ymdhm1 = "^"+pattern_ymdhm1+"$";
    	pattern_ymdh1 = "^"+pattern_ymdh1+"$";
    	pattern_ymd1 = "^"+pattern_ymd1+"$";
    	pattern_ym1 = "^"+pattern_ym1+"$";
    	pattern_ymdhms2 = "^"+pattern_ymdhms2+"$";
    	pattern_ymdhm2 = "^"+pattern_ymdhm2+"$";
    	pattern_ymdh2 = "^"+pattern_ymdh2+"$";
    	pattern_ymd2 = "^"+pattern_ymd2+"$";
    	pattern_ym2 = "^"+pattern_ym2+"$";
    }

    if (text == "") {
        month = -1;
        day = -1;
    } else if (text.match(pattern_ymdhms1)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
        minute = parseInt(RegExp.$4, 10);
        second = parseInt(RegExp.$5, 10);
    } else if (text.match(pattern_ymdhm1)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
        minute = parseInt(RegExp.$4, 10);
    } else if (text.match(pattern_ymdh1)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
    } else if (text.match(pattern_ymd1)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
    } else if (text.match(pattern_ym1)) {
        month = parseInt(RegExp.$1,10);
        day = -1;
    } else if (text.match(pattern_ymdhms2)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
        minute = parseInt(RegExp.$4, 10);
        second = parseInt(RegExp.$5, 10);
    } else if (text.match(pattern_ymdhm2)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
        minute = parseInt(RegExp.$4, 10);
    } else if (text.match(pattern_ymdh2)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
        hour = parseInt(RegExp.$3, 10);
    } else if (text.match(pattern_ymd2)) {
        month = parseInt(RegExp.$1,10);
        day = parseInt(RegExp.$2, 10);
    } else if (text.match(pattern_ym2)) {
        month = parseInt(RegExp.$1,10);
        day = -1;
    } else if (strict) {
        // 日付に完全一致しない場合
        throw res.EXCEPTION_MSG_UNMATCHED + text;
    } else {
        month = -1;
        day = -1;
    }

    var ret = new Array(year, month, day, hour, minute, second);
    return ret;
}

/**
 * 日付フォーマットの正規表現オブジェクトを返す
 */
function getUserDefinedFormatRegExp(format) {
  var reStr = dateFormatRegExpStr[format];
  if (!reStr) {
    // ユーザ定義フォーマット
    return null;
  }
  return new RegExp(reStr);
}

/**
 * 短縮英語月名を数字に変換する
 * 数字の場合は、数値変換して返す
 */
function getMonthFromMonthMMMFormat(monthMMM) {
  for (var i=0; i<month_mmm_table.length; i++) {
    if (month_mmm_table[i] === monthMMM) {
      return (i + 1);
    }
  }
  var month = parseInt(monthMMM, 10);
  if (isNaN(month) || month < 1 || month > 12) {
    return -1;
  }
  return month;
}

/**
 * 日付フォーマットの情報を利用して日付文字を年月日を格納した配列に変換します。
 */
function createDateArrayWithDateFormat(text, format) {
  re = getUserDefinedFormatRegExp(format);
  if (!re) {
    return null;
  }
  // 年月日を正規表現で切り出す
  var splitDate = re.exec(text);
  // 日付フォーマットから年月日の情報を正規表現で切り出す
  var splitFormat = /(g{1,3}e{1,2}|y{2,4}|M{1,3}|d{1,2})?[.年月/-]?(g{1,3}e{1,2}|y{2,4}|M{1,3}|d{1,2})?[.年月/-]?(g{1,3}e{1,2}|y{2,4}|M{1,3}|d{1,2})?(?:\s)?(H{1,2})?:?(m{1,2})?:?(s{1,2})?/.exec(format);
  if (!splitDate || !splitFormat || splitDate[0] === "" || splitFormat[0] === "") {
    return null;
  }
  var result = {
    year: -1,
    month: 1,
    day: 1,
    hour: -1,
    minute: -1,
    second: -1
  };

  for (var i=1; i<splitFormat.length; i++) {
    var formatPart = splitFormat[i];
    if (!formatPart) {
      continue;
    }
    if (formatPart.indexOf("e") !== -1) {
      // 和暦を西暦に変換する
      result.year = _getYearFor3Token(replaceWarekiNengouFullnameToShortchar(splitDate[i]));
    } else if (formatPart === "MMM") {
      // 短縮英語月名を数字に変換する
      result.month = getMonthFromMonthMMMFormat(splitDate[i]);
    } else if (i === 1 && formatPart === "yy") {
      // yy/MM/dd フォーマットの場合、2桁年の値から4桁年の値を取得する
      result.year = _getYearFor3Token(splitDate[i]);
    } else {
      var resultKey;
      if (formatPart.indexOf("y") !== -1) {
        resultKey = "year";
      } else if (formatPart.indexOf("M") !== -1) {
        resultKey = "month";
      } else if (formatPart.indexOf("d") !== -1) {
        resultKey = "day";
      } else if (formatPart.indexOf("H") !== -1) {
        resultKey = "hour";
      } else if (formatPart.indexOf("m") !== -1) {
        resultKey = "minute";
      } else if (formatPart.indexOf("s") !== -1) {
        resultKey = "second";
      }
      // 年月日時刻の場合、数値変換する
      if (resultKey) {
        var value;
        if (resultKey === "year") {
          // 年の値を2桁省略入力を許容するため、入力値から4桁年の値を取得する
          value = _getYearFor3Token([splitDate[i]]);
        } else {
          value = parseInt(splitDate[i], 10);
        }
        result[resultKey] = value;
      }
    }
  }
  return new Array(result.year, result.month, result.day, result.hour, result.minute, result.second);
}

/**
 * 指定された日付を書式を指定して文字列にします。
 * formatに指定できる書式の例：
 * ggge年m月d日aaa曜日 - 平成5年3月4日水曜日
 * gge-m-d             - 平5-3-4
 * ge-m-d              - H5-3-4
 *
 * Excelで指定できる書式記号のうち、※マークのないものをサポートしている。
 * 書式記号     表示結果
 * yy           00～99（西暦の年）
 * yyyy         1900～9999（西暦の年）
 * [DBNum1]yyyy 一九〇〇～九九九九（年）※
 * [DBNum2]yyyy 壱九〇〇～九九九九（年）※
 * [DBNum3]yyyy １９００～９９９９（年）※
 * e            1～99（和暦の年）
 * ee           01～99（和暦の年）
 * g            H（元号のアルファベット）
 * gg           平（元号の1文字目）
 * ggg          平成（元号）
 * [DBNum1]ggge 平成一～平成九十九（年）※
 * [DBNum2]ggge 平成壱～平成九拾九（年）※
 * [DBNum3]ggge 平成１～平成９９（年）※
 * r            01～（和暦の年） # eeと同じ？
 * rr           平成01～（元号つき和暦の年） # gggeeと同じ？
 * m            1～12（月の数字表記）
 * mm           01～12（月の数字表記）
 * mmm          Jan～Dec（月の短縮英語表記）※
 * mmmm         January～December（月の英語表記）※
 * mmmmm        J～D（月のアルファベット1文字目）※
 * d            1～31（日）
 * dd           01～31（日）
 * ddd          sun～sat（曜日の短縮英語表記）
 * dddd         Sunday～Satrday（曜日の英語表記）
 * aaa          日～土（曜日の日本語1文字表記）
 * aaaa         日曜日～土曜日（曜日の日本語表記）
 *
 * [wagby:reki_japanoldstyle]
 *              旧暦モードにする。
 *              和暦は元年の1月1日から開始される。
 *              使用するには、qreki.jsを読み込む必要がある。
 * [wagby:reki_default]
 *              通常の暦に戻す。
 * rokuyo       六曜。使用するには、qreki.jsを読み込む必要がある。
 */
function formatDateObject(d,format) {
    if (!d) {
      return "";
    }
    var dfullyear = d.getFullYear();
    var dmonth = d.getMonth();
    var ddate = d.getDate();
    var dhours = d.getHours();
    var dminutes = d.getMinutes();
    var dseconds = d.getSeconds();
    var default_warekicode = getWarekiNengouCode(d);
    var dwarekicode = default_warekicode;

    var japanoldstyle_date;
    if (format.indexOf("[wagby:reki_japanoldstyle]") >= 0) {
        japanoldstyle_date = new kyureki(d.getJD());
    }

    var ret = "";
    var i;
    for (i=0;i<format.length;) {
        if (format.indexOf("[wagby:reki_japanoldstyle]",i) == i) {
            dfullyear = japanoldstyle_date.year;
            dmonth = japanoldstyle_date.month-1;
            ddate = japanoldstyle_date.day;
            dwarekicode = getWarekiNengouCodeByYear(dfullyear);
            i += 26;
        } else if (format.indexOf("[wagby:reki_default]",i) == i) {
            dfullyear = d.getFullYear();
            dmonth = d.getMonth();
            ddate = d.getDate();
            dwarekicode = default_warekicode;
            i += 20;
        } else if (format.indexOf("yyyy",i) == i) {
            ret += dfullyear;
            i += 4;
        } else if (format.indexOf("yy",i) == i) {
            ret += get2ketastr(dfullyear);
            i += 2;
        } else if (format.indexOf("ggg",i) == i) {
            if (dwarekicode >= 0) {
                ret += wareki_fullname_a[dwarekicode];
            }
            i += 3;
        } else if (format.indexOf("gg",i) == i) {
            if (dwarekicode >= 0) {
                ret += wareki_fullname_a[dwarekicode].charAt(0);
            }
            i += 2;
        } else if (format.indexOf("g",i) == i) {
            if (dwarekicode >= 0) {
                ret += wareki_shortcharpattern_a[dwarekicode].charAt(0);
            }
            i++;
        } else if (format.indexOf("ee",i) == i) {
            ret += get2ketastr(getWarekiYear(dwarekicode,dfullyear));
            i+=2;
        } else if (format.indexOf("e",i) == i) {
            ret += getWarekiYear(dwarekicode,dfullyear);
            i++;
        } else if (format.indexOf("rokuyo",i) == i) {
            if (japanoldstyle_date == null) {
                japanoldstyle_date = new kyureki(d.getJD());
            }
            ret += japanoldstyle_date.rokuyo;
            i+=6;
        } else if (format.indexOf("rr",i) == i) {
            if (dwarekicode >= 0) {
                ret += wareki_fullname_a[dwarekicode];
            }
            ret += get2ketastr(getWarekiYear(dwarekicode,dfullyear));
            i+=2;
        } else if (format.indexOf("r",i) == i) {
            ret += get2ketastr(getWarekiYear(dwarekicode,dfullyear));
            i++;
        } else if (format.indexOf("MMM",i) == i) {
            if (browser_locale.lastIndexOf("en", 0) == 0) {
                ret += month_mmm_table[dmonth];
            } else {
                ret += (dmonth+1);
            }
            i+=3;
        } else if (format.indexOf("MM",i) == i) {
            ret += get2ketastr(dmonth+1);
            i+=2;
        } else if (format.indexOf("M",i) == i) {
            ret += (dmonth+1);
            i++;
        } else if (format.indexOf("dddd",i) == i) {
            ret += youbi_dddd_table[d.getDay()];
            i += 4;
        } else if (format.indexOf("ddd",i) == i) {
            ret += youbi_ddd_table[d.getDay()];
            i += 3;
        } else if (format.indexOf("dd",i) == i) {
            ret += get2ketastr(ddate);
            i += 2;
        } else if (format.indexOf("d",i) == i) {
            ret += ddate;
            i++;
        } else if (format.indexOf("aaaa",i) == i) {
            ret += youbi_aaa_table[d.getDay()] + res.FORMAT_DATE_YOUBI;
            i += 4;
        } else if (format.indexOf("aaa",i) == i) {
            ret += youbi_aaa_table[d.getDay()];
            i += 3;
        } else if (format.indexOf("HH",i) == i) {
            ret += get2ketastr(dhours);
            i += 2;
        } else if (format.indexOf("mm",i) == i) {
            ret += get2ketastr(dminutes);
            i += 2;
        } else if (format.indexOf("ss",i) == i) {
            ret += get2ketastr(dseconds);
            i += 2;
        } else {
            ret += format.substring(i,i+1);
            i++;
        }
    }
    return ret;
}

function get2ketastr(i) {
    var s = ""+i;
    if (s.length == 0) return "00";
    if (s.length == 1) return "0"+s;
    if (s.length == 2) return s;
    return s.substring(s.length-2);
}

/**
 * 入力可・不可の制御対象コントロールと条件を保持するクラス
 */
var TargetCtrl = function() {
  this.initialize.apply(this, arguments);
}
TargetCtrl.prototype = {
  //コンストラクタ
  initialize: function(ctrl, flag, values) {
    this.ctrl = ctrl;     //制御対象コントロール
    this.flag = flag;     //制御フラグ(入力可:enable|入力不可:disable|表示:displayinline|非表示:displaynone)
    this.values = values; //条件値(複数指定可能とするため配列が引き渡される)
  },

  getCtrl: function() {
    return this.ctrl;
  },

  getFlag: function() {
    return this.flag;
  },

  getConditionValues: function() {
    return this.values;
  },

  //条件値によりコントロールの入力可、表示・不可、非表示を切り替える
  changeDisabled: function(srcCtrlValues) {
    var switchtype = 1;
    var disableFlag = true;

    //switchtypeとdisable フラグの初期値を設定する
    //enable,displayinline:条件が成立した時に入力可、表示になるため、初期値は入力不可、非表示にする
    //disable,displaynone:条件が成立した時に入力不可、非表示になるため、初期値は入力可、表示にする
    if (this.getFlag() == "enabled") {
      switchtype = 1;
      disableFlag = true;
    } else if (this.getFlag() == "disabled") {
      switchtype = 1;
      disableFlag = false;
    } else if (this.getFlag() == "displayinline") {
      switchtype = 2;
      disableFlag = true;
    } else if (this.getFlag() == "displaynone") {
      switchtype = 2;
      disableFlag = false;
    }

    //入力可・不可の条件値
    var conditionValues = this.getConditionValues();

    //条件が成立した時には disable フラグを反転させる
    //enable:入力不可→入力可
    //disable:入力可→入力不可
    EXIT:
    for (var i=0,l=conditionValues.length; i<l; i++) {
      for (var j=0,m=srcCtrlValues.length; j<m; j++) {
        //条件の値が空文字の場合
        if (conditionValues[i].length == 0) {
          //制御元に入力があれば条件成立
          if (srcCtrlValues[j].length != 0) {
            disableFlag = !disableFlag;
            break EXIT;
          } else {
            //条件不成立の場合には次の条件値を調べる
            continue;
          }
        }
        //条件の値が空文字以外の場合
        if (conditionValues[i] == srcCtrlValues[j]) {
          disableFlag = !disableFlag;
          break EXIT;
        }
      }
    }
    //制御対象のコントロールの disabled プロパティをセットする
    var ctrls = this.getCtrl();
    for (var i=0,l=ctrls.length; i<l; i++) {
      if (switchtype == 1) {
        this.changeDisabled1(ctrls[i], disableFlag);
      } else if (switchtype == 2) {
        this.changeDisabled2(ctrls[i], disableFlag);
      }
    }
  },
  changeDisabled1: function(ctrl, disableFlag) {
    // BR4946 2009.09.25
    // ストアモデル参照(検索画面)のボタンの入力可・不可制御対応
    // BR5377 2010.03.24
    // ファイル名項目のクリアボタン(submit)対応
    if (ctrl.type == 'button' || ctrl.type == 'submit') {
        // 対象コントロールがボタンの場合、Dojo の dijit ライブラリで制御を行なう
        // BR5696 2010.10.07
        // Dojo 1.5.0 から dijit.form.Button の button タグがid 属性のない
        // input タグへ変更になったため、代わりに name 属性から取得するよう
        // に修正しました
        // また、setDisabled メソッドが廃止になったため、set(name, value)
        // メソッドへ変更しました
        dijit.byId(ctrl.name).set('disabled', disableFlag);
    } else if (ctrl.nodeName.toUpperCase() == "DIV") {
        // use rich text, dijit.Editor
        var dijitEditor = dijit.byId(ctrl.id);
        if (dijitEditor) {
          dijitEditor.set('disabled', disableFlag);
        }
    } else {
        // 数値型の入力項目が hidden となっているため、id で取得できない場合は
        // name でも取得してみる
        var widget = dijit.registry.byId(ctrl.id) || dijit.registry.byId(ctrl.name);
        if (widget) {
          widget.set("disabled", disableFlag);
        } else {
          ctrl.disabled = disableFlag;
        }
    }
  },
  changeDisabled2: function(ctrl, disableFlag) {
    var widget = dijit.byId(ctrl.id) || dijit.byId(ctrl.name);
    if (widget) {
      if (disableFlag) {
        // 非表示にする。
        widget.domNode.style.display = "none";
      } else {
        // 表示する。
        widget.domNode.style.display = "inline-block";
      }
    } else {
      console.log("widget not found");
    }
  }
};
/**
 * コントロールの入力可・不可を制御するクラス
 */
var CtrlDisableManager = function() {
  this.initialize.apply(this, arguments);
}
//コントロールの入力可・不可を制御するクラスの関数プロトタイプ宣言
CtrlDisableManager.prototype = {
  //コンストラクタ
  initialize: function(srcCtrlName) {
    //制御元コントロールを保持する配列
    this.srcCtrls = new Array();
    //制御元コントロールの名称を取得する
    var ctrlsName = this.getCtrlsName(srcCtrlName);
    //取得した制御元コントロールをインスタンス変数へ追加する
    var srcCtrl;
    for (var i=0,l=ctrlsName.length; i<l; i++) {
      var name = ctrlsName[i];
      if (name.lastIndexOf("content_", 0) === 0) {
        srcCtrl = [document.getElementById(name)];
      } else {
        srcCtrl = document.getElementsByName(name);
      }
      for (var j=0,m=srcCtrl.length; j<m; j++) {
        this.srcCtrls.push(srcCtrl[j]);
      }
    }
    //制御対象コントロールを保持する配列
    this.targetCtrls = new Array();
  },

  //制御対象コントロールを追加するメソッド
  addTargetCtrl: function(targetCtrlName, flag, value) {
    //制御対象コントロールの名称を取得する
    var targetCtrlsName = this.getCtrlsName(targetCtrlName);
    //制御対象コントロールを追加する
    for (var i=0,l=targetCtrlsName.length; i<l; i++) {
      var suggest = document.getElementById("_" + targetCtrlsName[i] + "_content_displayed");
      if (suggest) {
        this.targetCtrls.push(new TargetCtrl(new Array(suggest), flag, value));
      } else {
        var targetCtrl = document.getElementsByName(targetCtrlsName[i]);
        if (targetCtrl != null && targetCtrl.length > 0) {
          this.targetCtrls.push(new TargetCtrl(targetCtrl, flag, value));
        }
      }
      var targetCtrl_editor = document.getElementById(targetCtrlsName[i]+"_editor");
      if (targetCtrl_editor != null) {
        var a = new Array(1);
        a[0] = targetCtrl_editor;
        this.targetCtrls.push(new TargetCtrl(a, flag, value));
      }
      var subwindowTextbox = document.getElementById("_" + targetCtrlsName[i] + "_content");
      if (subwindowTextbox) {
        this.targetCtrls.push(new TargetCtrl(new Array(subwindowTextbox), flag, value));
      }
    }
  },

  //制御元コントロールで選択された値を取得する
  getSrcCtrlValues: function() {
	//制御元コントロールで選択された値を保持する配列
	var srcCtrlValues = new Array();
    for (var i=0,l=this.srcCtrls.length; i<l; i++) {
      var ctrl = this.srcCtrls[i];
      var ctrlType = ctrl.type;
      var value = ctrl.value;
      //選択された値を配列へ追加する
      if ((ctrlType == 'text') || (ctrlType == 'textarea') || (ctrlType == 'file') ||
		  (ctrlType == 'select-one') || (ctrlType == 'hidden')) {
        srcCtrlValues.push(value);
      } else if ((ctrlType == 'radio') || (ctrlType == 'checkbox')) {
        require(["dijit/registry"], function(registry) {
          var widget = registry.byId(ctrl.id);
          if (widget && widget.get('checked')) {
            srcCtrlValues.push(value);
          }
        });
      } else if (!ctrlType && ctrl.tagName === 'SPAN') {
        var value = ctrl.innerText;
        if (value) {
          srcCtrlValues.push(value.trim());
        }
	  }
    }
    return srcCtrlValues;
  },

  //制御対象コントロールの disabled 属性を変更するメソッド
  //条件に一致する
  changeTargetCtrlDisabled: function() {
    //制御対象コントロールで選択された値を取得する
    require(["dojo/topic"], (topic) => {
      const srcCtrlValues = this.getSrcCtrlValues();
      //制御対象のコントロール全ての条件をチェックする
      for (var i=0,l=this.targetCtrls.length; i<l; i++) {
        var targetCtrl = this.targetCtrls[i];
        targetCtrl.changeDisabled(srcCtrlValues);
        const message = `{"targetCtrlId": "${targetCtrl.ctrl[0].id || targetCtrl.ctrl[0].name}", "disabled": "${targetCtrl.flag}"}`;
        topic.publish("CtrlDisableManager", message);
      }
      topic.publish("CtrlDisableManager", "done");
    });
  },

  //引数のコントロール名が存在するフォームのインデックス値を返すメソッド
  getFormIndexContainsByName: function(ctrlName) {
    var formIndex = 0;

    //フォームが 1 つだけの場合 0 を返して終了
    if (document.forms.length == 1) {
      return 0;
    }

    EXIT:
    for (var i=0,l=document.forms.length; i<l; i++) {
      var elements = document.forms[i].elements;
      for (var j=0,m=elements.length; j<m; j++) {
        if (!elements[j].name) {
          continue;
        }
        var matchedCtrlName = (elements[j].name).match(ctrlName);
        if (matchedCtrlName != null) {
          formIndex = i;
          break EXIT;
        }
      }
    }
    return formIndex;
  },

  //引数で指定したコントロールの名称を返す
  //正規表現型で指定された場合のため、正規表現にマッチするコントロールの名称を配列に入れて返す
  //文字列型で指定された場合、そのまま名称を配列に入れて返す
  getCtrlsName: function(ctrlName) {
    if (Array.isArray(ctrlName)) {
      return ctrlName;
    }
    var ctrlsName = new Array();

    if (typeof(ctrlName) == 'string') {
      ctrlsName[0] = ctrlName;
    } else if (ctrlName instanceof RegExp) {
      //引数のタイプが正規表現の場合、フォーム内の全コントロールの name 属性を
      //正規表現で検索を行ないマッチしたコントロールの name を配列へ保持する
      var formIndex = this.getFormIndexContainsByName(ctrlName);
      var ctrls = document.forms[formIndex].elements;

      for (var i=0,l=ctrls.length; i<l; i++) {
        var matchedCtrlName = (ctrls[i].name).match(ctrlName);
        if (matchedCtrlName != null) {
          ctrlsName.push(matchedCtrlName);
        }
      }
    }
    return ctrlsName;
  },

  //制御元コントロールにイベントを登録する
  addEvent: function(me) {
    var that = this;
    var eventSetClearButton;
    for (var i=0,l=this.srcCtrls.length; i<l; i++) {
      var fireEvent;
      var id = this.srcCtrls[i].id || this.srcCtrls[i].name;
      // Dojo の Widget を取得する
      var ctrl = dijit.registry.byId(id);
      if (!ctrl) {
        continue;
      }
      if (ctrl.declaredClass === "dijit.form.CheckBox" || ctrl.declaredClass === "dijit.form.RadioButton") {
        // チェックボックス、ラジオボタンの場合
        var clearButtonId = this.srcCtrls[i].name;
        var count = 0;
        if (ctrl.declaredClass === "dijit.form.RadioButton") {
          // 繰り返しコンテナ内のクリアボタンのIDはチェックボックスと同様項目IDのみとなるため、
          // 2番目の_005b以降の文字列を削除する
          count = (clearButtonId.match(/\_005b/g) || []).length;
        }
        if (ctrl.declaredClass === "dijit.form.CheckBox" || count === 2) {
          clearButtonId = this.srcCtrls[i].name.substring(0, this.srcCtrls[i].name.lastIndexOf("_005b"));
        }
        var clearButton = this.getClearButton(clearButtonId);
        if (eventSetClearButton !== clearButton && clearButton && clearButton.iconClass === "clearButtonIcon") {
          clearButton.on("click", function() {
            that.changeTargetCtrlDisabled();
          });
          eventSetClearButton = clearButton;
        }
        fireEvent = "change";
      } else if (ctrl.declaredClass === "dijit.form.Select" || ctrl.type === "file") {
        // リストボックス、ファイル型の場合
        fireEvent = "change";
      } else if (ctrl.declaredClass === "dijit.form.ValidationTextBox" || ctrl.declaredClass === "dijit.form.NumberTextBox" ||
          ctrl.baseClass === "dijitTextBox dijitTextArea") {
        // テキストボックス、数値入力テキストボックス、テキストエリアの場合
        fireEvent = "keyup";
        ctrl.on("blur", function() {
          that.changeTargetCtrlDisabled();
        });
      } else {
        fireEvent = "change";
      }
      ctrl.on(fireEvent, function() {
        that.changeTargetCtrlDisabled();
      });
    }
  },

  getClearButton: function(id) {
    var clearButton;
    require(["dijit/registry"], function(registry) {
      clearButton = registry.byId("btnClear_" + id);
    });
    return clearButton;
  }
};

function getElementValueByName(f, name) {
  var e = f.elements[name];
  if (e == null) {
      // checkbox ? ...
      return getElementValueByName_checkbox(f, name);
  }
  var element = e[0];
  if (element == null) {
      element = e;
  }
  if (element.type == 'radio') {
      for (var j=0,m=e.length; j<m; j++) {
        if (e[j].checked) {
          return e[j].value;
        }
      }
  } else if (element.type == 'checkbox') {
      // ignore case
  } else if (element.type == 'select-one') {
      // case of dualinput
      if (e[1] != null && e[1].value !=null && e[1].value != '') {
          return e[1].value;
      } else if (e[0].value != null && e[0].value != '') {
          return e[0].value;
      } else {
          return null;
      }
  } else {
    // Dojo のウィジェットから値を取得する
    var value;
    require(["dijit/registry"], function(registry) {
      var widget = registry.byId(name);
      if (widget) {
        if (widget.baseClass.indexOf("DateTextBox") !== -1 ||
            widget.baseClass.indexOf("dijitComboBox") !== -1) {
          value = widget.get("displayedValue");
        } else {
          value = widget.get("value");
        }
      }
    });
    if (value) {
      return value;
    }
    if (e.value != null && e.value != '') {
      return e.value;
    } else {
      return null;
    }
  }
  return null;
}

function getElementValueByName_checkbox(f, name) {
  var values = new Array();
  name += "_005b";
  for (var j=0,m=f.length; j<m; j++) {
    var e = f.elements[j];
    if (e.name.indexOf(name) == 0) {
      if ((e.type == "checkbox" && e.checked == true) || e.type == "hidden") {
        values.push(e.value);
      }
    }
  }
  return values;
}

function createActionParam(name, values) {
  if (values instanceof Array) {
      if (values[0] != null && values[0] != '') {
          return "&" + name + "=" + encodeURIComponent(values[0]);
      }
  } else {
      if (values != null && values != '') {
          return "&" + name + "=" + encodeURIComponent(values);
      }
  }
  return "";
}

function createActionParam_checkbox(name, values) {
  var actionParam = "";
  if (values instanceof Array) {
    for (var j=0,m=values.length; j<m; j++) {
      if (values[j] != null && values[j] != '') {
        actionParam += "&" + name + "_005b" + values[j] + "_005d_002f_0040id="+values[j];
      }
    }
    return actionParam;
  }

  return "&" + name + "_005b" + values + "_005d_002f_0040id="+values;
}

// 指定した年月の最後の日を返します。
function getLastDayOfThisMonth(year, month) {
  // 0日は「前月末日」として扱われる
  const d = new Date(year, month + 1, 0);
  return d.getDate();
}

function changeSizePerPageComboOff() {
  var d = window.document;
  var length = d.forms.length;

  for (var i=0,l=length; i<l; i++) {
    var f = d.forms[i];
    for (var j=0,m=f.length; j<m; j++) {
      var e = f.elements[j];
      if ((e.type == "submit" || e.type == "button") && e.name != "__jfc_changeSizePerPage") {
        e.disabled = true;
      } else if (e.name == "__jfc_size_per_page0") {
	f.__jfc_size_per_page.value = e.options[e.selectedIndex].value;
        e.disabled = true;
      }
    }
  }
}

function isIE() {
  if (navigator.userAgent.indexOf("MSIE") == -1) {
    return false;
  }
  return true;
}
function getIEVersion() {
  navigator.appVersion.match(/MSIE (\d\.\d)/);
  return parseFloat(RegExp.$1);
}
function getShimedElement(id) {
    var ifrmhtml = "<iframe src='javascript:false;' " +
                   "scrolling='no' frameborder='0'" +
                   "style='position:absolute; top:0px;" +
                   "left:0px; z-index: -1; filter:Alpha(Opacity=\"0\");'></iframe>";
    ifrm = document.createElement(ifrmhtml);
    ifrm.tabIndex = -1;
	var width = document.getElementById(id).offsetWidth - 1;
    ifrm.style.setExpression("width", width);
    ifrm.style.setExpression("height", "document.getElementById(id).offsetHeight");
	return ifrm;
}
function setShim2Element(id) {
	element = document.getElementById(id);
	element.appendChild(getShimedElement(id));
}
//カレンダーポップアップの DIV 要素に iframe を追加する
//
//IE 7 以前のバージョンでリストボックスがカレンダーポップアッ
//プ画面を透過して表示されるバグを回避するため
function setShim2Calendar() {
  var calendar = document.getElementById("calendar");
  if (!calendar) {
    return;
  }
  if (!isIE()) {
    return;
  }
  if (getIEVersion() < 7) {
    var ifrmhtml="<iframe src='javascript:false;' "+
          "scrolling='no' frameborder='0'"+
          "style='position:absolute; top:0px;"+
          "left:0px; z-index: -1; filter:Alpha(Opacity=\"0\");'></iframe>";
    ifrm = document.createElement(ifrmhtml);
    ifrm.tabIndex = -1;
    ifrm.style.setExpression("width", "document.getElementById('calendar').offsetWidth");
    ifrm.style.setExpression("height", "document.getElementById('calendar').offsetHeight");
    calendar.appendChild(ifrm);
  }
}

//Dojo dijit.layout.TabContainer 用の関数
//選択されたタブをクッキーに保存する
function setSelectedTabId(key, tabId) {
  if (tabId) {
    require(["dojo/cookie"], function(cookie) {
      cookie(key, tabId);
    });
  }
  //選択されていたサブメニューを表示する
  showSubMenu(getVisibleMenuId(), getInvisibleMenuId());
}
//クッキーから選択されたタブを取得する
function getSelectedTabId(key) {
  var selectedTabId;
  require(["dojo/cookie"], function(cookie) {
    selectedTabId = cookie(key);
  });
  return selectedTabId;
}

//メニューリンクをクリックした際に、選択していたサブメニューを
//再表示するため、選択されたサブメニュー、非表示にするメニュー
//のMenuId をクッキーに保存しておく
function setSubMenuId(visibleMenuId, invisibleMenuId) {
  require(["dojo/cookie"], function(cookie) {
    cookie("visibleMenu", visibleMenuId);
    cookie("invisibleMenu", invisibleMenuId);
  });
}
function getVisibleMenuId() {
  var visibleMenuId;
  require(["dojo/cookie"], function(cookie) {
    visibleMenuId = cookie("visibleMenu");
  });
  return visibleMenuId;
}
function getInvisibleMenuId() {
  var invisibleMenuId;
  require(["dojo/cookie"], function(cookie) {
    invisibleMenuId = cookie("invisibleMenu");
  });
  return invisibleMenuId;
}
function removeSubMenuCookies() {
  require(["dojo/cookie"], function(cookie) {
    cookie('visibleMenu', null, {expires: -1});
    cookie('invisibleMenu', null, {expires: -1});
  });
}
function showSubMenu(visibleMenuId, hiddenMenuId) {
  const hiddenMenu = document.getElementById(hiddenMenuId);
  const visibleMenu = document.getElementById(visibleMenuId);
  if (!hiddenMenu || !visibleMenu) {
    return;
  }
  setSubMenuId(visibleMenuId, hiddenMenuId);
  const selectedTabId = getSelectedTabId("mainMenuSelectedTab") || "menuTab1";
  const submenus = Array.from(document.querySelectorAll(`div[id='${selectedTabId}'] nav[id^='menuId']`));
  const isContainHiddenMenu = submenus.some((submenu) => submenu.id === hiddenMenuId);
  // 選択されたタブ内に非表示にするサブメニューがない場合は何もしない
  if (!isContainHiddenMenu) {
    return;
  }
  // 選択されたメニュータブ内のサブメニューを一旦全て非表示にする
  submenus.forEach((submenu) => submenu.style.display = "none");
  // 表示するサブメニューのみ、display 属性の none を外す
  visibleMenu.style.display = "flex";
}
//OnLoad 時にタブが選択された状態にする
function selectTabOnLoad(tabContainerId, key, defaultTab) {
  require(["dijit/registry", "dojo/ready"], function(registry, ready) {
    ready(function() {
      var tabContainer = registry.byId(tabContainerId);
      if (!tabContainer) {
        return;
      }
      var id = getSelectedTabId(key);
      if (!id) {
        if (defaultTab && registry.byId(defaultTab)) {
          // デフォルトのタブが選択可能な場合、デフォルトタブを選択状態にする
          id = defaultTab;
        } else {
          // id が取得できずデフォルトタブの指定も無い場合、1番目のタブを選択状態にする
          var firstTab = tabContainer.getChildren()[0];
          if (firstTab) {
            id = firstTab.id;
          }
        }
      }
      var selectedTab = registry.byId(id);
      if (id && selectedTab) {
        //サブメニューの MenuId を取得する
        var visibleMenuId = getVisibleMenuId();
        var invisibleMenuId = getInvisibleMenuId();
        if (visibleMenuId && invisibleMenuId) {
          //選択されていたサブメニューを表示する
          showSubMenu(visibleMenuId, invisibleMenuId);
        }
        tabContainer.selectChild(id);
      }
    });
  });
}
//TabContainer 用のクッキーを削除する
function removeTabCookies() {
  if (window.localStorage) {
    window.localStorage.clear();
  }
  require(["dojo/cookie"], function(cookie) {
    cookie('mainMenuSelectedTab', null, {expires: -1});
    cookie('calendarConditionTabContainer', null, {expires: -1});
  });
  removeSubMenuCookies();
}

//ナビゲーションバーのボタン用
function submitNavigationCommand(form, action, name, target) {
  if (action) {
    document.forms[form].action = action;
  }
  if (name) {
    document.forms[form].SENDACTION.name = name;
  }
  if (target && target !== 'null') {
    document.forms[form].target = target;
    document.forms[form].submit();
    document.forms[form].elements[name].name = "SENDACTION";
  } else {
    document.forms[form].target = '_self';
    buttonOff();
    document.forms[form].submit();
  }
}

//ナビゲーションバーのボタン用
function submitNavigationCommand_skipButtonOff(form, action, name, target) {
  if (action) {
    document.forms[form].action = action;
  }
  if (name) {
    document.forms[form].SENDACTION.name = name;
  }
  if (target && target !== 'null') {
    document.forms[form].target = target;
    document.forms[form].submit();
    document.forms[form].elements[name].name = "SENDACTION";
  } else {
    document.forms[form].target = '_self';
    document.forms[form].submit();
  }
}

//一覧表示画面における一括処理チェックボックスの一斉ON/OFF処理
function toggleJshCheckBox(form, checkedValue) {
  require(["dijit/registry"], function(registry) {
    for (var i=0,l=form.length; i<l; i++) {
      var e = form.elements[i];
      if (e.type !== 'checkbox' || e.name.indexOf('_jsh_cb') === -1) {
        continue;
      }
      var widget = registry.byId(e.id);
      if (widget) {
        widget.set("checked", checkedValue);
      } else {
        e.checked = checkedValue;
      }
    }
  });
}

//一覧表示画面における一括処理チェックボックスの数
function countJshCheckBox(form) {
  var count = 0;
  require(["dijit/registry"], function(registry) {
    for (var i=0,l=form.length; i<l; i++) {
      var e = form.elements[i];
      if (e.type !== 'checkbox' && e.name.indexOf('_jsh_cb') === -1) {
        continue;
      }
      if (e.checked) {
        count++;
      }
    }
  });
  return count;
}

function getWidgetsInTabContainer(tabContainer) {
  var widgetsInTabContainer = [];
  // 初期表示されているタブ内の widget を優先するため、非表示のタブ内の
  // widget を保持する配列
  var widgetsInUnselectedTab = [];
  var tabs = tabContainer.getChildren();
  for (var i=0,l=tabs.length; i<l; i++) {
    var widgets = tabs[i].getChildren();
    if (tabs[i].get("selected")) {
      for (var j=0,m=widgets.length; j<m; j++) {
        if (widgets[j].declaredClass === "dijit.layout.TabContainer") {
          Array.prototype.push.apply(widgetsInTabContainer, getWidgetsInTabContainer(widgets[j]));
        } else {
          widgetsInTabContainer.push(widgets[j]);
        }
      }
    } else if (!tabs[i].get("selected") && !this.ignoreWidgetsInUnselectedTab) {
      for (var j=0,m=widgets.length; j<m; j++) {
        if (widgets[j].declaredClass === "dijit.layout.TabContainer") {
          Array.prototype.push.apply(widgetsInTabContainer, getWidgetsInTabContainer(widgets[j]));
        } else {
          widgetsInUnselectedTab.push(widgets[j]);
        }
      }
    }
  }
  // 非表示のタブ内の widget を追加する
  Array.prototype.push.apply(widgetsInTabContainer, widgetsInUnselectedTab);
  return widgetsInTabContainer;
}

function getAllInputWidgets(isAcceptHidden) {
  return getAllWidgets(function(widget) {
    if (isAcceptHidden === true && widget.type === "hidden") {
      return true;
    }
    if (widget.type === "button" ||
        !widget.type ||
        (widget.name && widget.name === "__jfc_size_per_page0")) {
      return false;
    }
    return true;
  });
}

function getAllWidgets(filterFunc, noDialogContents) {
  var allWidgets = [];
  require(["dijit/registry", "dojo/_base/array", "dojo/dom"], function(registry, array, dom) {
    for (var i=0,l=document.forms.length; i<l; i++) {
      const form = document.forms[i];
      if (noDialogContents && form.parentNode.className === "dijitDialogPaneContent") {
        continue;
      }
      var widgets;
      var id = form.id;
      if (id) {
        widgets = registry.findWidgets(dom.byId(id));
      }
      if (!widgets || widgets.length === 0) {
        continue;
      }
      for (var j=0,m=widgets.length; j<m; j++) {
        // widget がタブコンテナの場合は、タブ内部の widget を取得する
        if (widgets[j].declaredClass === "dijit.layout.TabContainer" ||
            widgets[j].declaredClass === "dojox.mobile.RoundRect") {
          Array.prototype.push.apply(allWidgets, getWidgetsInTabContainer(widgets[j]));
        } else if (widgets[j].declaredClass === "wagby.TitlePane") {
          Array.prototype.push.apply(allWidgets, widgets[j].getChildren());
        } else {
          allWidgets.push(widgets[j]);
        }
      }
    }
    if (filterFunc) {
      allWidgets = array.filter(allWidgets, filterFunc);
    }
  });
  return allWidgets;
}

/**
 * Enterキーの取り扱いを制御するクラス
 */
var EnterKeyHandler = function() {
  this.initialize.apply(this, arguments);
}
EnterKeyHandler.prototype = {
  //コンストラクタ
  initialize: function(args) {
    // フォーカス移動対象の要素を保持する連想配列
    // key：name 属性値
    // value：フォーカス対象となる要素
    this.targetElements = new Array();
    // Shift+Enter でフォーカス移動する対象を保持する連想配列
    this.previousTargetElements = new Array();
    // Enterキーを無視する要素名を保持する配列
    this.ignoreElementNames = new Array();
    // Enterキーを無視する要素名をセットする
    this.setIgnoreElements(args);
    // 選択されていないタブ内の入力欄にはフォーカス移動しないフラグ
    // デフォルトでは選択されていないタブ内の入力欄にフォーカス移動する
    this.ignoreWidgetsInUnselectedTab = false;
    if (args && args.ignoreWidgetsInUnselectedTab !== undefined) {
      this.ignoreWidgetsInUnselectedTab = args.ignoreWidgetsInUnselectedTab;
    }
    var that = this;
    // 隠し項目、読み取り専用、無視する要素名として
    // 設定された項目は追加しない
    var targetWidgets = getAllWidgets(function(widget) {
      if (widget.id && widget.id !== "" &&
          widget.name && widget.name !== "" &&
          widget.type !== "hidden" && !widget.get("readOnly") &&
          widget.declaredClass !== "wagby.ReferenceLinkage" &&
          widget.tabIndex !== "-1" &&
          !that.isIgnoreElement(widget.name)) {
        return true;
      } else {
        return false;
      }
    }, true);
    // フォーカス対象となる要素の数
    this.targetElementsLength = targetWidgets.length;
    sortWidgetsByTabindex(targetWidgets);

    // 先頭の入力欄の id または name 属性をセットする
    let previousElementName = this.getElementName(targetWidgets[0]);
    for (var i=1,l=targetWidgets.length; i<l; i++) {
      // Enter キー押下時の移動先の入力欄をセットする
      this.targetElements[previousElementName] = targetWidgets[i];
      previousElementName = this.getElementName(targetWidgets[i]);
      // Shift+Enter キー押下時の移動先の入力欄をセットする
      this.previousTargetElements[previousElementName] = targetWidgets[i - 1];
    }
    // 最後の要素の Enter キー押下時の移動先は先頭要素
    this.targetElements[previousElementName] = targetWidgets[0];
    // 先頭の要素の Shift+Enter キー押下時の移動先は最終要素
    this.previousTargetElements[this.getElementName(targetWidgets[0])] = targetWidgets[this.targetElementsLength - 1];
  },

  getElementName: function(widget) {
    return widget.id || widget.name;
  },

  // フォーカス対象となる要素を取得する
  getNextElement: function(focusedElement, isReverse, callCount) {
    var id = this.getElementName(focusedElement);
    callCount = callCount || 0; // デフォルト値をセット
    var nextElement = isReverse ? this.previousTargetElements[id] : this.targetElements[id];
    if (!nextElement) {
      return null;
    }
    if (nextElement.type === 'radio') {
      nextElement = this.getNextElementOfRadio(focusedElement, isReverse, nextElement);
    }
    var tabIndex;
    require(["dojo/dom-attr"], function(domAttr) {
      tabIndex = domAttr.get(nextElement, "tabIndex");
    });
    // 入力不可、読み取り専用、tabIndex が -1、タブ内で利用不可(タブが非表示、disable)の場合、
    // さらに次の要素を取得する
    if (nextElement.disabled || nextElement.readOnly || tabIndex === "-1" ||
        !this.isWidgetAvailable(nextElement)) {
      if (callCount > this.targetElementsLength) {
        // 呼び出し回数がフォーカス対象項目数を超えた場合は終了させる
        return null;
      }
      return this.getNextElement(nextElement, isReverse, callCount++);
    }
    return nextElement;
  },

  getNextElementOfRadio: function(focusedElement, isReverse, element) {
    var nextElement = element;
    if (focusedElement.type === 'radio') {
      // ラジオボタンでEnterキーを押下した場合は、ラジオボタン項目の
      // 次の項目を返す
      while(focusedElement.name === nextElement.name && nextElement.type === 'radio') {
        nextElement = isReverse ? this.previousTargetElements[nextElement.id] : this.targetElements[nextElement.id];
      }
      if (nextElement.type !== 'radio') {
        return nextElement;
      }
    }
    // チェック済みのラジオボタンにフォーカスをセットする
    // チェック無しの場合、先頭のラジオボタンを返す
    var focusedRadio = nextElement;
    while(nextElement.name === focusedRadio.name) {
      if (nextElement.get('checked')) {
        return nextElement;
      }
      nextElement = isReverse ? this.previousTargetElements[nextElement.id] : this.targetElements[nextElement.id];
    }
    return focusedRadio;
  },

  isWidgetAvailable: function(nextElement) {
    var widget;
    require(["dijit/registry"], function(registry) {
      widget = registry.byId(nextElement.id);
    });
    if (!widget) {
      return false;
    }
    // タブを取得する
    var tab = widget.getParent();
    if (!tab || tab.declaredClass === undefined || tab.declaredClass !== "dijit.layout.ContentPane") {
      return true;
    }
    // タブが非活性の場合
    if (tab.get("disabled")) {
      return false;
    }
    // タブコンテナが取得できないか、タブコンテナの子としてタブが存在していない場合
    var tabContainer = tab.getParent();
    if (!tabContainer || tabContainer.getIndexOfChild(tab) === -1) {
      return false;
    }
    return true;
  },

  // 引数の次の要素にフォーカスをセットする
  focusNextElement: function(element, event) {
    // Enter キー、Tab キー以外、Shift + Tab キーの入力では何もしない
    if (!event.keyCode || !(event.keyCode == 0x0d || event.keyCode == 0x09) ||
        event.keyCode == 0x09 && event.shiftKey) {
      return;
    }
    dojo.stopEvent(event);
    // Shift キー押下時は逆順に移動させる
    var nextElement = this.getNextElement(element, event.shiftKey);
    if (!nextElement) {
      return;
    }
    // BR8468 2015.09.14
    // サジェスト利用時にEnterキーをタブキー扱いにしているとフォーカスセット時に
    // サジェストのxhr通信でエラーが発生するため、フォーカスのセットを300ms遅延させる
    var that = this;
    var isSuggest = false;
    if (element.id && element.id.indexOf("_content_displayed") !== -1) {
      isSuggest = true;
    }
    if (!isSuggest) {
      that.setFocusAndSelect(nextElement);
    } else {
      setTimeout(function() {
        that.setFocusAndSelect(nextElement);
      }, 300);
    }
  },

  setFocusAndSelect: function(element) {
    // タブ内の widget で、自信を含むタブが非表示の場合、選択状態にする
    var tab = element.getParent();
    if (tab && tab.declaredClass === "dijit.layout.ContentPane" && !tab.get("selected")) {
      var tabContainer = tab.getParent();
      if (tabContainer) {
        tabContainer.selectChild(tab);
      }
    }
    if (element.declaredClass === "wagby.DateTimeTextBox") {
      element.dateTextBox.focus();
    } else if (element.declaredClass === "wagby.FileUploader") {
      element.uploader.focus();
    } else {
      element.focus();
    }
    if (element.type == "text" && element.select) {
      element.select();
    }
  },

  setIgnoreElements: function(args) {
    // デフォルトでEnterキーを無視する要素名
    // 前方一致の要素名を先に列挙する
    this.ignoreElementNames["btnClear_"] = 1;    // クリアボタン
    this.ignoreElementNames["btnCalendar_"] = 1; // カレンダボタン
    this.ignoreElementNames["btnAdd_"] = 1;      // 繰り返し項目の追加ボタン
    this.ignoreElementNames["btnInsert_"] = 1;   // 繰り返しコンテナの挿入ボタン
    this.ignoreElementNames["btnRemove_"] = 1;   // 繰り返しコンテナの削除ボタン
    this.ignoreElementNames["jfcdelete_"] = 1;   // 親子同時更新画面の削除チェックボックス
    // 完全一致の要素名
    this.ignoreElementNames["__jfc_size_per_page0"] = 1; // ページ表示数の変更
    this.ignoreElementNames["btnSizePerPage"] = 1;       // ページ表示数変更ボタン
    this.ignoreElementNames["btnULCopy"] = 1;            // 親子同時更新画面のコピーボタン
    this.ignoreElementNames["btnULInsert"] = 1;          // 親子同時更新画面の新規ボタン
    this.ignoreElementNames["btnULDelete"] = 1;          // 親子同時更新画面の削除ボタン

    if (!args || args.ignoreElements === undefined) {
      return;
    }
    // カスタマイズで無視する要素名が引き渡されたら追加する
    for (var i=0,l=args.ignoreElements.length; i<l; i++) {
      this.ignoreElementNames[args.ignoreElements[i]] = 1;
    }
  },

  isIgnoreElement: function(name) {
    // 完全一致の要素名を先にチェックする
    if (this.ignoreElementNames[name]) {
      return true;
    }
    // 前方一致で要素名をチェックする
    for (var key in this.ignoreElementNames) {
      if (name.lastIndexOf(key, 0) == 0) {
        return true;
      }
    }
    return false;
  }
};

// サブメニュー、ログオフで引数のlocationへの画面遷移を行なう
function goPage(location) {
  if (clickedMenu) {
    return;
  }
  if (!window.confirm_destruction) {
    clickedMenu = true;
    window.location.href = location;
  } else {
    window.confirm_destruction(function() {
      clickedMenu = true;
      window.location.href = location;
    }, function() {
      clickedMenu = false;
    });
  }
}

function openPage(location, winname) {
  window.open(location, winname);
}

function getCheckboxesByName(form, checkboxNameRE) {
  var checkboxes = [];
  for (var i=0,l=form.elements.length; i<l; i++) {
    var element = form.elements[i];
    if (element.type != "checkbox" || element.name.match(checkboxNameRE) === null) {
      continue;
    }
    checkboxes.push(element);
  }
  return checkboxes;
}

function isAllSelected(checkboxes) {
  if (!checkboxes || checkboxes.length === 0) {
    return false;
  }
  var isSelected = true;
  require(["dijit/registry"], function(registry) {
    for (var i=0,l=checkboxes.length; i<l; i++) {
      var checkbox = registry.byId(checkboxes[i].id);
      if (!checkbox.get("checked")) {
        isSelected = false;
        break;
      }
    }
  });
  return isSelected;
}

function doClearOrCheckItem(checkboxes, state) {
  var changeelem = null;
  var checked = state["clear"];
  for (var i=0,l=checkboxes.length; i<l; i++) {
    if (checkboxes[i].checked) {
      changeelem = checkboxes[i];
    }
    // 入力可・不可制御の制御元がチェックボックス型にも対応したため
    // click イベントを発生させる
    if (checkboxes[i].checked ^ checked) {
      require(["dijit/registry"], function(registry) {
        var checkbox = registry.byId(checkboxes[i].id);
        if (checkbox) {
          checkbox.set("checked", checked);
          checkbox.onClick();
        }
      });
    }
  }
  return changeelem;
}

function getChangeToggleButtonStateFunc(buttonId, targetCheckboxes) {
  var checkIconClass = "dijitCheckBoxIcon";  // 全選択ボタンのアイコンクラス名
  var clearIconClass = "clearButtonIcon";    // クリアボタンのアイコンクラス名
  var tooltipContainerId = buttonId + "_TooltipContainer";
  var tooltipId = buttonId + "_Tooltip";
  var checkTooltip = res.CHECK_ALL;    // 全選択ボタンのツールチップメッセージ
  var clearTooltip = res.UNCHECK_ALL;  // クリアボタンのツールチップメッセージ

  // 全選択・クリアボタンの状態を変更する関数
  var changeToggleButtonState = function() {
    var toolTipMessage;
    var iconClass;
    // チェックボックスの選択状態を確認する
    if (isAllSelected(targetCheckboxes)) {
      // チェックボックスが全選択の場合は、クリアボタンを表示する
      iconClass = clearIconClass;
      toolTipMessage = clearTooltip;
    } else {
      // 対象のチェックボックスの中で選択されていないものがある場合、
      // 全選択ボタンを表示する
      iconClass = checkIconClass;
      toolTipMessage = checkTooltip;
    }
    require(["dijit/registry", "dojo/dom-construct"], function(registry, domConstruct) {
      // ボタンアイコン設定
      checkboxToggleButton = registry.byId(buttonId);
      if (checkboxToggleButton) {
        checkboxToggleButton.set("iconClass", iconClass);
      }
      // ツールチップメッセージ設定
      domConstruct.destroy(tooltipId);
      domConstruct.create("span", {id:tooltipId, innerHTML: toolTipMessage}, document.getElementById(tooltipContainerId));
    });
  };
  return changeToggleButtonState;
}

// 画面内の全てのチェックボックスを返す
function getAllCheckBoxInScreen() {
  return getAllWidgets(function(widget) {
    return widget.type === "checkbox"
  });
}

// 指定IDに前方一致するチェックボックスを返す
function getCheckboxById(id, allCheckBoxInScreen) {
  var checkboxSuffix = "_005d_002f_0040id";
  if (!allCheckBoxInScreen) {
    allCheckBoxInScreen = getAllCheckBoxInScreen();
  }
  if (!allCheckBoxInScreen) {
    return null;
  }
  var checkbox;
  require(["dojo/_base/array"], function(array) {
    checkbox = array.filter(allCheckBoxInScreen, function(widget) {
      return widget.id && widget.id.lastIndexOf(id, 0) === 0 &&
        widget.id.substr(-checkboxSuffix.length) === checkboxSuffix;
    });
  });
  return checkbox;
}

// チェックボックスのクリアボタン押下時にチェックボックスの
// 全選択・全解除を行なう関数をセットする
function setCheckboxToggleButtonClickEventFunc(targets) {
  var containerIndex = "${__position.count}";
  require(["dijit/registry", "dojo/query"], function(registry, query) {
    var allCheckBoxInScreen = getAllCheckBoxInScreen();
    for (var id in targets) {
      var reloadItemName = targets[id];
      if (id.indexOf(containerIndex) === -1) {
        setCheckboxToggleButtonClickEventFuncNormal(registry, id, reloadItemName, allCheckBoxInScreen);
      } else {
        // 繰り返しコンテナ内のチェックボックス
        var checkboxInContainerId = id.split(containerIndex);
        var queryStr = "input[type='button'][name^='btnClear_" + checkboxInContainerId[0] + "']"
          + "[name$='" + checkboxInContainerId[1].substring(0, checkboxInContainerId[1].lastIndexOf("_005b")) + "']";
        query(queryStr).forEach(function(node) {
          setCheckboxToggleButtonClickEventFuncNormal(registry, node.name, reloadItemName, allCheckBoxInScreen);
        });
      }
    }
  });
}

function setCheckboxToggleButtonClickEventFuncNormal(registry, id, reloadItemName, allCheckBoxInScreen) {
  var checkboxId;
  if (id.indexOf("${fn:escapeXml(c.id)}") !== -1) {
    checkboxId = id.split("${fn:escapeXml(c.id)}");
  } else if (id.lastIndexOf("btnClear_", 0) === 0) {
    checkboxId = [id.split("btnClear_")[1]];
  } else {
    checkboxId = [id];
  }
  var buttonId;
  if (id.lastIndexOf("btnClear_", 0) === 0) {
    buttonId = id;
  } else {
    var buttonId = "btnClear_" + checkboxId[0].substring(0, checkboxId[0].lastIndexOf("_005b"));
  }
  var checkboxToggleButton = registry.byId(buttonId);
  // 全選択・クリア対象のチェックボックスを取得
  var targetCheckboxes = getCheckboxById(checkboxId[0], allCheckBoxInScreen);
  getCheckboxToggleButtonClickEventFunc(buttonId, reloadItemName, checkboxToggleButton, targetCheckboxes);
}

function getCheckboxToggleButtonClickEventFunc(buttonId, reloadItemName, checkboxToggleButton, targetCheckboxes) {
  // 全選択・クリアボタンの状態を変更する関数
  var changeToggleButtonState = getChangeToggleButtonStateFunc(buttonId, targetCheckboxes);
  changeToggleButtonState();
  if (!checkboxToggleButton || !targetCheckboxes || targetCheckboxes.length === 0) {
    return;
  }
  // 対象のチェックボックスにも全選択・クリアボタンアイコン変更の関数をセットする
  for (var i=0,l=targetCheckboxes.length; i<l; i++) {
    targetCheckboxes[i].on("click", function() {
      changeToggleButtonState();
    });
  }
  // 全選択・クリアボタン押下時に実行する関数
  checkboxToggleButton.onClick = function(e) {
    var iconClass = checkboxToggleButton.get("iconClass");
    // ボタンアイコンによって状態を判断する
    var clearState = (iconClass === "dijitCheckBoxIcon"); // 全選択ボタンのアイコンクラス名
    // 全選択・クリアを実行
    var changeelem = doClearOrCheckItem(targetCheckboxes, {clear: clearState});
    if (changeelem !== null) {
      updateContent(null, changeelem);
    }
    // 現在のチェックボックスの状態によってボタンアイコンを変更する
    changeToggleButtonState();

    if (!reloadItemName || reloadItemName === "") {
      return;
    }
    var actionName = "action_";
    if (buttonId.indexOf("_cp_002f") != -1) {
      actionName += "Refresh";
      actionName = actionName + "_" + reloadItemName + "_" + iconClass;//2013.1.8 @since R6.8u3
    } else {
      actionName += ("Clear" + reloadItemName);
    }
    setScrollPosition(buttonId);
    e.target.form.SENDACTION.name = actionName;
    buttonOff();
    e.target.form.submit();
  }
}

// サブウィンドウ検索画面のリンクを非表示にする
function disableNoUseAnchor(target) {
  if (!target) {
    return;
  }
  // サブウィンドウ検索画面のリンクの id は、a_ で始まる
  // 親画面へ反映させるリンクかどうか正規表現でマッチさせる
  require(["dojo/dom-construct", "dojo/dom-style", "dojo/query"], function(domConstruct, domStyle, query) {
    var re = new RegExp("^a_.*_005d_002f" + target + "$|^a_.*_005d_002f" + target + ".*");
    query("a[id^='a_']").forEach(function(node) {
      var parentNode = node.parentNode;
      domStyle.set(node, "display", "none");
      var span = query("span", node)[0];
      if (span) {
        domConstruct.place(span, parentNode);
        // 親画面へ反映させる項目名を持つリンクのみフォントの色を変更する
        if (node.id.match(re)) {
          domStyle.set(span, "color", "#FF6600");
        }
      }
    });
  });
}

// タイトルペインの open 属性を cookie に保存する関数を返す
function getTitlePaneOpenAttrFunction(titlePaneId) {
  return function() {
    require(["dijit/registry", "dojo/cookie", "dojo/ready"], function(registry, cookie, ready) {
      ready(function() {
        var titlePane = registry.byId(titlePaneId);
        if (titlePane) {
          // タイトルペインの open 属性の初期値を取得する
          var titlePaneOpen = titlePane.get("open");
          if (cookie(titlePaneId)) {
            // cookie に open 属性が保存されている場合は、cookie の値を使用する
            titlePaneOpen = (cookie(titlePaneId) === "true");
          }
          titlePane.set("open", titlePaneOpen);
          titlePane.on("click", function() {
            cookie(titlePaneId, titlePane.get("open"));
          });
        }
      });
    });
  };
}

var jfcBubble = {
  // メッセージ表示場所のデフォルト値(右下)
  positionDirection: "br-left",

  errors: function(errors) {
    if (!errors) {
      return;
    }
    var message;
    if (errors.jfcerror && errors.jfcerror.length > 0) {
      message = "";
      for (var i=0,l=errors.jfcerror.length; i<l; i++) {
        message += (errors.jfcerror[i].content + "<br>");
      }
      this.error(message);
    }
    if (errors.jfcwarn && errors.jfcwarn.length > 0) {
      message = "";
      for (var i=0,l=errors.jfcwarn.length; i<l; i++) {
        message += (errors.jfcwarn[i].content + "<br>");
      }
      this.warn(message);
    }
    if (errors.jfcinfo && errors.jfcinfo.length > 0) {
      message = "";
      for (var i=0,l=errors.jfcinfo.length; i<l; i++) {
        message += (errors.jfcinfo[i].content + "<br>");
      }
      this.info(message);
    }
  },

  error: function(message) {
    this.showToasterMessage(message, "error");
  },

  warn: function(message) {
    this.showToasterMessage(message, "warning");
  },

  info: function(message) {
    this.showToasterMessage(message, "message");
  },

  showToasterMessage: function(message, type) {
    if (!message || message === "") {
      return;
    }
    jfcMessageToaster.setContent(message, type);
    jfcMessageToaster.show();
  },

  setMessagePosition: function(position) {
    if (!position || position === "") {
      position = this.positionDirection;
    }
    jfcMessageToaster.set("positionDirection", position);
  }
};

var ModernCalendarUtil = new function() {
  var that = this;
  require(["dijit/layout/ContentPane", "dijit/popup", "dijit/TooltipDialog", "dojo/_base/event", "dojo/_base/lang", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-style", "dojo/json", "dojo/on", "dojo/query", "dojo/request", "dojo/store/Memory", "dojo/store/Observable", "dojox/calendar/Calendar", "dojox/mobile/Tooltip"],
  function(ContentPane, popup, TooltipDialog, baseEvent, lang, domClass, domConstruct, domStyle, JSON, on, query, request, Memory, Observable, Calendar, Tooltip) {
    that.createCalendar = function(calendarOption) {
      var calendar = new Calendar({
        dateInterval: calendarOption.dateInterval || "month",
        columnViewProps: {
          minHours: calendarOption.minHours === undefined ? 8 : calendarOption.minHours,
          maxHours: calendarOption.maxHours === undefined ? 24: calendarOption.maxHours
        },
        firstDayOfWeek: calendarOption.firstDayOfWeek === undefined ? 0 : calendarOption.firstDayOfWeek,
        style: "position: relative; width: " + calendarOption.width + "; height: " + calendarOption.height + "; text-align: left;"
      }, calendarOption.id);
      that.isMobile = calendarOption.isMobile || false;
      // モデル毎のカレンダの色を設定する
      that.setCalendarCssClassFunc(calendar);
      // カレンダのイベントを設定する
      that.setCalendarEvent(calendar, calendarOption.modelId, calendarOption.domainURL);
      // カレンダデータの更新可能判定関数をセットする
      that.setCalendarItemEditableFunc(calendar);
      // カレンダデータ詳細ダイアログを生成する
      that.createCalendarItemDialog(calendar, calendarOption);
      that.selectedDateEvent = { date: new Date() };
      that.requestTimerId = null;
      return calendar;
    };

    that.setCalendarCssClassFunc = function(calendar) {
      calendar.set("cssClassFunc", function(item) {
        if (!item.calendar || item.calendar === "") {
          return "Calendar1";
        }
        return item.calendar;
      });
    };

    that.setCalendarEvent = function(calendar, modelId, domainURL) {
      // カレンダのデータを取得する関数
      var getCalendarItems = that.getCalendarItemsFunc(calendar, modelId, domainURL);
      // カレンダの表示月変更時に開始日でカレンダのデータを取得する
      calendar.on("TimeIntervalChange", function(e) {
        getCalendarItems(e.startTime);
      });
      // 週表示のカラムでは初期表示時に時間を現在時刻に合わせる
      calendar.on("RenderersLayoutDone", function(view) {
        calendar.columnView.set('startTimeOfDay', {hours: new Date().getHours(), duration: 10});
      });
      // カレンダデータ押下でダイアログを表示する
      that.setCalendarItemClickEvent(calendar, modelId);
      // カレンダデータのドラッグアンドドロップでの更新イベントを設定する
      that.setCalendarItemUpdateEvent(calendar, domainURL);
      // 週表示のカラムでは初期表示時に時間を現在時刻に合わせる
      that.setStartTimeOfDay(calendar);
      // カレンダグリッドのダブルクリックで新規登録の設定ダイアログを表示する
      if (!that.isMobile) {
        that.setCalendarDblClickEvent(calendar);
      }
    };

    that.getCalendarItemsFunc = function(calendar, modelId, domainURL) {
      var getCalendarUrl = that.getCalendarUrlFunc(domainURL);
      return function(date) {
        request(getCalendarUrl(modelId, date), {
          headers: {
            'X-Wagby-RESTAPIVersion': "v2",
          },
          handleAs: "json",
          withCredentials: true,
        }).then(function(data) {
          that.setCalendarStore(calendar, data);
        }, function(data) {
          console.error("get calendarItem err: ", data);
          if (data.message) {
            jfcBubble.error(data.message);
          }
        });
      };
    };

    // カレンダデータ押下で設定ダイアログを表示する
    that.setCalendarItemClickEvent = function(calendar, modelId) {
      calendar.on("itemClick", function(event) {
        that.openJfcCalendarItemDialog(event, null, modelId);
      });
      // カレンダのグリッド押下で設定ダイアログを非表示にする
      calendar.on("gridClick", function(event) {
        that.selectedDateEvent = event;
        that.closeJfcCalendarItemDialog();
      });
    };

    // カレンダデータ編集完了時に update の REST API を実行する
    that.setCalendarItemUpdateEvent = function(calendar, domainURL) {
      calendar.on("itemEditEnd", function(event) {
        that.updateCalendarItem(event, domainURL);
      });
    };

    that.updateCalendarItem = function(event, domainURL) {
      var item = that.getUpdateCalendarItem(event);
      if (!item || !that.isCalendarItemChanged(item)) {
        return;
      }
      var baseUrl = "rest/" + item.modelId + "/editical/";
      if (domainURL) {
        baseUrl = domainURL + baseUrl;
      }
      var calendarItem = JSON.stringify(that.createCalendarItem(item));
      request(baseUrl + item.pkey, {
        data: calendarItem,
        handleAs: "json",
        headers: {
          'X-Wagby-RESTAPIVersion': "v2",
          'Content-Type': "application/json; charset=utf-8",
        },
        method: "PUT",
        withCredentials: true,
      }).then(function(data) {
        if (data.errors) {
          jfcBubble.errors(data.errors);
        }
      }, function(data) {
        that.rollbackItemData(item);
        if (data.response.data.errors) {
          jfcBubble.errors(data.response.data.errors);
        }
      });
    };

    that.getUpdateCalendarItem = function(event) {
      var item = event.item;
      var modelIdPkey = that.getModelIdPkey(item.id);
      if (!modelIdPkey) {
        return null;
      }
      return {
        id: item.id,
        modelId: modelIdPkey.modelId,
        pkey: modelIdPkey.pkey,
        startTime: _setDateWithFormat(item.startTime, "yyyy-MM-dd HH:mm:ss"),
        endTime: _setDateWithFormat(item.endTime, "yyyy-MM-dd HH:mm:ss"),
        savedStartTime: _setDateWithFormat(new Date(event.source._editStartTimeSave), "yyyy-MM-dd HH:mm:ss"),
        savedEndTime: _setDateWithFormat(new Date(event.source._editEndTimeSave), "yyyy-MM-dd HH:mm:ss")
      };
    };

    that.isCalendarItemChanged = function(item) {
      if (item.startTime === item.savedStartTime &&
           item.endTime === item.savedEndTime) {
        return false;
      }
      return true;
    };

    that.setCalendarItemEditableFunc = function(calendar) {
      calendar.isItemEditable = function(item, renderKind) {
        if (!item || that.isMobile) {
          return false;
        }
        // 更新画面の URL が無い場合は、データ更新不可
        if (!item.updateUrl) {
          return false;
        }
        return true;
      }
    };

    that.insertCalendarItem = function(item) {
      var content = that.createCalendarItem(data.entityp, item);
      request("rest/" + item.modelId + "/new", {
        data: JSON.stringify(content),
        handleAs: "json",
        headers: {
          'X-Wagby-RESTAPIVersion': "v2",
          'Content-Type': "application/json; charset=utf-8",
        },
        method: "POST",
        withCredentials: true,
      }).then(function(data) {
        refreshCalendarItem(item, data.entity);
      }, function(error) {
        console.error(data);
        if (data.response.data.errors) {
          jfcBubble.errors(data.response.data.errors);
        }
      });
    };

    that.createCalendarItem = function(item) {
      return {
        'start': item.startTime,
        'end': item.endTime
      };
    };

    that.rollbackItemData = function(item) {
      var store = dijitCalendar.get("store");
      var calendaritem = store.get(item.id);
      if (!calendaritem) {
        return;
      }
      calendaritem.startTime = item.savedStartTime.replace(" ", "T");
      calendaritem.endTime = item.savedEndTime.replace(" ", "T");
      store.put(calendaritem);
    };

    that.refreshCalendarItem = function(item, entity) {
      var store = dijitCalendar.get("store");
      if (item.id !== "") {
      var obj = store.get(item.id);
        if (obj) {
          obj.startTime = new Date(item.startTime);
          obj.endTime = new Date(item.endTime);
          store.put(obj);
        }
      } else {
        store.add({
          id: item.modelId + ":" + entity.pkey,
          summary: item.summary || "",
          startTime: new Date(item.startTime),
          endTime: new Date(item.endTime),
          allDay: item.allDay || false,
          description: item.description || "",
          location: item.location || "",
          calendar: item.calendar || "Calendar1"
        });
      }
    };

    that.setStartTimeOfDay = function(calendar) {
      calendar.on("RendererCreated", function(e) {
        calendar.columnView.set('startTimeOfDay', {hours: new Date().getHours(), duration: 20});
        var renderer = e.renderer.renderer;
        on(renderer.domNode, "touchend", lang.hitch(calendar, function(e) {
          baseEvent.stop(e);
          calendar.onItemClick({
            triggerEvent: e,
            renderer: renderer,
            item: renderer.item._item
          });
        }));
      });
    };

    that.openNewCalendarItemDialog = function(event) {
      if (!event) {
        event = that.selectedDateEvent;
      }
      that.openJfcCalendarItemDialog(event, {
        id: "",
        summary: "",
        startTime: _setDateWithFormat(event.date, "yyyy-MM-dd 09:00:00"),
        endTime: _setDateWithFormat(event.date, "yyyy-MM-dd 18:00:00"),
        allDay: false,
        staff: "",
        location: "",
        url: "",
        description: ""
      });
    }

    that.setCalendarDblClickEvent = function(calendar) {
      calendar.on("gridDoubleClick", function(event) {
        that.openNewCalendarItemDialog(event);
      });
    };

    that.setJfcCalendarItemAllDayEvent = function(jfcRegisterMobileCalendarItemAllDay) {
      var chkAllDay;
      var txtStartDate;
      var txtStartTime;
      var txtEndDate;
      var txtEndTime;
      if (jfcRegisterMobileCalendarItemAllDay) {
        chkAllDay = jfcRegisterMobileCalendarItemAllDay;
        txtStartDate = jfcRegisterMobileCalendarItemStartDate;
        txtStartTime = jfcRegisterMobileCalendarItemStartTime;
        txtEndDate = jfcRegisterMobileCalendarItemEndDate;
        txtEndTime = jfcRegisterMobileCalendarItemEndTime;
      } else {
        chkAllDay = jfcCalendarItemAllDay;
        txtStartDate = jfcCalendarItemStartDate;
        txtStartTime = jfcCalendarItemStartTime;
        txtEndDate = jfcCalendarItemEndDate;
        txtEndTime = jfcCalendarItemEndTime;
      }
      // 終日フラグ押下時
      chkAllDay.on('click', function(event) {
        var startDate = txtStartDate.get("value");
        // 開始時刻
        txtStartTime.set("value", startDate);
        // 終了日
        var endDate = createDateObject(txtStartDate.get("displayedValue") + " 00:00:00");
        endDate = new Date(endDate.setDate(endDate.getDate() + 1));
        txtEndDate.set("value", endDate);
        // 終了時刻
        txtEndTime.set("value", endDate);
        that.setDataTimeWidgetReadOnly(txtStartTime, txtEndDate, txtEndTime, event.target.checked)
      });
      // 終日設定時の開始日時変更イベント
      that.setJfcStartDateChangeEvent(txtStartDate, txtEndDate, chkAllDay);
    }

    that.setDataTimeWidgetReadOnly = function(startTime, endDate, endTime, checked) {
      startTime.set("readOnly", checked);
      endDate.set("readOnly", checked);
      endTime.set("readOnly", checked);
    }

    that.setJfcStartDateChangeEvent = function(txtStartDate, txtEndDate, chkAllDay) {
      txtStartDate.on("change", function() {
        if (!chkAllDay.get("checked")) {
          return;
        }
        let endDate = txtStartDate.get("value");
        endDate.setDate(endDate.getDate() + 1);
        txtEndDate.set("value", endDate);
      });
    }

    that.getCalendarBaseUrl = function(domainURL, modelId) {
      var url = "rest/" + modelId + "/ical/";
      if (domainURL) {
        return domainURL + url;
      }
      return url;
    };

    that.getCalendarUrlFunc = function(domainURL) {
      return function(modelId, date) {
        if (!date) {
          return null;
        }
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        return that.getCalendarBaseUrl(domainURL, modelId) + year + "-" + month + "-01";
      };
    };

    that.getCalendarItemsFromData = function(data) {
      var calendarItems = [];
      var items = data.listp.item;
      for (var i=0,l=items.length; i<l; i++) {
        var item = items[i];
        if (item.calendaritem.length === 0) {
          continue;
        }
        for (var j=0,m=item.calendaritem.length; j<m; j++) {
          var calendaritem = item.calendaritem[j];
          calendarItems.push({
            id: calendaritem.modelid + ":" + calendaritem.calendarid,
            modelId: calendaritem.modelid,
            calendarId: calendaritem.calendarid,
            primaryKeyName: calendaritem.primarykeyname,
            primaryKeyNames: calendaritem.primarykeynames,
            primaryKeyValues: calendaritem.primarykeyvalues,
            summary: calendaritem.summary || "",
            startTime: that.getISODatetimeFormatValue(calendaritem.start) || "",
            endTime: that.getISODatetimeFormatValue(calendaritem.end) || "",
            allDay: calendaritem.allDay || false,
            staff: calendaritem.staff || "",
            description: calendaritem.description || "",
            location: calendaritem.location || "",
            url: calendaritem.url || "",
            showUrl: calendaritem.showurl || "",
            updateUrl: calendaritem.updateurl || "",
            deleteUrl: calendaritem.deleteurl || "",
            calendar: calendaritem.calendar || "Calendar1"
          });
        }
      }
      return calendarItems;
    };

    that.getISODatetimeFormatValue = function(strDate) {
      if (!strDate || strDate === "") {
        return null;
      }
      // 日付と時刻を空白ではなく「T」で連結する
      return strDate.replace(/\s/, "T");
    };

    that.getModelIdPkey = function(calendarItemId) {
      if (!calendarItemId || calendarItemId === "" || calendarItemId.indexOf(":") === -1) {
        return null;
      }
      var modelIdPkey = calendarItemId.split(":"); // modelId:pkey
      return {
        modelId: modelIdPkey[0],
        pkey: modelIdPkey[1] || 0
      };
    };

    // カレンダ設定ダイアログ表示関数
    that.openJfcCalendarItemDialog = function(event, item, modelId) {
      if (!item && event) {
        item = event.item;
      }
      // 休日設定モデル以外では、jholiday のデータはダイアログを開かない
      if (item && item.modelId
          && item.modelId === 'jholiday'
          && modelId !== 'jholiday') {
        return;
      }
      // カレンダ設定ダイアログを開く
      if (!that.isMobile) {
        popup.open({
          popup: that.jfcCalendarItemDialog,
          x: event.triggerEvent.x || event.triggerEvent.clientX,
          y: event.triggerEvent.y || event.triggerEvent.clientY
        });
      } else {
        var node;
        if (event.renderer) {
          node = event.renderer.summaryLabel;
          if (!node && event.source) {
            node = event.source.header || event.source.columnHeader;
          }
        }
        if (!node) {
          node = document.getElementById("jfcToolBarBtnNew");
        }
        that.jfcCalendarItemDialog.show(node);
      }
      // カレンダ設定ダイアログにデータをセットする
      that.setCalendarItemDataToDialog(item);
      that.setJfcCalendarItemDialogButtonDisabled(item);
    };

    // カレンダ設定ダイアログ非表示関数
    that.closeJfcCalendarItemDialog = function() {
      if (!that.isMobile) {
        popup.close(that.jfcCalendarItemDialog);
      } else {
        that.jfcCalendarItemDialog.hide();
      }
    };

    that.getCalendarItemTableRows = function() {
      if (that.calendarItemTableRows) {
        return that.calendarItemTableRows;
      }
      var rows = query('tr', 'jfcCalendarItemDialogTableTbody');
      for (var i=0,l=6; i<l; i++) {
        rows.shift();
      }
      that.calendarItemTableRows = rows;
      return that.calendarItemTableRows;
    };

    that.setJfcCalendarItemDialogRowsDisplay = function(display) {
      domStyle.set('showJfcCalendarBtnContainer', 'display', display);
      var rows = that.getCalendarItemTableRows();
      for (var i=0,l=rows.length; i<l; i++) {
        domStyle.set(rows[i], 'display', display);
      }
    };

    that.setJfcCalendarItemDialogInsert = function() {
      domStyle.set('insertJfcCalendarBtnContainer', 'display', '');
      that.setJfcCalendarItemDialogRowsDisplay('none');
      that.setCalendarItemDialogReadonly(false);
    };

    that.setJfcCalendarItemDialogShow = function() {
      domStyle.set('insertJfcCalendarBtnContainer', 'display', 'none');
      that.setJfcCalendarItemDialogRowsDisplay('');
      that.setCalendarItemDialogReadonly(true);
    }

    that.setCalendarItemDialogReadonly = function(readOnly) {
      // タイトル
      jfcCalendarItemSummary.set("readOnly", readOnly);
      // 開始日
      jfcCalendarItemStartDate.set("readOnly", readOnly);
      // 終了日
      jfcCalendarItemEndDate.set("readOnly", readOnly);
      // 開始時刻
      jfcCalendarItemStartTime.set("readOnly", readOnly);
      // 終了時刻
      jfcCalendarItemEndTime.set("readOnly", readOnly);
      // 終日フラグ
      jfcCalendarItemAllDay.set("readOnly", readOnly);
    }

    that.setCalendarItemDataToDialog = function(item) {
      var lbxJfcCalendarViewModelDisabled = true;
      var modelIdPkey = that.getModelIdPkey(item.id);
      if (!modelIdPkey) {
        // モデルIDと主キーが無い場合は、新規登録なのでモデル選択リストボックスを入力可とする
        lbxJfcCalendarViewModelDisabled = false;
        that.setJfcCalendarItemDialogInsert();
      } else {
        // モデルIDが取得できた場合は、更新なので対象モデルを選択状態にする
        lbxJfcCalendarViewModel.set("value", modelIdPkey.modelId);
        that.setJfcCalendarItemDialogShow();
      }
      lbxJfcCalendarViewModel.set("readOnly", lbxJfcCalendarViewModelDisabled);

      // モデルID:主キー
      jfcCalendarItemId.set("value", item.id);
      // タイトル
      jfcCalendarItemSummary.set("value", item.summary);
      // 開始日
      jfcCalendarItemStartDate.set("value", _setDateWithFormat(item.startTime, "yyyy-MM-dd"));
      // 終了日
      jfcCalendarItemEndDate.set("value", _setDateWithFormat(item.endTime, "yyyy-MM-dd"));
      // 開始時刻
      jfcCalendarItemStartTime.set("value", "T" + _setDateWithFormat(item.startTime, "HH:mm"));
      // 終了時刻
      jfcCalendarItemEndTime.set("value", "T" + _setDateWithFormat(item.endTime, "HH:mm"));
      // 終日
      jfcCalendarItemAllDay.set("value", item.allDay);
      // 担当者
      jfcCalendarItemStaff.set("value", item.staff);
      // 場所
      jfcCalendarItemLocation.set("value", item.location);
      // URL
      jfcCalendarItemUrl.set("value", item.url);
      // 備考
      jfcCalendarItemDescription.set("value", item.description);
    };

    that.setJfcCalendarItemDialogButtonDisabled = function(item) {
      if (item.id === "") {
        // 新規登録
        var value = that.lbxCalendarView.get("value");
        that.setBtnInsertJfcCalendarItemDisabled(value);
        return;
      }
      // 詳細画面表示ボタン
      var showBtnDisabled = false;
      if (!item.showUrl) {
        showBtnDisabled = true;
      }
      btnShowJfcCalendarItem.set("disabled", showBtnDisabled);

      // 更新画面表示ボタン
      var updateBtnDisabled = false;
      if (!item.updateUrl) {
        updateBtnDisabled = true;
      }
      btnUpdateJfcCalendarItem.set("disabled", updateBtnDisabled);

      // 削除ボタン
      var deleteBtnDisabled = false;
      if (!item.deleteUrl) {
        deleteBtnDisabled = true;
      }
      btnDeleteJfcCalendarItem.set("disabled", deleteBtnDisabled);
    };

    that.getCalendarItemFromStore = function(calendar, id) {
      if (!calendar) {
        return null;
      }
      var store = calendar.get("store");
      if (!store) {
        return null;
      }
      return store.get(id);
    };

    that.openPage = function(url) {
      if (url) {
        window.location.href = url;
      }
    };

    that.getShowUrlFromForm = function(calendar) {
      var calendaritem = that.getCalendarItemFromForm(calendar);
      if (!calendaritem || !calendaritem.showUrl || calendaritem.showUrl === "") {
        return null;
      }
      return calendaritem.showUrl + "?" +
        that.getPrimaryKeyValueParameter(calendaritem.primaryKeyNames, calendaritem.primaryKeyValues);
    };

    that.getUpdateUrlFromForm = function(calendar) {
      var calendaritem = that.getCalendarItemFromForm(calendar);
      if (!calendaritem || !calendaritem.updateUrl || calendaritem.updateUrl === "") {
        return null;
      }
      return calendaritem.updateUrl + "?action_Update=&" +
        that.getPrimaryKeyValueParameter(calendaritem.primaryKeyNames, calendaritem.primaryKeyValues);
    };

    that.getJfcCalendarTitle = function(calendaritem) {
      if (calendaritem.summary) {
        return calendaritem.summary;
      }
      if (!that.isMobile) {
        return jfcCalendarItemSummary.get("value");
      } else {
        return jfcRegisterMobileCalendarItemSummary.get("value");
      }
    }

    that.getJfcCalendarStartDateTime = function(calendaritem) {
      if (calendaritem.startTime) {
        return _setDateWithFormat(calendaritem.startDate, "yyyy-MM-dd") +
          _setDateWithFormat(calendaritem.startTime, " HH:mm:ss");
      }
      if (!that.isMobile) {
        return _setDateWithFormat(jfcCalendarItemStartDate.get("value"), "yyyy-MM-dd") +
          _setDateWithFormat(jfcCalendarItemStartTime.get("value"), " HH:mm:ss");
      } else {
        return _setDateWithFormat(jfcRegisterMobileCalendarItemStartDate.get("value"), "yyyy-MM-dd") +
          _setDateWithFormat(jfcRegisterMobileCalendarItemStartTime.get("value"), " HH:mm:ss");
      }
    }

    that.getJfcCalendarEndDateTime = function(calendaritem) {
      if (calendaritem.endTime) {
        return _setDateWithFormat(calendaritem.endDate, "yyyy-MM-dd") +
          _setDateWithFormat(calendaritem.endTime, " HH:mm:ss");
      }
      if (!that.isMobile) {
        return _setDateWithFormat(jfcCalendarItemEndDate.get("value"), "yyyy-MM-dd") +
          _setDateWithFormat(jfcCalendarItemEndTime.get("value"), " HH:mm:ss");
      } else {
        return _setDateWithFormat(jfcRegisterMobileCalendarItemEndDate.get("value"), "yyyy-MM-dd") +
          _setDateWithFormat(jfcRegisterMobileCalendarItemEndTime.get("value"), " HH:mm:ss");
      }
    }

    that.isJfcCalendarItemAllDay = function() {
      if (!that.isMobile) {
        return jfcCalendarItemAllDay.get("checked");
      } else {
        return jfcRegisterMobileCalendarItemAllDay.get("checked");
      }
    }

    that.getInsertUrlFromLbxCalendarView = function(calendaritem) {
      var value = that.lbxCalendarView.get("value");
      var selectedOption = that.lbxCalendarView.getOptions(value);
      if (!selectedOption) {
        return capFirst(calendaritem.modelId) + ".do";
      }
      return selectedOption.inserturl;
    },

    that.getInsertUrlFromForm = function(calendar) {
      var calendaritem;
      if (!that.isMobile) {
        calendaritem = that.getCalendarItemFromForm(calendar);
      } else {
        calendaritem = that.getRegisterMobileCalendarItemFromForm(calendar);
      }
      if (!calendaritem || !calendaritem.modelId || calendaritem.modelId === "") {
        return null;
      }
      // タイトル
      var jfcCalendarTitle = that.getJfcCalendarTitle(calendaritem);
      // 開始日時
      var jfcCalendarStartDateTime = that.getJfcCalendarStartDateTime(calendaritem);
      // 終了日時
      var jfcCalendarEndDateTime = that.getJfcCalendarEndDateTime(calendaritem);
      var url = that.getInsertUrlFromLbxCalendarView(calendaritem) + '?action_Insert=&jfcCalendarTitle=' + jfcCalendarTitle +
        '&jfcCalendarStartDateTime=' + jfcCalendarStartDateTime + '&jfcCalendarEndDateTime=' + jfcCalendarEndDateTime;
      // 終日フラグ
      if (that.isJfcCalendarItemAllDay(calendaritem)) {
        url = url + '&jfcCalendarAllDay=1';
      }
      return url
    };

    that.getPrimaryKeyValueParameter = function(primaryKeyNames, primaryKeyValues) {
      if (!primaryKeyNames || primaryKeyNames.length === 0 ||
           !primaryKeyValues || primaryKeyValues.length === 0) {
        return "";
      }
      var primaryKeyValueParameter = primaryKeyNames[0] + "=" + primaryKeyValues[0];
      for (var i=1,l=primaryKeyNames.length; i<l; i++) {
        primaryKeyValueParameter += "&" + primaryKeyNames[i] + "=" + primaryKeyValues[i];
      }
      return primaryKeyValueParameter;
    };

    that.getCalendarItemFormValues = function() {
      return jfcCalendarItemForm.get("value");
    }

    that.getRegisterMobileCalendarItemFormValues = function() {
      return jfcRegisterMobileCalendarItemForm.get("value");
    }

    that.getJfcCalendarItemId = function(formValues) {
      return formValues.jfcCalendarItemId;
    }

    that.getRegisterMobileCalendarItemFromForm = function(calendar) {
      var formValues = that.getRegisterMobileCalendarItemFormValues();
      if (!formValues.jfcRegisterMobileCalendarItemId) {
        return formValues;
      }
      var calendaritem = that.getCalendarItemFromStore(calendar, formValues.jfcRegisterMobileCalendarItemId);
      if (!calendaritem) {
        return formValues;
      }
      calendaritem.startTime = _setDateWithFormat(formValues.startDate, "yyyy-MM-dd") + "T" + _setDateWithFormat(formValues.startTime, "HH:mm");
      calendaritem.endTime = _setDateWithFormat(formValues.endDate, "yyyy-MM-dd") + "T" + _setDateWithFormat(formValues.endTime, "HH:mm");
      calendaritem.summary = formValues.summary;
      calendaritem.staff = formValues.staff;
      calendaritem.description = formValues.description;
      calendaritem.location = formValues.location;
      calendaritem.url = formValues.url;
      calendaritem.allDay = jfcRegisterMobileCalendarItemAllDay.get("checked");
      return calendaritem;
    }

    that.getCalendarItemFromForm = function(calendar) {
      var formValues = that.getCalendarItemFormValues();
      var calendaritem = that.getCalendarItemFromStore(calendar, that.getJfcCalendarItemId(formValues));
      if (!calendaritem) {
        return formValues;
      }
      calendaritem.startTime = _setDateWithFormat(formValues.startDate, "yyyy-MM-dd") + "T" + _setDateWithFormat(formValues.startTime, "HH:mm");
      calendaritem.endTime = _setDateWithFormat(formValues.endDate, "yyyy-MM-dd") + "T" + _setDateWithFormat(formValues.endTime, "HH:mm");
      calendaritem.summary = formValues.summary;
      calendaritem.staff = formValues.staff;
      calendaritem.description = formValues.description;
      calendaritem.location = formValues.location;
      calendaritem.url = formValues.url;
      var allDay;
      if (!that.isMobile) {
        allDay = jfcCalendarItemAllDay.get("checked");
      } else {
        allDay = jfcRegisterMobileCalendarItemAllDay.get("checked");
      }
      calendaritem.allDay = allDay;
      return calendaritem;
    };

    that.openShowPage = function(calendar) {
      that.openPage(that.getShowUrlFromForm(calendar));
    };

    that.openUpdatePage = function(calendar) {
      that.openPage(that.getUpdateUrlFromForm(calendar));
    };

    // 削除ボタン押下時のイベント
    that.deleteCalendarItemFromForm = function(calendar, calendarOption) {
      if (!confirm(res.CONFIRM_DELETE)) {
        return;
      }
      that.deleteCalendarItem(calendar, calendarOption);
      that.closeJfcCalendarItemDialog();
    };

    that.deleteCalendarItem = function(calendar, calendarOption) {
      var calendaritem = that.getCalendarItemFromForm(calendar)
      if (!calendaritem) {
        return;
      }
      var url = "rest/" + calendaritem.modelId + "/edit/" + calendaritem.calendarId;
      if (calendarOption.domainURL) {
        url = calendarOption.domainURL + url;
      }
      request(url, {
        headers: {
          'X-Wagby-RESTAPIVersion': "v2",
        },
        handleAs: "json",
        method: "DELETE",
        withCredentials: true,
      }).then(function(data) {
        if (data && data.errors) {
          if (data.errors.jfcinfo && data.errors.jfcinfo.length > 0) {
            // サーバでの削除処理が正常終了した場合に画面のカレンダデータを削除する
            var store = calendar.get("store");
            store.remove(calendaritem.id);
          }
          jfcBubble.errors(data.errors);
        }
      }, function(data) {
        console.error("delete calendarItem error: ", data);
        if (data && data.response && data.response.data && data.response.data.errors) {
          jfcBubble.errors(data.response.data.errors);
        } else {
          jfcBubble.error(res.ERROR_MSG_DELETE_CALENDAR_ITEM);
        }
      });
    };

    that.insertCalendarItemFromForm = function(calendar) {
      var url = that.getInsertUrlFromForm(calendar);
      that.openPage(url);
    };

    that.getConditionWidgetChangeEventFunc = function(calendar) {
      var getCalendarUrl = that.getCalendarUrlFunc();
      return function(modelId, date, condition) {
        if (that.requestTimerId) {
          clearTimeout(that.requestTimerId);
        }
        that.requestTimerId = setTimeout(function() {
          var url = getCalendarUrl(modelId, date);
          request(url, {
            query: condition,
            handleAs: "json",
            headers: {
              'X-Wagby-RESTAPIVersion': "v2",
              "Content-Type": "application/x-www-form-urlencoded",
            },
            method: "POST",
            withCredentials: true,
          }).then(function(data) {
            that.setCalendarStore(calendar, data);
          }, function(data) {
            console.error("searchCalendar err: ", data);
            if (data.message) {
              jfcBubble.error(data.message);
            }
          });
        }, 100);
      };
    };

    that.setCalendarStore = function(calendar, data) {
      var store = calendar.get("store");
      if (store) {
        store = null;
      }
      calendar.set("store", new Observable(new Memory({
        'data': that.getCalendarItemsFromData(data),
      })));
    };

    that.getMobileCalendarItemContentTemplate = function() {
      var dialogTemplate = '<form data-dojo-type="dijit/form/Form" data-dojo-id="jfcCalendarItemForm" id="jfcCalendarItemForm" action="" method="post" style="font-size: x-small;padding-bottom: 0;">';
      dialogTemplate = dialogTemplate + that.getCalendarItemContentTemplateTable();
      dialogTemplate = dialogTemplate + '<div style="padding: 10px 0 0 0; text-align: right;">'
+ '<span id="showJfcCalendarBtnContainer"><button data-dojo-type="dojox/mobile/Button" data-dojo-id="btnShowJfcCalendarItem" type="button" style="height: auto;font-size:x-small;"><div>'
+ res.LABEL_CALENDAR_DIALOG_BTN_SHOW +
'</div></button><button data-dojo-type="dojox/mobile/Button" data-dojo-id="btnUpdateJfcCalendarItem" type="button" style="height: auto;font-size:x-small;">'
+ res.LABEL_CALENDAR_DIALOG_BTN_UPDATE +
'</button><button data-dojo-type="dojox/mobile/Button" data-dojo-id="btnDeleteJfcCalendarItem" type="button" style="height: auto;font-size:x-small;">'
+ res.BUTTON_DELETE +
'</button></span><span id="insertJfcCalendarBtnContainer"><button data-dojo-type="dojox/mobile/Button" data-dojo-id="btnInsertJfcCalendarItem" type="button" style="height: auto;font-size:x-small;">'
+ res.LABEL_CALENDAR_DIALOG_BTN_INSERT +
'</button></span><button data-dojo-type="dojox/mobile/Button" data-dojo-id="btnCancelJfcCalendarItem" type="button" style="height: auto;font-size:x-small;" data-dojo-props="onClick: function() { ModernCalendarUtil.closeJfcCalendarItemDialog(); }">'
+ res.BUTTON_CANCEL +
'</button></div><input data-dojo-type="dijit/form/TextBox" type="hidden" data-dojo-id="jfcCalendarItemId" name="jfcCalendarItemId"></form>';
      return dialogTemplate;
    }

    that.getCalendarItemContentTemplate = function() {
      var dialogTemplate = '<form data-dojo-type="dijit/form/Form" data-dojo-id="jfcCalendarItemForm" id="jfcCalendarItemForm" action="" method="post" style="padding-bottom: 0;">';
      dialogTemplate = dialogTemplate + that.getCalendarItemContentTemplateTable();
      dialogTemplate = dialogTemplate + '<div style="padding: 10px 0 0 0; text-align: right;">'
+ '<span id="showJfcCalendarBtnContainer"><button data-dojo-type="dijit/form/Button" data-dojo-id="btnShowJfcCalendarItem" type="button"><div>'
+ res.LABEL_CALENDAR_DIALOG_BTN_SHOW +
'</div></button><button data-dojo-type="dijit/form/Button" data-dojo-id="btnUpdateJfcCalendarItem" type="button"><div style="width: 80px;">'
+ res.LABEL_CALENDAR_DIALOG_BTN_UPDATE +
'</div></button><button data-dojo-type="dijit/form/Button" data-dojo-id="btnDeleteJfcCalendarItem" type="button"><div style="width: 60px;">'
+ res.BUTTON_DELETE +
'</div></button></span><span id="insertJfcCalendarBtnContainer"><button data-dojo-type="dijit/form/Button" data-dojo-id="btnInsertJfcCalendarItem" type="button"><div style="width: 110px;">'
+ res.LABEL_CALENDAR_DIALOG_BTN_INSERT +
'</div></button></span><button data-dojo-type="dijit/form/Button" data-dojo-id="btnCancelJfcCalendarItem" type="button" data-dojo-props="onClick: function() { ModernCalendarUtil.closeJfcCalendarItemDialog(); }">'
+ res.BUTTON_CANCEL +
'</button></div><input data-dojo-type="dijit/form/TextBox" type="hidden" data-dojo-id="jfcCalendarItemId" name="jfcCalendarItemId"></form>';
      return dialogTemplate;
    }

    that.getCalendarItemContentTemplateTable = function() {
      var dialogTemplate = '<table class="display_table"><tbody id="jfcCalendarItemDialogTableTbody"><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_MODELNAME +
'</th><td><select data-dojo-type="wagby/Select" id="lbxJfcCalendarViewModel" data-dojo-id="lbxJfcCalendarViewModel" name="modelId" style="width: 150px;"></select></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_TITLE +
'</th><td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-id="jfcCalendarItemSummary" name="summary" data-dojo-props="required: true, readOnly: true, selectOnClick: true" style="width: 99%;"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_ALLDAYFLAG +
'</th><td><input type="checkbox" data-dojo-type="dijit/form/CheckBox" data-dojo-id="jfcCalendarItemAllDay" id="jfcCalendarItemAllDay" name="allDay" data-dojo-props="readOnly: true"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_STARTDATETIME +
'</th><td><input type="text" data-dojo-type="wagby/DateTextBox" data-dojo-id="jfcCalendarItemStartDate" name="startDate" data-dojo-props="dateFormat: \'yyyy-MM-dd\', required: true, readOnly: true" style="width: 150px;"/><input type="text" data-dojo-type="dijit/form/TimeTextBox" data-dojo-id="jfcCalendarItemStartTime" name="startTime" data-dojo-props="readOnly: true"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_ENDDATETIME +
'</th><td><input type="text" data-dojo-type="wagby/DateTextBox" data-dojo-id="jfcCalendarItemEndDate" name="endDate" data-dojo-props="dateFormat: \'yyyy-MM-dd\', required: true, readOnly: true" style="width: 150px;"/><input type="text" data-dojo-type="dijit/form/TimeTextBox" data-dojo-id="jfcCalendarItemEndTime" name="endTime" data-dojo-props="readOnly: true"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_STAFF +
'</th><td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-id="jfcCalendarItemStaff" name="staff" data-dojo-props="readOnly: true, selectOnClick: true" style="width: 100%;"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_PLACE +
'</th><td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-id="jfcCalendarItemLocation" name="location" data-dojo-props="readOnly: true, selectOnClick: true" style="width: 100%;"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_URL +
'</th><td><input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-id="jfcCalendarItemUrl" name="url" data-dojo-props="readOnly: true, selectOnClick: true" style="width: 100%;"/></td></tr><tr class="display_field"><th class="display_label">'
+ res.LABEL_CALENDAR_DIALOG_MEMO +
  '</th><td><textarea data-dojo-type="dijit/form/SimpleTextarea" data-dojo-id="jfcCalendarItemDescription" name="description" data-dojo-props="readOnly: true, rows: 5" style="width: 97%;"></textarea></td></tr></tbody></table>';
      return dialogTemplate;
    }

    that.createCalendarItemDialog = function(calendar, calendarOption) {
      if (!that.isMobile) {
        that.jfcCalendarItemDialog = new TooltipDialog({
          id: "jfcCalendarItemDialog",
        });
        that.jfcCalendarItemDialog.on("Load", function(data) {
          that.setCalendarItemDialogEvent(calendar, calendarOption);
          // カレンダ設定ダイアログのモデルリストのデータを取得する
          that.setCalendarViewModelData(calendarOption);
        });
        that.jfcCalendarItemDialog.set("content", that.getCalendarItemContentTemplate());
      } else {
        that.jfcCalendarItemDialog = jfcCalendarItemDialog;
        var cp = new ContentPane();
        cp.on("Load", function() {
          that.setCalendarItemDialogEvent(calendar, calendarOption);
        });
        domConstruct.place(cp.domNode, that.jfcCalendarItemDialog.domNode, "last");
        cp.set("content", that.getMobileCalendarItemContentTemplate());
      }
    };

    that.setCalendarItemDialogEvent = function(calendar, calendarOption) {
      // 詳細画面表示ボタン押下イベント
      btnShowJfcCalendarItem.on("click", function() {
        that.openShowPage(calendar);
      });
      // 更新画面表示ボタン押下イベント
      btnUpdateJfcCalendarItem.on("click", function() {
        that.openUpdatePage(calendar);
      });
      // 削除ボタン押下イベント
      btnDeleteJfcCalendarItem.on("click", function() {
        that.deleteCalendarItemFromForm(calendar, calendarOption);
      });
      // 新規登録画面表示ボタン押下イベント
      btnInsertJfcCalendarItem.on('click', function() {
        that.insertCalendarItemFromForm(calendar);
      });
      // 終日フラグ押下時のイベント
      that.setJfcCalendarItemAllDayEvent();
    }

    // モデル名選択リストボックス変更時に新規登録画面表示の
    // ボタンの押下可・不可を切り替える
    that.setLbxCalendarViewOnChangeEvent = function() {
      that.lbxCalendarView.on("change", function(value) {
        that.setBtnInsertJfcCalendarItemDisabled(value);
      });
    };

    that.setBtnInsertJfcCalendarItemDisabled = function(value) {
      var disabled = false;
      var selectedOption = that.lbxCalendarView.getOptions(value);
      if (!selectedOption || !selectedOption.inserturl) {
        // 新規登録画面のURLがない場合はボタンを押下不可にする
        disabled = true;
      }
      btnInsertJfcCalendarItem.set("disabled", disabled);
    },

    that.setCalendarViewModelData = function(calendarOption, isMobile) {
      that.lbxCalendarView;
      if (isMobile) {
        that.lbxCalendarView = lbxJfcRegisterMobileCalendarViewModel;
      } else {
        that.lbxCalendarView = lbxJfcCalendarViewModel;
      }
      var options = that.lbxCalendarView.get("options");
      if (options && options.length > 0) {
        return;
      }
      that.setLbxCalendarViewOnChangeEvent();
      var url = "rest/" + calendarOption.modelId + "/ical/models";
      if (calendarOption.domainURL) {
        url = calendarOption.domainURL + url;
      }
      request(url, {
        headers: {
          'X-Wagby-RESTAPIVersion': "v2",
        },
        handleAs: "json",
        withCredentials: true,
      }).then(function(data) {
        options = [];
        if (data && data.length > 0) {
          for (var i=0,l=data.length; i<l; i++) {
            var calendarviewModel = data[i];
            options.push({
              label: calendarviewModel.modelname,
              value: calendarviewModel.modelid,
              inserturl: calendarviewModel.inserturl,
            });
          }
        }
        that.lbxCalendarView.set("options", options);
        if (options.length > 0) {
          that.lbxCalendarView.set("value", options[0].value);
        }
      }, function(data) {
        console.error("setCalendarViewModelData error: ", data);
        if (data.message) {
          jfcBubble.error(data.message);
        }
      });
    };
  });
};

function activateTabContainsErrorWidget(widget) {
  var contentPane = widget.getParent();
  if (contentPane.declaredClass !== "dijit.layout.ContentPane") {
    return;
  }
  var tabContainer = contentPane.getParent();
  if (tabContainer.declaredClass !== "dijit.layout.TabContainer") {
    return;
  }
  tabContainer.selectChild(contentPane);
  activateTabContainsErrorWidget(tabContainer);
}

function focusErrorWidget() {
  var widgets = getAllWidgets();
  require(["dojo/_base/array"], function(array) {
    var errorWidgets = array.filter(widgets, function(widget) {
      return widget.isValid && !widget.isValid();
    });
    var errorWidget = errorWidgets[0];
    activateTabContainsErrorWidget(errorWidget);
    errorWidget.focus();
  });
}

function isFormValid(f) {
  var isFormValid = true;
  require(["dijit/registry"], function(registry) {
    var formWidget = registry.byId(f.id);
    if (formWidget && formWidget.declaredClass &&
        formWidget.declaredClass === "dijit.form.Form") {
      isFormValid = formWidget.validate();
      if (!isFormValid) {
        focusErrorWidget();
      }
    }
  });
  return isFormValid;
}

function doSubmitForm(form, actionName, isNoValidate) {
  if (!form) {
    console.error("doSubmitForm form null");
    console.trace();
    return;
  }
  var actionParam = "action_";
  if (actionName === undefined || actionName === null) {
    if (form.id.lastIndexOf("condition", 0) === 0) {
      actionParam = actionParam + "Search_Condition";
    } else {
      actionParam = actionParam + "Send";
    }
    actionName = actionParam;
  }
  if (window.isSubmitIfError) {
    isNoValidate = window.isSubmitIfError(actionName);
  }
  if (window.doSubmit && !window.doSubmit(form, isNoValidate)) {
    if (form.target === "_blank") {
      form.target = '_self';
    }
    return;
  }
  if (!window.doSubmit_skipButtonOff &&
      form.target !== "_blank" &&
      actionName && actionName !== "action_Download" && actionName.indexOf("action_Print") === -1) {
    buttonOff();
  }
  if (actionName && actionName !== "") {
    form.SENDACTION.name = actionName;
    // 一覧更新のコピー、新規ボタン押下時はスクロールを維持する
    require(["dojo/cookie"], function(cookie) {
      var id = cookie("scrollAnchorId");
      if (!id || !(id.indexOf("ULCopy") !== -1 || id.indexOf("ULInsert") !== -1
                   || id.lastIndexOf("btnAdd_", 0) === 0)) {
        removeScrollPosition();
      }
    });
  }
  form.submit();
  if (window.doSubmit && form.target === "_blank") {
    form.target = '_self';
  }
  window.doSubmit_skipButtonOff = false;
  changeTargetCtrlDisabled();
  if (actionName && actionName !== "") {
    setTimeout(function() {
      form.elements[actionName].name = 'SENDACTION';
    }, 10);
  }
}

function doConfirmSubmitForm(form, actionName, message) {
  if (actionName === "action_ULExecute") {
    if (!isFormValid(form)) {
      return;
    }
  }
  showConfirmDialog(message, function() {
    doSubmitForm(form, actionName, true);
  });
}

function disablePankuzu() {
  require(["dojo/dom-attr", "dojo/dom-style", "dojo/query"], function(domAttr, domStyle, query) {
    query("ul[id='pankuzu'] a").forEach(function(node) {
      domAttr.set(node, "disabled", "true");
      domAttr.set(node, "href", "javascript:void(0)");
      node.onclick = function(event) { event.preventDefault(); };
    });
  });
}
function decodeHtml(s) {
    return s.replace(/&#0?39;/g, "'").replace(/&#0?34;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
}

const FixTableHeaderRowColumn = function() {
  this.initialize.apply(this, arguments);
}
FixTableHeaderRowColumn.prototype = {
  //コンストラクタ
  initialize: function(args) {
    // ヘッダ行固定とする一覧の id 属性接頭辞
    this.modelId = args.modelId || "";
    // フッタ(集計欄)のラベル幅
    this.FOOTER_LABEL_WIDTH = 45;
    // スクロールバー表示時のパディング幅
    this.SCROLLBAR_WIDTH = isEdge() ? 15 : 17; // Edge の場合はスクロールバーが細い為 2px 減らす
    // ステータス列の幅
    this.STATUS_WIDTH = 70;
    // ボタンの幅
    this.BUTTON_WIDTH = 75;
    // 幅の初期値
    this.WIDTH_ = 10;
    // テーブルを囲むdivタグ
    this.tableContainer;
  },

  init: function() {
    require(["dijit/registry"], (registry) => {
      // 左右ヘッダ行テーブル
      this.header1_left = document.getElementById(`${this.modelId}_header1_left`);
      this.header1 = document.getElementById(`${this.modelId}_header1`);
      // 左右値行テーブル
      this.body1_left = document.getElementById(`${this.modelId}_body1_left`);
      this.body1 = document.getElementById(`${this.modelId}_body1`);
      // 集計欄表示時の外枠
      this.body0_left = document.getElementById(`${this.modelId}_body0_left`);
      this.body0 = document.getElementById(`${this.modelId}_body0`);
      // 左右フッタ(集計欄)行テーブル
      this.footer1_left = document.getElementById(`${this.modelId}_footer1_left`);
      this.footer1 = document.getElementById(`${this.modelId}_footer1`);
      if (!this.body1 || this.body1.children.length === 0) {
        return;
      }
      // ヘッダ行固定時にスクロールバーの有無でテーブルの幅、右側余白を調整する関数を生成する
      this.createSetScrollbarPaddingFunc();

      // テーブルの列幅を固定する
      this.fixTableColumnSize();

      // 列固定の場合、左側のテーブルを固定する
      if (this.header1_left || this.body1_left) {
        this.fixLeftTable();
      }
      // テーブルを固定する
      if (this.header1 || this.body1) {
        this.fixTable();
      }
      // 分割したテーブルの接続部分の角丸設定を無効にする
      this.setBorderRadius();
      // テーブルがタブ内にある場合、タブ表示時にテーブルのスクロールバーの幅を
      // 調整する関数を実行するイベントを設定する
      this.setTabContainerOnShowEvent(registry);
    });
  },

  getTabContentPane: function(node, registry) {
    if (node.classList.contains("dijitContentPane")) {
      return registry.byId(node.id);
    }
    if (!node || node.id === "centerarea" || node.nodeName === "BODY") {
      return null;
    }
    return this.getTabContentPane(node.parentNode, registry);
  },

  setTabContainerOnShowEvent: function(registry) {
    if (!this.header1) {
      return;
    }
    const contentPane = this.getTabContentPane(this.header1, registry);
    if (!contentPane) {
      return;
    }
    contentPane.on("show", () => {
      // テーブルの列幅を固定する
      this.releaseTableLayoutFixed();
      this.fixTableColumnSize();
      this.setScrollbarPaddingFunc();
    });
  },

  createSetScrollbarPaddingFunc: function() {
    const table = this.body1.querySelector("table[class*='display_table']");
    this.setScrollbarPaddingFunc = () => {
      if (!table) {
        return;
      }
      const body = this.body0 ? this.body0 : this.body1;
      let width = "99.5";
      let scrollbarPadding = "0";

      // 横スクロールバーが表示されている場合に左右のテーブルの高さを調整する
      this.setPaddingForHorizontalScroll();

      if (!this.header1) {
        return;
      }
      if (body.scrollHeight > body.clientHeight) {
        scrollbarPadding = this.SCROLLBAR_WIDTH;
      }
      // スクロールバーの幅だけマージンを設定するため、
      // ヘッダの幅設定を解除する
      width = `${width}%`;
      scrollbarPadding = `${scrollbarPadding}px`;
      this.header1.children[0].style.width = width;
      if (!this.body0) {
        this.body1.children[0].style.width = width;
      }
      this.header1.style.marginRight = scrollbarPadding;
      if (this.footer1) {
        this.footer1.style.marginRight = scrollbarPadding;
      }
    }
  },

  fixTableColumnSize: function() {
    if (this.header1_left || this.body1_left) {
      // 左側のテーブルの列幅をセットする
      this.setTableColumnSize(this.header1_left, this.body1_left, this.footer1_left);
    }
    if (this.header1 || this.body1) {
      // テーブルの列幅をセットする
      this.setTableColumnSize(this.header1, this.body1, this.footer1);
    }
    // 分割したテーブルを固定レイアウトにする
    this.setTableLayoutFixed();
  },

  fixLeftTable: function() {
    if (this.header1_left) {
      const tableContainer = this.header1_left.parentNode.parentNode;
      if (tableContainer) {
        const display = tableContainer.style.display;
        if (display !== "flex") {
          tableContainer.style.display = "flex";
        }
      }
      // 左右のヘッダ行の高さを合わせる
      this.setTableRowSize(this.header1_left, this.header1);
      if (!this.body1_left) {
        return;
      }
    }
    // 左右のテーブルの値行の高さを合わせる
    this.setTableRowSize(this.body1_left, this.body1);
    // 左側のテーブルは縦スクロールバーを非表示にする
    require(["dojo/on"], (on) => {
      this.body1_left.style.overflowY = "hidden";
      // フッタテーブルがある場合横スクロールバーも非表示にする
      if (this.footer1_left) {
        this.body1_left.style.overflowX = "hidden";
      }
      // 左右のテーブルの縦スクロールを同期させる
      let bodyLeft = this.body1_left;
      let bodyRight = this.body1;
      if (this.body0_left) {
        // 集計欄がある場合
        this.body0_left.style.overflowY = "hidden";
        bodyLeft = this.body0_left;
        bodyRight = this.body0;
      }
      on(bodyRight, "scroll", (e) => {
        bodyLeft.scrollTop = bodyRight.scrollTop;
      });
    });
    // 左側のテーブルのボディ部にマウスホイールイベントを設定する
    this.setLeftTableMouseWheelEvent(this.body1_left, this.body1);
    // 左側のテーブルのスクロールイベントを設定する
    this.setScrollEvent(this.header1_left, this.body1_left, this.footer1_left);
  },

  setLeftTableMouseWheelEvent: function(leftBody, rightBody) {
    // スクロールバーが非表示の場合はイベントを設定しない
    if (rightBody.scrollHeight === rightBody.clientHeight) {
      return;
    }
    // 左側のテーブルのボディ部にマウスホイールイベントを設定し、
    // 右側と左側のテーブルのボディ部をスクロールさせる
    leftBody.addEventListener("wheel", (event) => {
      // スクロールバーの位置が最上部、最下部に到達するまでは
      // ブラウザウィンドウのスクロールを止める
      if (event.deltaY < 0 && rightBody.scrollTop !== 0 ||
          event.deltaY >= 0 && (rightBody.scrollHeight - rightBody.clientHeight) > rightBody.scrollTop) {
        event.preventDefault();
      }
      rightBody.scrollTop = rightBody.scrollTop + event.deltaY;
      leftBody.scrollTop = rightBody.scrollTop;
    });
    // 左側のテーブルにテキストエリアがある場合、テーブルのスクロールイベントを
    // 無効にし、テキストエリアのスクロールイベントが有効となるようにする
    this.setIgnoreTextareaWheelScrollEvent(leftBody);
  },

  setIgnoreTextareaWheelScrollEvent: function(leftBody) {
    if (!isEditScreen()) {
      return;
    }
    leftBody.querySelectorAll("textarea").forEach((textarea) => {
      textarea.addEventListener("wheel", (event) => {
        if (event.deltaY < 0 && textarea.scrollTop == 0 ||
            (Math.abs(textarea.scrollHeight - textarea.clientHeight - textarea.scrollTop) < 1)) {
          // テキストエリアのスクロール位置が上端、下端の場合は、
          // テーブルのスクロールイベントを有効とする
          return;
        }
        event.stopPropagation();
      });
    });
  },

  fixTable: function() {
    // ボディ部に縦スクロールバーが表示された場合、ヘッダ部にスクロールバーの幅を加える
    this.setScrollbarPaddingFunc();
    // テーブルのスクロールイベントを設定する
    this.setScrollEvent(this.header1, this.body1, this.footer1);
  },

  setPaddingForHorizontalScroll: function() {
    if (!this.body1_left || this.body0) {
      return;
    }
    let isSetPaddingBodyLeft = false;
    // 左側のテーブルに横スクロールバーが表示されている場合、左右の行がずれないよう
    // 左側の表示エリアの高さにスクロールバー分の高さを加える
    const body1LeftScrollWidth = this.body1_left.scrollWidth;
    const body1LeftClientWidth = this.body1_left.clientWidth;
    if (body1LeftScrollWidth > body1LeftClientWidth) {
      this.setMaxHeightForScrollBar(this.body1_left);
      isSetPaddingBodyLeft = true;
    }
    const body1ScrollWidth = this.body1.scrollWidth;
    const body1ClientWidth = this.body1.clientWidth;
    if (body1ScrollWidth > body1ClientWidth) {
      // 右側のテーブルに横スクロールバーが表示されている場合、左右の行がずれないよう
      // 右側の表示エリアの高さにスクロールバー分の高さを加える
      this.setMaxHeightForScrollBar(this.body1);
    } else if (isSetPaddingBodyLeft) {
      // 左側のテーブルに横スクロールバーが表示されている場合、右側のテーブルの縦表示エリアを縮める
//      domStyle.set(this.body1, "maxHeight", (this.body1.clientHeight - this.SCROLLBAR_WIDTH) + "px");
//      this.body1.style.maxHeight = `(${this.body1.clientHeight} - ${this.SCROLLBAR_WIDTH})px`);
    }
  },

  setMaxHeightForScrollBar: function(body) {
    body.style.maxHeight = `${parseInt(body.style.maxHeight, 10) + this.SCROLLBAR_WIDTH}px`;
  },

  getMaxBodyColumnsWidthAllRows: function(bodyRows) {
    const bodyColumnsWidth = [];
    const targetRows = this.getTargetRowsSetColumnWidth(bodyRows);
    targetRows.forEach((row) => {
      Array.from(row.querySelectorAll("td:not([style*='display: none']):not([class*='dijitReset'])"))
        .filter((column) => column.style.display !== "none")
        .forEach((column, index) => {
          const width = this.getMaxWidth(column);
          bodyColumnsWidth[index] = Math.max((bodyColumnsWidth[index] || 0), width);
        });
    });
    return bodyColumnsWidth;
  },

  setTableColumnSize: function(header, body, footer) {
    if (!(header || body)) {
      return;
    }
    let headerTable;
    let bodyRows;
    let bodyColumns;
    let bodyColumnsWidth;
    let bodyTableTdQuery;
    // ヘッダテーブルの有無により値行の対象を変更する
    if (header) {
      headerTable = header;
      bodyRows = body.querySelectorAll("tr:not([style*='display: none'])[class*='display_field']");
      bodyColumns = bodyRows[0].querySelectorAll("td:not([style*='display: none']):not([class*='dijitReset'])");
      bodyColumnsWidth = this.getMaxBodyColumnsWidthAllRows(bodyRows);
    } else {
      headerTable = body;
      bodyRows = body.querySelectorAll("tbody > tr:not([style*='display: none'])[class*='display_field']");
      bodyColumns = bodyRows[0].querySelectorAll("td:not([style*='display: none']):not([class*='dijitReset'])");
      bodyColumnsWidth = this.getMaxBodyColumnsWidthAllRows(bodyRows);
    }
    // ヘッダ行の列を取得する
    const headerColumns = headerTable.querySelectorAll("table[class*='display_table'] tr:first-child > th:not([style*='display: none'])");
    const footerColumns = !footer ? null :
      footer.querySelectorAll("table[class*='display_table'] tr:first-child > td:not([style*='display: none']):not([class*='dijitReset'])");

    const columnWidth = [];
    headerColumns.forEach((th, index) => {
      const bodyColumn = bodyColumns[index];
      const bodyColumnWidth = bodyColumnsWidth[index];
      const footerColumn = !footer ? null : footerColumns[index];
      const width = this.getMaxColumnWidth(th, bodyColumnWidth, footerColumn);
      this.setColumnWidth(th, width);
      this.setColumnWidth(bodyColumn, width);
      this.setColumnWidth(footerColumn, width);
      columnWidth.push(width);
    });
  },

  getTargetRowsSetColumnWidth: function(rows) {
    if (!rows || rows.length === 0) {
      return [];
    }
    // 段組みレイアウトのテーブルでない場合、そのまま返す
    const isMultiRowTable = rows[0].dataset.rownum;
    if (!isMultiRowTable) {
      return rows;
    }
    // 段組みレイアウトのテーブルの場合、一段目の行のみ列幅の設定対象となる
    let prevRownum = "";
    return rows.flatMap((row) => {
      const rownum = row.dataset.rownum;
      if (rownum !== prevRownum) {
        prevRownum = rownum;
        return row;
      } else {
        return [];
      }
    });
  },

  getMaxColumnWidth: function(headerColumn, bodyColumnWidth, footerColumn) {
    const headerWidth = this.getMaxWidth(headerColumn);
    let footerWidth = 0;
    if (this.isFooterColumnAggregateLabel(footerColumn)) {
      // 集計欄がある場合、先頭列は集計ラベルを表示するため、
      // ラベル表示用に最低幅を確保しておく
      footerWidth = this.FOOTER_LABEL_WIDTH;
    } else {
      footerWidth = this.getMaxWidth(footerColumn);
    }
    if ((typeof headerWidth === "string" || headerWidth instanceof String) &&
        headerWidth.indexOf("%") !== -1) {
      return headerWidth;
    }
    return `${Math.max(headerWidth, bodyColumnWidth, footerWidth)}px`;
  },

  isFooterColumnAggregateLabel: function(footerColumn) {
    if (!footerColumn) {
      return false;
    }
    if (footerColumn.children.length === 0) {
      return false;
    }
    return footerColumn.children[0].tagName === "SPAN";
  },

  getMaxWidth: function(td) {
    if (!td) {
      return 0;
    }
    let maxWidth = 0;
    let styleWidth = 0
    let styleMaxWidth = 0;
    if (td.classList.contains("display_label_button") ||
        td.classList.contains("display_field_button") ||
        td.classList.contains("display_field_buttons")) {
      maxWidth = this.getWidthByButtons(td);
    } else {
      let attrWidth = td.attributes["width"]?.nodeValue;
      if (attrWidth && attrWidth.indexOf("%") !== -1) {
        maxWidth = attrWidth;
      } else {
        attrWidth = attrWidth ? parseInt(attrWidth.replace("px", ""), 10) : 0;
        let clientWidth = td.clientWidth || 0;
        if (td.children && td.children.length > 0) {
          if (td.children[0].tagName === "SPAN" || td.children[0].tagName === "DIV" ||
              td.children[0].tagName === "TEXTAREA" || td.tagName === "TH" && td.children[0].tagName === "A") {
            styleWidth = isEditScreen() ? this.getSumOfChildrenWidth(td.children[0]) :
              td.children[0].offsetWidth;
            clientWidth = 0;
          }
        } else if (!td.children || td.children.length === 0 || td.children[0].tagName !== "A") {
          styleWidth = parseInt(td.style.width, 10) || 0;
        }
        styleMaxWidth = td.style.maxWidth || 0;
        if (styleMaxWidth) {
          maxWidth = styleMaxWidth;
        } else {
          maxWidth = Math.max(attrWidth, styleWidth, clientWidth);
        }
      }
    }
    return maxWidth;
  },

  getSumOfChildrenWidth: function(node) {
    if (node.children.length === 0) {
      return node.offsetWidth + this.WIDTH_;
    }
    return Array.from(node.children)
      .map((child) => child.offsetWidth)
      .reduce((sum, width) => sum + width, this.WIDTH_);
  },

  getWidthByButtons: function(node) {
    const status = node.querySelector("div[id$='jfcstatus']");
    if (node.tagName === "TH" || status) {
      return this.STATUS_WIDTH;
    }
    const buttons = node.querySelectorAll("span.dijitButton");
    if (!buttons || buttons.length === 0) {
      return this.BUTTON_WIDTH;
    }
    const initialWidth = buttons.length * 6;
    return Array.from(buttons).map((button) => button.offsetWidth)
      .reduce((sum, width) => { return sum + width; }, initialWidth);
  },

  setColumnWidth: function(column, width) {
    if (!column) {
      return;
    }
    column.style.width = width;
    column.style.boxSizing = "border-box";
  },

  setTableRowSize: function(leftTable, rightTable) {
    if (!(leftTable && rightTable)) {
      return;
    }
    // 左右のテーブルのヘッダ部の行を揃える
    const leftTableHeaderRows = Array.from(leftTable.querySelectorAll("table[class*='display_table'] > thead > tr"));
    const rightTableHeaderRows = Array.from(rightTable.querySelectorAll("table[class*='display_table'] > thead > tr"));
    if (leftTableHeaderRows.length > 0 && rightTableHeaderRows.length > 0) {
      this.setRowHeight(leftTableHeaderRows, rightTableHeaderRows);
    }
    // 左右のテーブルのボディ部の行を揃える
    const leftTableBodyRows = Array.from(leftTable.querySelectorAll("table[class*='display_table'] > tbody > tr"));
    const rightTableBodyRows = Array.from(rightTable.querySelectorAll("table[class*='display_table'] > tbody > tr"));
    if (leftTableBodyRows.length > 0 && rightTableBodyRows.length > 0) {
      this.setRowHeight(leftTableBodyRows, rightTableBodyRows);
    }
  },

  setRowHeight: function(leftTableRows, rightTableRows) {
    rightTableRows.forEach((rightTr, index) => {
      const leftTr = leftTableRows[index];
      if (rightTr && leftTr) {
        const maxLeftTableRowHeight = this.getMaxHeight(leftTr);
        const maxRightTableRowHeight = this.getMaxHeight(rightTr);
        const height = `${(maxLeftTableRowHeight > maxRightTableRowHeight ? maxLeftTableRowHeight : maxRightTableRowHeight) + 1}px`;

        leftTr.style.height = height;
        rightTr.style.height = height;
      }
    });
  },

  getBodyFirstRow: function(rows) {
    const firstRow = rows.find((row) => row.firstElementChild.tagName !== "TH");
    return firstRow ? firstRow : rows[0];
  },

  getMaxHeight: function(tr) {
    if (!tr) {
      return 0;
    }
    const getMaxHeightOfChildren = (node) => {
      const nodeHeight = node.offsetHeight;
      if (node.children.length === 0) {
        return nodeHeight;
      }
      const maxChildNodeHeight = Array.from(node.children)
        .map((child) => child.offsetHeight)
        .reduce((a, b) => { return a > b ? a : b }, node.offsetHeight);
      return maxChildNodeHeight;
    }

    // 行内の各列の高さの最大値を取得する
    const clientHeight = Array.from(tr.children)
      .map((td) => getMaxHeightOfChildren(td))
      .reduce((a, b) => a > b ? a : b);

    const attrHeight = parseInt(tr.getAttribute("height"), 10) || 0;
    const styleHeight = parseInt(window.getComputedStyle(tr).height, 10) || 0;

    return Math.max(attrHeight, clientHeight, styleHeight);
  },

  setTableLayoutFixed: function() {
    // 固定レイアウトを解除するために設定変更対象のテーブルを配列に保持する
    this.targetTables = [];
    this.addTable(this.header1_left);
    this.addTable(this.header1);
    this.addTable(this.body1_left);
    this.addTable(this.body1);
    this.addTable(this.footer1_left);
    this.addTable(this.footer1);

    this.targetTables.forEach((table) => table.style.tableLayout = "fixed");
  },

  addTable: function(elem) {
    if (!elem) {
      return;
    }
    const table = elem.querySelector("table[class*='display_table']");
    if (table) {
      this.targetTables.push(table);
    }
  },

  releaseTableLayoutFixed: function() {
    this.targetTables.forEach((table) => table.style.tableLayout = "auto");
  },

  setScrollEvent: function(header, body, footer) {
    if (!(header || footer)) {
      return;
    }
    let scrollNode = footer || body;
    let footerScrollEventId = null;
    require(["dojo/on"], function(on) {
      if (footer) {
        on(body, "scroll", function() {
          footer.scrollLeft = body.scrollLeft;
        });
        on(footer, "scroll", function() {
          if (footerScrollEventId) {
            clearTimeout(footerScrollEventId);
          }
          footerScrollEventId = setTimeout(function() {
            header.scrollLeft = footer.scrollLeft;
            body.scrollLeft = footer.scrollLeft;
            footerScrollEventId = null;
          }, 25);
        });
      } else {
        on(body, "scroll", function() {
          header.scrollLeft = body.scrollLeft;
        });
      }
    });
  },

  setBorderRadius: function() {
    // 集計欄の表示がある場合、分割されたテーブルの接地部分の角丸設定を無効にする
    if (!this.footer1 || isCssLayout()) {
      return;
    }
    let that = this;
    require(["dojo/dom-style", "dojo/query", "dojo/NodeList-dom"], function(domStyle, query) {
      // 値表示のテーブル
      if (that.body1_left) {
        query("table[class*='display_table']", that.body1_left).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child", that.body1_left).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child > td:first-child", that.body1_left).style("borderBottomLeftRadius", "0px");
      } else {
        query("table[class*='display_table']", that.body1).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child", that.body1).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child > td:first-child", that.body1).style("borderBottomLeftRadius", "0px");
      }
      query("table[class*='display_table']", that.body1).style("borderBottomRightRadius", "0px");
      query("table[class*='display_table'] tr:last-child", that.body1).style("borderBottomRightRadius", "0px");
      query("table[class*='display_table'] tr:last-child > td:last-child", that.body1).style("borderBottomRightRadius", "0px");
      // 集計欄
      if (that.footer1_left) {
        query("table[class*='display_table']", that.footer1_left).style("borderTopLeftRadius", "0px");
        query("table[class*='display_table'] tr:first-child", that.footer1_left).style("borderTopLeftRadius", "0px");
        query("table[class*='display_table'] tr:first-child > td:first-child", that.footer1_left).style("borderTopLeftRadius", "0px");
        query("table[class*='display_table']", that.footer1_left).style("borderTopRightRadius", "0px");
        query("table[class*='display_table'] tr:first-child", that.footer1_left).style("borderTopRightRadius", "0px");
        query("table[class*='display_table'] tr:first-child > td:last-child", that.footer1_left).style("borderTopRightRadius", "0px");
        query("table[class*='display_table']", that.footer1_left).style("borderBottomRightRadius", "0px");
        query("table[class*='display_table'] tr:last-child", that.footer1_left).style("borderBottomRightRadius", "0px");
        query("table[class*='display_table'] tr:last-child > td:last-child", that.footer1_left).style("borderBottomRightRadius", "0px");
        query("table[class*='display_table'] ", that.footer1).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child", that.footer1).style("borderBottomLeftRadius", "0px");
        query("table[class*='display_table'] tr:last-child > td:first-child", that.footer1).style("borderBottomLeftRadius", "0px");
      }
      query("table[class*='display_table']", that.footer1).style("borderTopLeftRadius", "0px");
      query("table[class*='display_table'] tr:first-child", that.footer1).style("borderTopLeftRadius", "0px");
      query("table[class*='display_table'] tr:first-child > td:first-child", that.footer1).style("borderTopLeftRadius", "0px");
      query("table[class*='display_table']", that.footer1).style("borderTopRightRadius", "0px");
      query("table[class*='display_table'] tr:first-child", that.footer1).style("borderTopRightRadius", "0px");
      query("table[class*='display_table'] tr:first-child > td:last-child", that.footer1).style("borderTopRightRadius", "0px");
    });
  }
}

CtrlDisableManagerList = new Array();

function addCtrlDisableManager(cdm) {
    CtrlDisableManagerList.push(cdm); 
}

function changeTargetCtrlDisabled() {
   for (i in CtrlDisableManagerList) {
      (CtrlDisableManagerList[i]).changeTargetCtrlDisabled();
   }
}

/**
 * オプション表示(日付)の和暦の1年を元年へ変更する関数
 */
function replaceFirstYearOfImperialEra(dateStr) {
  if (!isReplaceFirstYearOfImperialEra) {
    return dateStr;
  }
  var replacedDateStr = dateStr;
  var firstYearOfImperialEra = new RegExp("^（(" + warekiFullnameStr + ")1年(.*)）");
  if (firstYearOfImperialEra.test(dateStr)) {
    replacedDateStr = dateStr.replace(firstYearOfImperialEra, "（$1元年$2）");
  }
  return replacedDateStr;
}

function convClassname4Relax(s) {
  if (!s || s === "") {
    return s;
  }
  var convStr = "";
  for (var i=0,l=s.length; i<l; i++) {
    var c = s.charAt(i);
    if (c === "_") {
      while (i+1 < s.length && (c = s.charAt(++i)) === "_") ;
      if (c !== "_") {
        convStr += c.toUpperCase();
      }
    } else {
      convStr += c;
    }
  }
  return convStr;
}

function capFirst(str) {
  if (!str || str === "") {
    return str;
  }
  var name = convClassname4Relax(str);
  return name.substring(0, 1).toUpperCase() + name.substring(1);
}

function showConfirmDialog(msg, okCallback, cancelCallback, hideCallback) {
  showDijitConfirm({
    "message": msg,
    "onExecute": okCallback,
    "onCancel": cancelCallback,
    "onHide": hideCallback,
  });
}

var confirmDialog;
var confirmDialogArgs;
function showDijitConfirm(args) {
  if (!window.confirmDialog) {
    confirmDialogArgs = {
      "title": getPagetitle(),
      "type": args.type || "Confirm",
      "icon": args.icon,
      "style": args.style,
      "message": args.message || "",
      "onExecute": args.onExecute,
      "onCancel": args.onCancel,
      "onShow": args.onShow,
      "onHide": args.onHide,
    };
    createConfirmDialog(confirmDialogArgs, function(dialog) {
      window.confirmDialog = dialog;
      dialog.show();
    });
  } else {
    confirmDialogArgs.type = args.type;
    confirmDialogArgs.icon = args.icon;
    window.confirmDialog.setEventCallbackFunc(args);
    window.confirmDialog.updateMessage(args.message);
    window.confirmDialog.show();
  }
}

var alertDialog;
function showAlertDialog(message, callback) {
  var callbackFunc = {
    "onShow": function() {
      // ダイアログ表示後にOKボタンにフォーカスをセットする
      setTimeout(function() {
        window.alertDialog.focus();
        window.alertDialog.okButton.focus();
      }, 130);
    }
  };
  if (callback) {
    callbackFunc.onExecute = callback;
    callbackFunc.onHide = callback;
  }
  if (!window.alertDialog) {
    createAlertDialog({
      "message": message,
      "callbackFunc": callbackFunc,
    }, function(dialog) {
      dialog.show();
    });
  } else {
    window.alertDialog.updateMessage(message);
    window.alertDialog.setEventCallbackFunc(callbackFunc);
    window.alertDialog.show();
  }
}

function createAlertDialog(args, callback) {
  createConfirmDialog({
    "title": getPagetitle(),
    "type": "alert",
    "message": args.message || "",
  }, function(dialog) {
    dialog.setEventCallbackFunc(args.callbackFunc);
    window.alertDialog = dialog;
    if (callback) {
      callback(dialog);
    }
  });
}

function createConfirmDialog(args, callback) {
  var that = this;
  require(["dijit/ConfirmDialog", "dojo/aspect", "dojo/dom-construct", "dojo/dom-style"], function(ConfirmDialog, aspect, domConstruct, domStyle) {
    var dialog = new ConfirmDialog({
      title: args.title || getAppname(),
      style: args.style || "width: 400px",
      autofocus: false,
      actionBarTemplate: args.actionBarTemplate || "<div class='dijitDialogPaneActionBar' data-dojo-attach-point=\"actionBarNode\">\n\t<button data-dojo-type='dijit/form/Button' id='jfc" + args.type + "DialogBtnOk' type='submit' data-dojo-attach-point=\"okButton\"></button>\n\t<button data-dojo-type='dijit/form/Button' id='jfc" + args.type + "DialogBtnCancel' type='button'\n\t\t\tdata-dojo-attach-point=\"cancelButton\" data-dojo-attach-event='click:onCancel'></button>\n</div>\n",
    });
    // サブメニューを上に表示している場合、ダイアログが表示されるとスクロール位置が
    // 画面下部になるため、ダイアログ表示前のスクロール位置を保持しておく
    var scrollY = 0;
    if (window.submenuDisplayArea === "top") {
      aspect.before(dialog, "show", function() {
        scrollY = window.scrollY;
      });
    }
    domStyle.set(dialog.actionBarNode, {
      'border': "none",
      'background-color': "#fff",
      'text-align': "right",
      'padding': "10px"
    });
    domStyle.set(dialog.okButton.focusNode, "min-width", "70px");
    domStyle.set(dialog.cancelButton.focusNode, "min-width", "70px");
    domStyle.set(dialog.titleNode.parentNode, "padding-left", "5px");
    dialog.okButton.set("label", args.okButtonLabel || res.BUTTON_OK);
    dialog.cancelButton.set("label", args.cancelButtonLabel || res.BUTTON_CANCEL);

    var iconNode = domConstruct.create("div", {
    }, dialog.titleNode, "first");
    var confirmIcon = domConstruct.create("i", {
      "class": "fas fa-exclamation-triangle jfcConfirmIcon",
      "style": "display: none;",
    }, iconNode, "first");
    var alertIcon = domConstruct.create("i", {
      "class": "fas fa-minus-circle jfcAlertIcon",
      "style": "display: none;",
    }, iconNode, "first");
    var infoIcon = domConstruct.create("i", {
      "class": "fas fa-info-circle jfcAlertIcon",
      "style": "display: none;color: #3333CC;",
    }, iconNode, "first");
    var questionIcon = domConstruct.create("i", {
      "class": "fas fa-question-circle jfcAlertIcon",
      "style": "display: none;color: #3333CC;",
    }, iconNode, "first");

    var messageDom = domConstruct.create("div", { innerHTML: args.message || "" }, dialog.containerNode);
    dialog.updateMessage = function(message) {
      messageDom.innerHTML = message || "";
    }

    dialog.on("Show", function() {
      var display = "";
      var icon = args.icon;
      if (args.type && args.type.lastIndexOf("alert", 0) === 0) {
        if (! icon) {
          icon = "alert";
        }
        display = "none";
      } else {
        if (! icon) {
          icon = "confirm";
        }
      }
      if (icon === "none") {
      } else if (icon === "alert") {
        domStyle.set(alertIcon, "display", "block");
      } else if (icon === "confirm") {
        domStyle.set(confirmIcon, "display", "block");
      } else if (icon === "info") {
        domStyle.set(infoIcon, "display", "block");
      } else if (icon === "question") {
        domStyle.set(questionIcon, "display", "block");
      }
      if (icon !== "alert") {
        domStyle.set(alertIcon, "display", "none");
      }
      if (icon !== "confirm") {
        domStyle.set(confirmIcon, "display", "none");
      }
      if (icon !== "info") {
        domStyle.set(infoIcon, "display", "none");
      }
      if (icon !== "question") {
        domStyle.set(questionIcon, "display", "none");
      }
      domStyle.set(dialog.cancelButton.domNode, "display", display);
      if (window.submenuDisplayArea === "top") {
        window.scrollTo(0, scrollY);
      }
    });
    aspect.after(dialog, "show", function() {
      // ダイアログ表示時にフォーカスをセットするボタンを設定する
      if (args.focusCancelButton) {
        dialog.cancelButton.focus();
      } else {
        dialog.okButton.focus();
      }
    });

    that.createDialogSetEventCallbackFunc(dialog);
    dialog.setEventCallbackFunc(args);
    if (callback) {
      callback(dialog);
    }
  });
}

function createDialogSetEventCallbackFunc(dialog) {
  dialog.on("Execute", function() {
    dialog.onExecuteFunc();
  });
  dialog.on("Cancel", function() {
    dialog.onCancelFunc();
  });
  dialog.on("Show", function() {
    dialog.onShowFunc();
  });
  dialog.on("Hide", function() {
    dialog.onHideFunc();
  });
  dialog.setEventCallbackFunc = function(args) {
    dialog.onExecuteFunc = args.onExecute || function(){};
    dialog.onCancelFunc = args.onCancel || function(){};
    dialog.onShowFunc = args.onShow || function(){};
    dialog.onHideFunc = args.onHide || function(){};
  }
}

function getAppname() {
  return document.getElementById("appnameinfo")?.innerHTML ?? " ";
}

function getPagetitle() {
  const pagetitleDom = document.querySelector("div.pagetitle");
  if (!pagetitleDom) {
    return;
  }
  const pagetitle = pagetitleDom.firstElementChild ?
    pagetitleDom.firstElementChild.firstChild.textContent :
    pagetitleDom.firstChild.textContent;
  return pagetitle ? pagetitle.trim() : "";
}

function getOpenSearchListOverlayFunc(args) {
  if (!args) {
    return function(){};
  }
  var overlay;
  require(['dijit/registry'], function(registry) {
    overlay = registry.byId(args.overlayId);
  });
  if (!overlay) {
    return function(){};
  }
  var grid = args.getGridFunc;
  if (!grid) {
    return;
  }
  return function() {
    setScrollPosition(this.id);
	idElement = args.idElement;
    contentElement = args.contentElement;
    grid.setContentValueFunc(function(row) {
      if (row) {
        args.setValueFunc(row.data[args.valueId], row.data[args.contentId]);
      }
      overlay.hide();
    });
    overlay.show();
    setTimeout(function() {
      grid.setOverlaySearchEvent();
    }, 10);
  }
}

function setJfcToolBarBtnSearchClickEvent() {
  require(['dojo/_base/connect', 'dojo/dom-style', 'dojo/query', 'dijit/registry', 'dojo/ready'], function(connect, domStyle, query, registry, ready) {
    var changeToolBarBtnSearchProperties = function(moveTo) {
      var toolBarBtnSearch = registry.byId('jfcToolBarBtnSearch');
      if (!toolBarBtnSearch) {
        return;
      }
      var moveNext = "showList";
      var transitionDir = 1;
      if (moveTo !== "condition") {
        moveNext = "condition";
        transitionDir = -1;
      }
      toolBarBtnSearch.set("moveTo", moveNext);
      toolBarBtnSearch.set("transitionDir", transitionDir);
    }
    var getDisplayResultCountFunc = function() {
      var resultcounts = query("div.display_resultcount");
      if (!resultcounts || resultcounts.length === 0) {
        return function(){}
      }
      var resultcountDiv = resultcounts[0];

      return function(moveTo) {
        var display = "";
        if (moveTo === "condition") {
          // 検索画面の場合は検索件数を非表示にする
          display = "none";
        }
        domStyle.set(resultcountDiv, "display", display);
      }
    }

    ready(function() {
      var conditionView = registry.byId('condition');
      var showListView = registry.byId('showList');
      if (!conditionView || !showListView) {
        return;
      }
      // 検索件数表示・非表示の関数
      var displayResultCountFunc = getDisplayResultCountFunc();

      // 検索条件入力フォームビュー表示前のイベント
      connect.connect(conditionView, "onBeforeTransitionIn", null,
        function(moveTo, dir, transition, context, method) {
          // 検索条件入力フォームビュー表示前に検索件数を非表示にする
          displayResultCountFunc(moveTo);
      });
      // 検索条件入力フォームビュー表示後のイベント
      connect.connect(conditionView, "onAfterTransitionIn", null,
        function(moveTo, dir, transition, context, method) {
          // 検索ボタンのプロパティを変更する
          changeToolBarBtnSearchProperties(moveTo);
      });
      // 一覧表示ビュー表示後のイベント
      connect.connect(showListView, "onAfterTransitionIn", null,
        function(moveTo, dir, transition, context, method) {
          // 検索件数を表示する
          displayResultCountFunc(moveTo);
          // 検索ボタンのプロパティを変更する
          changeToolBarBtnSearchProperties(moveTo);
      });
    });
  });
}

function setTouchScrollDisableEvent() {
  require(["dijit/registry", "dojo/dom-class", "dojo/query", "dojo/ready"], function(registry, domClass, query, ready) {
    ready(function() {
      var mainScrollableView = registry.byId('mainScrollableView');
      if (!mainScrollableView) {
        return;
      }
      query("div.mblRoundRect").forEach(function(node) {
        if (node.children && node.children.length > 0 && domClass.contains(node.children[0], "mblScrollableView")) {
          setScrollDisableFunc(mainScrollableView, node.previousElementSibling);
        }
      });
    });

    var setScrollDisableFunc = function(mainScrollableView, containerTitle) {
      if (!domClass.contains(containerTitle, "mblRoundRectCategory")) {
        return;
      }
      var title = registry.byId(containerTitle.id);
      if (!title) {
        return;
      }
      var stopScroll = false;
      title.on("click", function() {
        stopScroll = !stopScroll;
        mainScrollableView.set("disableTouchScroll", stopScroll);
      });
    }
  });
}

function setCheckboxSearchButtonClickEventFunc(id, callbackFunc, registry) {
  var btn = registry.byId(id);
  if (!btn) {
    return;
  }
  btn.on("click", callbackFunc);
}

function setCheckboxSearchButtonEventFunc(btnId, labelid, relationIdref, relationPkey, form, props, actionParamFunc) {
  require(["dijit/registry", "dojo/dom-construct", "dojo/query"], function(registry, domConstruct, query) {
    if (btnId.indexOf("${__position.count}") === -1) {
      setCheckboxSearchButtonClickEventFunc(
        btnId,
        getCheckboxSearchButtonClickEventFunc(labelid.split("${fn:escapeXml(c.id)}"), relationIdref, relationPkey, form, domConstruct, query, registry, props, actionParamFunc),
        registry
      );
    } else {
      var buttonId = btnId.split("${__position.count}");
      query("input[name^='" + buttonId[0] + "'][name$='" + buttonId[1] + "']").forEach(function(node, index) {
        var checkboxId = labelid.replace("${__position.count}", index + 1);
        checkboxId = checkboxId.split("${fn:escapeXml(c.id)}");
        setCheckboxSearchButtonClickEventFunc(
          node.name,
          getCheckboxSearchButtonClickEventFunc(checkboxId, relationIdref, relationPkey, form, domConstruct, query, registry, props, actionParamFunc, index + 1),
          registry
        );
      });
    }
  });
}

function getCheckboxSearchButtonClickEventFunc(checkboxId, relationIdref, relationPkey, form, domConstruct, query, registry, props, actionParamFunc, containerPosition) {
  var windowName = getCheckboxSearchWindowName(checkboxId);
  return function() {
    var selectedPkeys = [];
    var queryString = "input[type='checkbox'][name^='" + checkboxId[0] + "'][name$='" + checkboxId[1] + "']:checked";
    query(queryString).forEach(function(node) {
      selectedPkeys.push(node.value);
    });
    var actionName = "searchList" + relationIdref + ".do";
    if (typeof actionParamFunc === 'function') {
      actionName = actionName + actionParamFunc(form, containerPosition);
      if (actionName.includes("?")) {
        actionName = actionName + "&jfc_use_cb=true";
      } else {
        actionName = actionName + "?jfc_use_cb=true";
      }
    } else {
      actionName = actionName + "?jfc_use_cb=true";
    }
    if (selectedPkeys.length !== 0) {
      for (var i=0,l=selectedPkeys.length; i<l; i++) {
        actionName = actionName + "&" + relationPkey + "_jsh_cb=" + selectedPkeys[i];
      }
    }
    createCheckcboxSearchWindowSetSelectedValueFunc(form, checkboxId, domConstruct, query, registry);
    openSearchWindow(actionName,
                     windowName,
                     null,
                     null,
                     null,
                     props);
  }
}

function getCheckboxSearchWindowName(checkboxId) {
  if (!checkboxId || checkboxId.length === 0 || !checkboxId[0]) {
    return null;
  }
  var modelAndItemId = checkboxId[0].split("_002f");
  if (!modelAndItemId || modelAndItemId.length === 0) {
    return null;
  }
  var windowName = null;
  if (modelAndItemId.length === 2 && modelAndItemId[1]) {
    // 通常項目の場合、モデルID_p_項目ID
    windowName = modelAndItemId[0];
    windowName = windowName + "_" + modelAndItemId[1].split("_005b")[0];
  } else if (modelAndItemId.length === 3 &&
             modelAndItemId[1] && modelAndItemId[2]) {
    // コンテナ内の項目の場合、コンテナID_項目ID
    windowName = modelAndItemId[1].split("_005b")[0];
    windowName = windowName + "_" + modelAndItemId[2].split("_005b")[0];
  }
  return windowName;
}

function createCheckcboxSearchWindowSetSelectedValueFunc(form, checkboxId, domConstruct, query, registry) {
  var actionName = "";
  if (form.id && form.id.lastIndexOf("condition", 0) === 0) {
    // 検索画面では選択したチェックボックスの値設定時の画面リロードで
    // 検索処理が行なわれないようアクション文字列を設定する
    actionName = "action_Refresh";
  }
  window.setCheckcboxSearchWindowSelectedValue = function(selectedPkeys) {
    if (!selectedPkeys) {
      return;
    }
    query("input[name^='"+checkboxId[0]+"'][name$='"+checkboxId[1]+"']").forEach(function(node) {
      var widget = registry.byId(node.id);
      if (selectedPkeys[node.value]) {
        delete selectedPkeys[node.value];
        if (!widget.get("checked")) {
          widget.set("checked", true);
        }
      } else {
        widget.set("checked", false);
      }
    });
    for (var pkey in selectedPkeys) {
      domConstruct.create("input", {
        type:"hidden",
        name: checkboxId[0] + pkey + checkboxId[1],
        value: pkey
      }, "jfc_hidden_item");
    }
    if (window.originalAction) {
      form.action = window.originalAction;
    }
    doSubmitForm(form, actionName, true);
  }
}

function setJfcBtnMenuEvent(dom, domStyle, fx, registry) {
  var jfcBtnMenu = registry.byId("jfcBtnMenu");
  if (!jfcBtnMenu) {
    return;
  }
  var borderlayout = registry.byId("dojolayout");
  var leadingarea = document.getElementById('jfcLeadingarea');
  var jfcMenuDisplay = false; // サブメニューエリア表示フラグ

  // leadingarea を表示する関数
  var showMenuarea = function() {
    if (leadingarea) {
      fx.wipeIn({ node: leadingarea }).play();
    }
    borderlayout.layout();
    jfcMenuDisplay = true;
  }

  // leadingarea を隠す関数
  var hideMenuarea = function() {
    if (leadingarea) {
      fx.wipeOut({ node: leadingarea }).play();
      domStyle.set(leadingarea, "display", "none");
    }
    borderlayout.layout();
    jfcMenuDisplay = false;
  }

  var toggleMenuarea = function(e) {
    if (jfcMenuDisplay) {
      hideMenuarea();
      setJfcLeadingAreaDisplayProperty("none")
    } else {
      showMenuarea();
      setJfcLeadingAreaDisplayProperty("block")
    }
    if (window.gridResizeFunc) {
      window.gridResizeFunc();
    }
  }
  jfcBtnMenu.on("click", function(e) {
    toggleMenuarea();
  });
}

function showSubmenuTree() {
  require(["dijit/Tree", "dijit/registry", "dojo/cookie", "dojo/request", "dojo/store/Memory", "dijit/tree/ObjectStoreModel"],
  function(Tree, registry, cookie, request, Memory, ObjectStoreModel) {
    window.submenuDisplayArea = "side";
    var jfcSubmenuTreeArea = document.getElementById("jfcSubmenuTreeArea");
    if (!jfcSubmenuTreeArea) {
      window.submenuDisplayArea = "top";
      return;
    }
    showJfcLeadingArea(registry, cookie);
    request("rest/submenu", {
      headers: {
        'Content-Type': "application/json; charset=utf-8",
      },
      handleAs: "json"
    }).then(function(data) {
      var store = createStore(data);
      if (store) {
        createSubmenuTree(createModel(store));
      }
    }, function(err) {
      console.error("err: ", err);
    });

    var createStore = function(data) {
      if (data.status !== "success") {
        console.error("data.status error: ", data);
        return null;
      }
      var store = new Memory({
        data: data.submenu,
        getChildren: function(object) {
          return this.query({parent: object.id});
        },
      });
      return store;
    }

    var createModel = function(store) {
      var model = new ObjectStoreModel({
        store: store,
        query: {id: 'all'},
        mayHaveChildren: function(item) {
          if (item.type === "model") {
            return false;
          }
          return true;
        }
      });
      return model;
    }

    var createSubmenuTree = function(model) {
      if (!model) {
        return;
      }
      var tree = new Tree({
        id: "jfcSubmenuTree",
        model: model,
        persist: true,
        showRoot: false,
        onClick: function(item) {
          if (!item.url) {
            return;
          }
          goPage(item.url);
        },
        getIconClass: function(item, opened){
          if (item.type === "model") {
            return "dijitLeaf";
          }
          return opened ? "dijitFolderOpened" : "dijitFolderClosed";
        },
      });
      if (!tree) {
        return;
      }
      tree.placeAt(jfcSubmenuTreeArea);
      tree.startup();
    }
  });
}

function setJfcLeadingAreaDisplayProperty(display) {
  require(["dojo/cookie"], function(cookie) {
    cookie("displayJfcLeadingarea", display, { expires: 365 });
  });
}

function showJfcLeadingArea(registry, cookie) {
  var displayJfcLeadingarea = cookie("displayJfcLeadingarea");
  if (displayJfcLeadingarea === undefined) {
    return;
  }
  var jfcBtnMenu = registry.byId("jfcBtnMenu");
  if (!jfcBtnMenu) {
    return;
  }
  if (displayJfcLeadingarea === "block") {
    jfcBtnMenu.onClick();
  }
}

function setJfcKeyEventHandler(baseEvent, keys, on, dom, registry, query) {
  var keyEventHandlers = getKeyEventHandlers(keys);
  if (!keyEventHandlers || Object.keys(keyEventHandlers).length === 0) {
    return;
  }
  on(document, "keydown", function(event) {
    var keyCode = event.keyCode + "";
    var keyEventHandler = keyEventHandlers[keyCode];
    if (!keyEventHandler) {
      return;
    }
    if (event.target.tagName === "INPUT" && !(event.keyCode >= keys.F1 && event.keyCode <= keys.F12)) {
      return;
    }
    keyEventHandler(event, dom, registry, query);
    baseEvent.stop(event);
  });
}

function openLocation(href) {
  if (window.confirm_destruction && !window.confirm_destruction()) {
    return;
  }
  location.href = href;
}

function setMainMenuSelectedTabId(menuId) {
  setSelectedTabId("mainMenuSelectedTab", menuId);
}

var scriptEditorDialog;
function setScriptEditorToTextarea(condition) {
  require(["dijit/registry", "dojo/query", "wagby/ScriptEditorDialog"], function(registry, query, ScriptEditorDialog) {
    scriptEditorDialog = new ScriptEditorDialog();
    var setOpenScriptEditorEvent = function(id) {
      var textarea = registry.byId(id);
      if (!textarea) {
        return;
      }
      textarea.on("focus", function() {
        scriptEditorDialog.setScriptWidget(textarea);
        scriptEditorDialog.show();
      });
    }
    var queryString = "textarea";
    if (condition) {
      queryString = queryString + condition;
    }
    query(queryString).forEach(function(node) {
      setOpenScriptEditorEvent(node.id);
    });
  });
}

function setAvatarImage(dom, domClass, domConstruct, registry, request, md5) {
  var jfcDrpDwnBtnGloballink = registry.byId("jfcDrpDwnBtnGloballink");
  if (!jfcDrpDwnBtnGloballink) {
    return;
  }
  domClass.remove(jfcDrpDwnBtnGloballink.iconNode, "dijitNoIcon");
  getAvatarImageSrc(dom, request, md5, function(avatarImgSrc) {
    domConstruct.create("img", {
      "class": "avatar",
      "src": avatarImgSrc
    }, jfcDrpDwnBtnGloballink.iconNode);
  });
}

function getAvatarImageSrc(dom, request, md5, callback) {
  var avatarText = getAvatarTextFromCache(dom, md5);
  if (avatarText) {
    callback(avatarText)
  } else {
    getAvatarTextFromServer(request, md5, callback);
  }
}

function getAvatarTextFromCache(dom, md5) {
  if (!window.localStorage) {
    return null;
  }
  var jfcUserId = document.getElementById("jfcUserId");
  if (!jfcUserId) {
    return null;
  }
  var user = jfcUserId.innerHTML;
  var avatarText = window.localStorage.getItem(getAvatarCacheKey(user, md5));
  if (!avatarText) {
    return null;
  }
  return getBase64ImgSrc(avatarText);
}

function getAvatarTextFromServer(request, md5, callback) {
  var defaultAvatarSrc = "img/defaultAvatar.png";
  request("rest/session/avatarImage", {
    headers: {
      'Content-Type': "application/x-www-form-urlencoded",
      'X-Wagby-RESTAPIVersion': "v2"
    },
    "handleAs": "json",
  }).then(function(avatar) {
    if (avatar) {
      callback(getBase64ImgSrc(avatar.avatarImage));
      setAvatarTextToCache(avatar, md5);
    } else {
      callback(defaultAvatarSrc);
    }
  }, function(err) {
    callback(defaultAvatarSrc);
  });
}

function setAvatarTextToCache(avatar, md5) {
  if (!window.localStorage) {
    return null;
  }
  window.localStorage.setItem(getAvatarCacheKey(avatar.username, md5), avatar.avatarImage);
}

function getBase64ImgSrc(text, type) {
  var imgType = "png";
  if (type) {
    imgType = type;
  }
  return "data:image/" + imgType + ";base64," + text;
}

function getAvatarCacheKey(user, md5) {
  return md5("wagbyAvatarImage-" + user);
}

function setUpdateListDeleteCheckboxClickEvent() {
  var setCheckboxClickEventFunc = function(checkbox, widgets) {
    checkbox.on("click", function(e) {
      for (var i=0,l=widgets.length; i<l; i++) {
        widgets[i].set("required", !checkbox.get("checked"));
      }
    });
  }
  var unsetRequiredWidegetsInDeleteRow = function(checkbox, widgets) {
    if (!checkbox.get("checked")) {
      return;
    }
    for (var i=0,l=widgets.length; i<l; i++) {
      widgets[i].set("required", false);
    }
  }

  require(["dojo/_base/array", "dojo/query", "dijit/registry"], function(array, query, registry) {
    query("input[type='checkbox'][name^='jfcdelete_']", "centerarea").forEach(function(node) {
      var widgets = registry.findWidgets(node.parentNode.parentNode.parentNode);
      var deleteCheckbox = array.filter(widgets, function(widget) {
        return widget.name && widget.name.lastIndexOf("jfcdelete_", 0) === 0;
      });
      var requiredWidgets = array.filter(widgets, function(widget) {
        return widget.required;
      });
      if (deleteCheckbox && deleteCheckbox.length > 0 &&
          requiredWidgets && requiredWidgets.length > 0) {
        setCheckboxClickEventFunc(deleteCheckbox[0], requiredWidgets);
        unsetRequiredWidegetsInDeleteRow(deleteCheckbox[0], requiredWidgets);
      }
    });
  });
}

const setShowNumOfRemainingCharEventToItems = (id) => {
  if (!id) {
    return;
  }
  const items = Array.isArray(id) ? [].concat(id) : [id];
  items.forEach((item) => setShowNumOfRemainingCharEventToItem(item));
}

const setShowNumOfRemainingCharEventToContainerItems = (id) => {
  if (!id) {
    return;
  }
  const items = Array.isArray(id) ? [].concat(id) : [id];
  items.forEach((item) => setShowNumOfRemainingCharEventToContainerItem(item.prefix, item.suffix));
}

const setShowNumOfRemainingCharEventToContainerItem = (prefix, suffix) => {
  require(["dijit/registry"], (registry) => {
    let i = 1;
    while(true) {
      let id = `${prefix}${i}${suffix}`;
      let widget = registry.byId(id);
      if (!widget) {
        break;
      }
      setShowNumOfRemainingCharEventToItem(id);
      i = i + 1;
    }
  });
}

const setShowNumOfRemainingCharEventToItem = (id) => {
  require(["dijit/registry"], (registry) => {
    const widget = registry.byId(id);
    if (!widget || !widget.maxLength) {
      return;
    }
    const remainingDisplayArea = document.getElementById(`${id}_remainingCharacter`);
    if (!remainingDisplayArea) {
      return;
    }

    const getRemainRate = (strLength) => {
      return Math.floor((widget.maxLength - strLength) / widget.maxLength * 100);
    }

    const getIconProps = (strLength) => {
      const iconProps = {
        "iconClass": "thermometer-full",
        "iconColor": "#09A318",
      };
      const remainRate = getRemainRate(strLength);
      if (remainRate > 50 && remainRate <= 75) {
        iconProps.iconClass = "thermometer-three-quarters";
      } else if (remainRate > 25 && remainRate <= 50) {
        iconProps.iconClass = "thermometer-half";
      } else if (remainRate > 10 && remainRate <= 25) {
        iconProps.iconClass = "thermometer-quarter";
        iconProps.iconColor = "#F4C722";
      } else if (remainRate > 0 && remainRate <= 10) {
        iconProps.iconClass = "thermometer-quarter";
        iconProps.iconColor = "#F92500";
      } else if (remainRate === 0) {
        iconProps.iconClass = "thermometer-empty";
        iconProps.iconColor = "#F92500";
      }
      return iconProps;
    }

    const changeIcon = (strLength) => {
      remainingDisplayArea.parentNode.querySelectorAll("i")
        .forEach((node) => {
          const iconProps = getIconProps(strLength);
          node.style.color = iconProps.iconColor;
          node.setAttribute("class", `fas fa-${iconProps.iconClass} fa-3x`)
      });
    }

    const widgetMaxLength = widget.maxLength;
    const changeRemainingStatus = (value) => {
      const strLength = value.length;
      remainingDisplayArea.textContent = widgetMaxLength - strLength;
      changeIcon(strLength);
    }
    changeRemainingStatus(widget.get("value"));

    const eventFunc = () => {
      const value = widget.get("value");
      if (!value && value !== "") {
        return;
      }
      changeRemainingStatus(value);
    }

    widget.on("change", eventFunc);
    widget.on("keyup", eventFunc);
  });
}

function setBatchBtnDisabledEvent() {
require(["dijit/registry", "dojo/on"], (registry, on) => {
  const batchBtnNameRE = RegExp("All\\d*$");
  const getBatchButtons = function() {
    return Array.from(document.querySelectorAll("input[type='button'][name^='btn']"))
      .filter((node) => batchBtnNameRE.test(node.name))
      .map((node) => registry.byNode(node.parentNode))
      .filter((button) => button);
  }

  const getBatchTargetCheckboxes = function() {
    return Array.from(document.querySelectorAll("input[type='checkbox'][name$='_jsh_cb']"))
      .map((node) => registry.byId(node.id))
      .filter((checkbox) => checkbox);
  }

  window.jfcIsBatchTargetChecked = function() {
    return batchTargetCheckboxes.some((checkbox) => checkbox.get("checked"));
  }

  const setBatchButtonDisabled = function(checked) {
    const disabled = checked ? false : !window.jfcIsBatchTargetChecked();
    const title = disabled ? res.INFO_MSG_SELECT_BATCH_TARGET : "";
    batchButtons.forEach((button) => {
      button.set("disabled", disabled);
      button.set("title", title);
    });
  }

  const setBatchTargetCheckClickEvent = function() {
    batchTargetCheckboxes.forEach((checkbox) => setCheckboxClickEvent(checkbox));

    Array.from(document.querySelectorAll("input[type='checkbox'][name='toggle_allcheck']"))
      .map((node) => registry.byId(node.id))
      .filter((checkbox) => checkbox)
      .forEach((checkbox) => setCheckboxClickEvent(checkbox));
  }

  const setCheckboxClickEvent = function(checkbox) {
    checkbox.on("click", (e) => {
      e.stopPropagation();
      setBatchButtonDisabled(checkbox.get("checked"));
    });
  }

  const setBatchTargetCheckColumnClickEvent = function() {
    Array.from(document.querySelectorAll("form[id^='showList'][id$='_lp'] table.display_table > tbody > tr > td.display_field_checkbox"))
      .forEach((td, row) => {
        setTdClickEvent(td, row);
      });
  }

  const setTdClickEvent = function(td, row) {
    on(td, "click", (e) => {
      const checkbox = batchTargetCheckboxes[row];
      checkbox.set("value", !checkbox.get("checked"));
      checkbox.onClick(e);
    });
  }

  const batchButtons = getBatchButtons();
  if (batchButtons.length === 0) {
    return;
  }
  const batchTargetCheckboxes = getBatchTargetCheckboxes();
  if (batchTargetCheckboxes.length === 0) {
    return;
  }
  setBatchTargetCheckClickEvent();
  setBatchTargetCheckColumnClickEvent();
  setBatchButtonDisabled();
});
}

function setJgroupnodeOrgChartButtonClickEventFunc(btnId, labelid, form) {
  require(["dijit/ConfirmDialog", "dijit/registry", "dojo/dom-construct", "dojo/dom-style", "dojo/query"],
  function(ConfirmDialog, registry, domConstruct, domStyle, query) {
    var btn = registry.byId(btnId);
    if (!btn) {
      return;
    }
    btn.on("click", function() {
      groupHierarchyDialog.show();
    });

    var checkboxId = labelid.split("${fn:escapeXml(c.id)}");
    var orgChart;

    var groupHierarchyDialog = new ConfirmDialog({
      "content": "<div id=\"jfcGroupnodeOrgChartContainer\"></div>",
      "title": res.LABEL_JFCGROUPNODE_GROUP_HIERARCHY_TAB,
    });
    groupHierarchyDialog.on("Show", function() {
      createOrgChart();
      setCheckedGroupInOrgChart();
    });
    groupHierarchyDialog.okButton.on("click", function() {
      setSelectedGroupid();
    });

    function createOrgChart() {
      if (datasource == null) {
        return;
      }
      domConstruct.empty("jfcGroupnodeOrgChartContainer");
      orgChart = $("#jfcGroupnodeOrgChartContainer").orgchart({
        'data': datasource,
        'hideRootNode': true,
        'nodeSelectToggle': true,
        'parentNodeSymbol': null,
      });
      $('.leftEdge').removeClass('leftEdge');
      $('.rightEdge').removeClass('rightEdge');
      // root ノードと下線を非表示にする
      query("#jfcGroupnodeOrgChartContainer > div.orgchart > table > tr:first-child,#jfcGroupnodeOrgChartContainer > div.orgchart > table > tr:nth-child(2),#jfcGroupnodeOrgChartContainer > div.orgchart > table > tr:nth-child(3)").forEach(function(rootNode) {
        domStyle.set(rootNode, "display", "none");
      });
    }

    function setCheckedGroupInOrgChart() {
      query("input[name^='" + checkboxId[0] + "'][name$='" + checkboxId[1] + "']").forEach(function(node) {
        $("#" + node.value).addClass('focused');
      });
    }

    function setSelectedGroupid() {
      var selectedIds = getSelectedIds();
      query("input[name^='" + checkboxId[0] + "'][name$='" + checkboxId[1] + "']").forEach(function(node) {
        var widget = registry.byId(node.id);
        if (widget) {
          if (selectedIds[node.value]) {
            delete selectedIds[node.value];
            if (!widget.get("checked")) {
              widget.set("checked", true);
            }
          } else {
            widget.set("checked", false);
          }
        }
      });
      for (var id in selectedIds) {
        domConstruct.create("input", {
          type:"hidden",
          name: checkboxId[0] + id + checkboxId[1],
          value: id,
        }, "jfc_hidden_item");
      }
      doSubmitForm(form, null, true);
    }

    function getSelectedIds() {
      var selectedIds = {};
      var selectedNodes = orgChart.$chart.find('.node.focused');
      if (!selectedNodes || selectedNodes.length === 0) {
        return selectedIds;
      }
      for (var i=0,l=selectedNodes.length; i<l; i++) {
        var node = selectedNodes[i];
        selectedIds[node.id] = true;
      }
      return selectedIds;
    }

  });
}

function interpretContentByLocale(resource, JSON) {
  if (!resource) {
    return "";
  }
  if (!(resource.lastIndexOf("{", 0) === 0 && resource.lastIndexOf("}") === resource.length - 1)) {
    return resource;
  }
  var content = JSON.parse(resource);
  var locale = browser_locale;
  if (locale && locale.length > 2) {
    locale = locale.substring(0, 2);
  }
  return content[locale] || "";
}

function setSeparatePhonenumberEventToWidgets(id, libphonenumber, registry) {
  if (!id || id === "") {
    return;
  }
  var splitString;
  if (id.indexOf("${__pos.count}") > 0) {
    splitString = "${__pos.count}";
  } else if (id.indexOf("${__position.count}") > 0) {
    splitString = "${__position.count}";
  }
  if (!splitString) {
    setSeparatePhonenumberEventToWidget(id, libphonenumber, registry);
  } else {
    var multipleItemId = id.split(splitString);
    document.querySelectorAll(`input[id^='${multipleItemId[0]}'][id$='${multipleItemId[1]}']`)
      .forEach((node) => {
        setSeparatePhonenumberEventToWidget(node.id, libphonenumber, registry);
      });
  }
}

function setSeparatePhonenumberEventToWidget(id, libphonenumber, registry) {
  var widget = registry.byId(id);
  if (!widget) {
    return;
  }
  var PNF = libphonenumber.PhoneNumberFormat;
  var phonenumberUtil = libphonenumber.PhoneNumberUtil.getInstance();
  widget.on("blur", function() {
    var value = this.get("value");
    if (!value || value === "") {
      return;
    }
    var number = phonenumberUtil.parseAndKeepRawInput(value, 'JP');
    this.set("value", phonenumberUtil.format(number, PNF.NATIONAL));
  });
}

function setAutofillFurigana(argsArr) {
  require(["dijit/registry", "dojo/query", "./system/autokana.js"], function(registry, query, AutoKana) {
    argsArr.forEach(function(args) {
      var suffixId = "_005d_002f";
      if (args.prefixId) {
        var queryString = "input[id^='" + args.prefixId + "'][id$='" + suffixId + args.srcId + "']";
        query(queryString).forEach(function(node, i) {
          setAutofillFuriganaToWidgets(node.id, args.prefixId + (i + 1) + suffixId + args.dstId, args.isKatakana, registry, AutoKana);
        });
      } else {
        setAutofillFuriganaToWidgets(args.srcId, args.dstId, args.isKatakana, registry, AutoKana);
      }
    });
    focusFirstElement();
  });
}

function setAutofillFuriganaToWidgets(srcId, dstId, isKatakana, registry, AutoKana) {
  var srcWidget = registry.byId(srcId);
  var dstWidget = registry.byId(dstId);
  if (srcWidget && dstWidget) {
    AutoKana.bind(srcId, dstId, { katakana: isKatakana });
  }
}

function createGetRelationValuesFunc(formId, url) {
  require(["dijit/registry", "dojo/dom-construct", "dojo/dom-style", "dojo/query", "dojo/request", "dojo/topic"], function(registry, domConstruct, domStyle, query, request, topic) {
    var form = registry.byId(formId);
    if (!form) {
      window.getRelationValues = function(){}
      return;
    }

    var setStatusMessage = function(key, value) {
      if (!value.messages) {
        return;
      }
      domConstruct.empty(key);
      for (var i=0,l=value.messages.length; i<l; i++) {
        domConstruct.create("div", { textContent: value.messages[i] }, key);
      }
    }

    var getErrorIdPrefix = function(key) {
      if (!key) {
        return;
      }
      var errorIdPrefix = key.split("jfcstatus");
      if (!errorIdPrefix || errorIdPrefix.length !== 2) {
        return;
      }
      return errorIdPrefix[0];
    }

    var setErrorMessage = function(key, value) {
      var errorIdPrefix = getErrorIdPrefix(key);
      if (!errorIdPrefix) {
        return;
      }
      // エラーメッセージを設定
      var errorId = errorIdPrefix + "jfcerror";
      domStyle.set(errorId, "display", "");
      domConstruct.empty(errorId);
      if (!value.error) {
        return;
      }
      setRelationValue(errorId, value.error.label);
      // エラーにマウスオーバー時のツールチップメッセージを設定
      var errorTooltipId = errorIdPrefix + "jfcerrorTooltip";
      setStatusMessage(errorTooltipId, value.error);
    }

    var setStatusInfo = function(key, value) {
      setStatusMessage(key, value);
      setErrorMessage(key, value);
    }

    var setRadioButtonChecked = function(widget, value) {
      query("input[name='" + widget.name + "']", widget.focusNode.form).forEach(function(node) {
        if (node.value == value) {
          var radioWidget = registry.byId(node.id);
          if (radioWidget) {
            radioWidget.set("checked", true);
          }
        }
      });
    }

    var setRelationValue = function(key, value, rawvalue, content) {
      var target = registry.byId(key);
      if (target) {
        if (target.declaredClass === "dijit.form.RadioButton") {
          setRadioButtonChecked(target, value);
        } else if (rawvalue && target.declaredClass === "wagby.NumberTextBox") {
          num = Number(rawvalue);
          if (num !== NaN) {
            if (value !== target.value) {
              target.set("value", num);
            }
          } else {
            console.log("Illegal number value "+ rawvalue + " key " + key)
          }
        } else if (rawvalue && target.declaredClass === "wagby.DateTextBox") {
          // rawvalue is yyyy-MM-dd
          num = Date.parse(rawvalue + " 00:00:00")
          if (num !== NaN) {
            value = new Date();
            value.setTime(num);
            if (target.value === null || value.getTime() !== target.value.getTime()) {
              target.set("value", value);
            }
          } else {
            console.log("Illegal date value "+ rawvalue + " key " + key)
          }
        } else if (rawvalue && target.declaredClass === "wagby.TimeTextBox") {
          // rawvalue is HH-mm-ss
          num = Date.parse("1970-01-01 "+rawvalue)
          if (num !== NaN) {
            value = new Date();
            value.setTime(num);
            if (target.value === null || value.getTime() !== target.value.getTime()) {
              target.set("value", value);
            }
          } else {
            console.log("Illegal time value "+ rawvalue + " key " + key)
          }
        } else if (target.declaredClass === "wagby.Select") {
          var s = '' + value;
          target.set("value", s); 
        } else {
          target.set("value", value);
          target = document.getElementById(`content_${key}`);
          if (target) {
            target.textContent = content;
          }
        }
      } else {
        target = document.getElementById(key);
        if (target) {
          if (target.type === "hidden") {
            target.value = rawvalue !== undefined ? rawvalue : value;
          } else {
            target.textContent = value;
          }
        }
        target = document.getElementById(`content_${key}`);
        if (target) {
          target.textContent = content;
        }
      }
    }

    var setRelationValues = function(data) {
      for (var key in data) {
        if (key.lastIndexOf("jfcerror") !== -1
          || key.match(/\/@rawvalue$/)
          || key.match(/\/@content$/)) {
          continue;
        }
        var value = data[key];
        if (key.lastIndexOf("jfcstatus") !== -1) {
          setStatusInfo(key, value);
          continue;
        }
        var rawvalue = data[key+"/@rawvalue"];
        if (rawvalue === undefined || rawvalue === null) {
          rawvalue = value
        }
        var content = data[key+"/@content"];
        if (content === undefined || content === null) {
          content = value
        }
        setRelationValue(key, value, rawvalue, content);
      }
    }

    var isIgnoreInput = function(elem) {
      if ((typeof elem.name) == 'undefined' ||
          elem.name == '' || elem.name == 'SENDACTION' || elem.name.indexOf('action_') == 0 ||
          elem.type == 'button' || elem.type == 'file' ||
          elem.type == 'image' || elem.type == 'reset' ||
          elem.type == 'submit') {
        return true;
      }
      if ((elem.type == 'radio' || elem.type == 'checkbox') && !elem.checked) {
        return true;
      }
      return false;
    }

    var getValues = function(form) {
      var values = {};
      for (i = 0,l=form.elements.length; i<l; i++) {
        var elem = form.elements[i];
        if (isIgnoreInput(elem)) {
          continue;
        }
        values[elem.name] = elem.value;
      }
      return values;
    }

    window.relationValuesRequest = null;
    window.getRelationValues = function(callback) {
      if (window.relationValuesRequest) {
        window.relationValuesRequest.cancel();
      }
      topic.publish("getRelationValues", "start");
      buttonOff();
      var values = getValues(form.domNode);
      window.relationValuesRequest = request(url, {
        data: values,
        method: "POST",
        handleAs: "json",
      }).then(function(data) {
        buttonOn();
        setRelationValues(data);
        topic.publish("getRelationValues", "done");
        window.relationValuesRequest = null;
        if (callback && callback.onsuccess) {
          callback.onsuccess(data);
        } else {
          window.getRelationValuesResponseData(data);
        }
      }, function(err) {
        buttonOn();
        topic.publish("getRelationValues", "done");
        window.relationValuesRequest = null;
        if (err.dojoType === "cancel") {
          return;
        }
        if (callback && callback.onerror) {
          callback.onerror(data);
        } else {
          showAlertDialog(res.ERROR_MSG_GET_RELATION_ERROR);
        }
      });
    }
    topic.publish("createGetRelationValuesFunc", "done");
  });
}

function getRelationValuesResponseData(data) {
  // relation REST API の戻り値をセットする関数内で呼び出される
}

function clearTabContainerSelectedTabCookie() {
  var cookies = document.cookie.split('; ');
  for (var i=0,l=cookies.length; i<l; i++) {
    var selectedTabCookie = cookies[i];
    if (selectedTabCookie.lastIndexOf("__jfc_cookie_TabContainer_selectedTab_") !== 0) {
      continue;
    }
    var selectedTabCookieKey = selectedTabCookie.split("=")[0];
    document.cookie = escape(selectedTabCookieKey) + "=; max-age=0";
  }
}

function setTableRowHoverEvent() {
  require(["dojo/dom-attr", "dojo/dom-class", "dojo/query", "dojo/on"], function(domAttr, domClass, query, on) {
    var getHoverEventFunc = function(rowNum) {
      return function() {
        query("table.display_table > tbody > tr[data-rownum=" + rowNum + "]").forEach(function(row) {
          domClass.toggle(row, "clickableRows");
        });
      }
    }

    query("table.display_table > tbody > tr.clickable").forEach(function(tr) {
      var rowNum = domAttr.get(tr, "data-rownum");
      if (rowNum) {
        var hoverEventFunc = getHoverEventFunc(rowNum);
        on(tr, "mouseover", hoverEventFunc);
        on(tr, "mouseout", hoverEventFunc);
      }
    });
  });
}

function isCssLayout() {
  return document.body.getAttribute("data-jfc-csslayout");
}

function getCheckboxImage(isChoose) {
  if (isCssLayout()) {
    return getCheckboxIcon(isChoose);
  } else {
    return getCheckboxGifImage(isChoose);
  }
}

function getCheckboxIcon(isChoose) {
  var img = document.createElement("i");
  img.setAttribute("class", isChoose ? "far fa-check-square fa-lg" : "far fa-square fa-lg");
  return img;
}

function getCheckboxGifImage(isChoose) {
  var img = document.createElement("img");
  img.setAttribute("style", "vertical-align:middle;padding-right:2px;");
  img.setAttribute("src", isChoose ? "img/check_Y.gif" : "img/check_N.gif");
  return img;
}

function setWidgetPatternAttr(checks) {
  if (!checks) {
    return;
  }
  require(["dijit/registry", "dojo/query"], function(registry, query) {
    for (var id in checks) {
      var widgets = getWidgetsById(id, registry, query);
      widgets.forEach(function(widget) {
        widget.set("pattern", checks[id]);
      });
    }
  });
}

function submitOnChange(widget) {
  if (!widget) {
    return;
  }
  var form = widget.focusNode.form || widget.valueNode.form;
  if (!form) {
    return;
  }
  const widgetDisableCtrlSrc = isWidgetDisableCtrlSrc(widget);
  if (widgetDisableCtrlSrc) {
    require(["dojo/topic"], (topic) => {
      const topicHandle = topic.subscribe("CtrlDisableManager", (message) => {
        if (message === "done") {
          topicHandle.remove();
          form.submit();
        }
      });
    });
  }
  buttonOff();
  getAllInputWidgets().forEach((widget) => widget.set("readOnly", true));
  if (form.id && form.id.lastIndexOf("condition", 0) === 0) {
    form.SENDACTION.name = 'action_Refresh';
  }
  if (!widgetDisableCtrlSrc) {
    form.submit();
  }
}

function isWidgetDisableCtrlSrc(widget) {
  if (!window.createCtrlDisableManager) {
    return false;
  }
  for (let i=0,l=CtrlDisableManagerList.length; i<l; i++) {
    let cdm = CtrlDisableManagerList[i];
    if (cdm.srcCtrls.some((srcCtrl) => srcCtrl.id === widget.id || srcCtrl.name === widget.id)) {
      return true;
    }
  }
  return false;
}

function openSubWindow(url, windowName, windowSize) {
  var width = 500;
  var height = 500;
  if (windowSize) {
    if (windowSize["height"] && !isNaN(windowSize["height"])) {
      height = windowSize["height"];
    }
    if (windowSize["width"] && !isNaN(windowSize["width"])) {
      width = windowSize["width"];
    }
  }
  var style ="width=" + width + ", height=" + height + ", directories=no, location=no, menubar=no, scrollbars=yes, status=no, toolbar=no, resizable=yes";
  var subwindow = window.open(url, windowName, style);
  subwindow.focus();
}

function setSubWindowHierarchicalView(href) {
  let url = new URL(href);
  let params = url.searchParams;
  if (!params.get('jfcHierarchicalView')) {
    return false;
  }
  require(["dojo/dom-construct", "dojo/dom-style"], function(domConstruct, domStyle) {
    domConstruct.create("div", { id: 'jfcTreeWidget' }, "bodyarea", "before");
    domStyle.set("bodyarea", "display", "none");
  });
  return true;
}

function showTreeWidget(modelId, placeAt, referenceItem, callback) {
  require(["dijit/Tree", "dijit/registry", "dojo/cookie", "dojo/dom", "dojo/request", "dojo/store/Memory", "dijit/tree/ObjectStoreModel"],
  function(Tree, registry, cookie, dom, request, Memory, ObjectStoreModel) {
    request("rest/" + modelId + "/list", {
      headers: {
        'Content-Type': "application/json; charset=utf-8",
      },
      handleAs: "json",
    }).then(function(data) {
      showTree(data);
    }, function(err) {
      console.error("err: ", err);
    });

    function showTree(data) {
      var store = createStore(data);
      if (!store) {
        return;
      }
      var tree = new Tree({
        id: "jfc" + modelId + "Tree",
        model: createModel(store),
        persist: true,
        showRoot: false,
        onClick: function(item) {
          if (!item.id) {
            return;
          }
          if (callback) {
            setIdElement();
            callback(item.id, item.name);
            if (!isOpenerShowListScreen()) {
              self.close();
            }
          }
        },
        getIconClass: function(item, opened){
          return opened ? "dijitFolderOpened" : "dijitFolderClosed";
        },
      });
      if (!tree) {
        return;
      }
      tree.placeAt(placeAt);
      tree.startup();
    }

    function setIdElement() {
      let url = new URL(window.location.href);
      let params = url.searchParams;
      let id = params.get('id');
      if (!id) {
        return;
      }
      window.opener.idElement = id;
    }

    function isOpenerShowListScreen() {
      let openerPathname = window.opener.location.pathname;
      if (!openerPathname) {
        return false;
      }
      let pathnames = openerPathname.split("/");
      if (!pathnames || pathnames.length !== 3) {
        return false;
      }
      if (pathnames[2].lastIndexOf("showList", 0) === 0) {
        return true;
      }
      return false;
    }

    function createStore(data) {
      var items = [{
        id: 'all',
        name: 'all',
        type: 'folder',
        parent: null,
      }];
      for (var i=0,l=data.entity.length; i<l; i++) {
        var item = data.entity[i];
        items.push({
          id: getPkeyData(referenceItem, item),
          name: item[referenceItem.content],
          type: 'folder',
          parent: item[referenceItem.parent] || 'all',
        });
      }
      return new Memory({
        data: items,
        getChildren: function(object) {
          return this.query({parent: object.id});
        },
      });
    }

    function getPkeyData(referenceItem, item) {
      var pkeyData = [];
      for (var i=0,l=referenceItem.pkeys.length; i<l; i++) {
        var pkey = referenceItem.pkeys[i];
        pkeyData.push(item[pkey]);
      }
      return pkeyData.join("$SEP$");
    }

    function createModel(store) {
      return new ObjectStoreModel({
        store: store,
        query: { id: 'all' },
        mayHaveChildren: function(item) {
          if (item.type === "") {
            return false;
          }
          return true;
        }
      });
    }
  });
}

function setCalendarViewAllDayItemEvent(startDateTimeItemId, endDateTimeItemId, allDayItemId) {
require(["dijit/registry"], function(registry) {
  let allDayWidget = registry.byId(allDayItemId);
  let startDateTimeWidget = registry.byId(startDateTimeItemId);
  let endDateTimeWidget = registry.byId(endDateTimeItemId);
  if (!(allDayWidget && startDateTimeWidget && endDateTimeWidget)) {
    return;
  }
  function getEndDate(startDate) {
    startDate.setHours(0);
    startDate.setMinutes(0);
    startDate.setSeconds(0);
    let endDate = new Date(startDate);
    endDate.setDate(endDate.getDate() + 1);
    return endDate;
  }

  function setEndDateTime(startDateTimeWidget, endDateTimeWidget) {
    let startDate = startDateTimeWidget.dateTextBox.get("value");
    if (!startDate) {
      return;
    }
    startDateTimeWidget.timeTextBox.set("value", "T00:00:00");
    endDateTimeWidget.set("value", formatDateObject(getEndDate(startDate), "yyyy-MM-dd HH:mm:ss"));
  }

  function setDateTimeWidgetReadOnly(startDate, endDate, checked) {
    startDate.timeTextBox.set("readOnly", checked);
    endDate.set("readOnly", checked);
  }

  startDateTimeWidget.dateTextBox.on("change", function(value) {
    if (!allDayWidget.get("checked")) {
      return;
    }
    setEndDateTime(startDateTimeWidget, endDateTimeWidget);
  });
  allDayWidget.on("change", function(checked) {
    if (checked) {
      setEndDateTime(startDateTimeWidget, endDateTimeWidget);
    }
    setDateTimeWidgetReadOnly(startDateTimeWidget, endDateTimeWidget, checked);
  });
  setDateTimeWidgetReadOnly(startDateTimeWidget, endDateTimeWidget, allDayWidget.get("checked"));
});
}

function getNodeId(id, registry, query) {
  var loopVariables = ["${iterStat.count}", "${__position.count}"];
  var loopVariable = loopVariables.find(element => id.indexOf(element) > 0);
  var nodeIdArr = [];
  if (loopVariable) {
    var widgetIdArr = id.split(loopVariable);
    var queryStr = "input[id^='" + widgetIdArr[0] + "'][id$='" + widgetIdArr[1] + "']";
    query(queryStr).forEach(function(node) {
      nodeIdArr.push(node.id);
    });
  } else {
    nodeIdArr.push(id);
  }
  return nodeIdArr;
}

function getWidgetsById(id, registry, query) {
  var nodeIdArr = getNodeId(id, registry, query);
  var widgets = [];
  nodeIdArr.forEach(function(nodeId) {
    var widget = registry.byId(nodeId);
    if (widget) {
      widgets.push(widget);
    }
  });
  return widgets;
}

function setDirectcopyEventToWidget(settings) {
require(["dijit/registry", "dojo/query"], function(registry, query) {
  var getWidgets = function(id) {
    var nodeIdArr = getNodeId(id, registry, query);
    var widgets = [];
    nodeIdArr.forEach(function(nodeId) {
      var widget = registry.byId(nodeId);
      if (widget) {
        widgets.push(widget);
      }
    });
    return widgets;
  }

  var getTargetSettings = function(targets) {
    var targetSettings = [];
    targets.forEach(function(target) {
      var targetWidgets = getWidgetsById(target.id, registry, query);
      targetWidgets.forEach(function(targetWidget) {
        targetSettings.push({
          id: target.id,
          targetWidget: targetWidget,
          type: target.type,
          forceCopy: target.forceCopy,
        });
      });
    });
    return targetSettings;
  }

  var canCopyValue = function(target, srcIndex, targetIndex) {
    // 繰り返しコンテナ項目は同一行の項目の値のみコピー対象とする
    if (target.id.indexOf("${") > 0
        && srcIndex !== targetIndex) {
      return false;
    }
    if (target.forceCopy) {
      return true;
    }
    var value = target.targetWidget.get("value");
    if (target.targetWidget.declaredClass === "wagby.NumberTextBox") {
      return value !== value;
    }
    return target.targetWidget.get("value") === "";
  }

  var setValueToTargets = function(value, targets, srcIndex) {
    targets.forEach(function(target, targetIndex) {
      if (canCopyValue(target, srcIndex, targetIndex)) {
        target.targetWidget.set("value", value);
      }
    });
  }

  var setWidgetOnChangeEvent = function(srcWidget, targets, index) {
    if (srcWidget.declaredClass === "wagby.DateTimeTextBox") {
      srcWidget.dateTextBox.on("change", function(value) {
        if (!srcWidget.timeTextBox.get("value")) {
          return;
        }
        setValueToTargets(srcWidget.get("value"), targets, index);
      });
      srcWidget.timeTextBox.on("change", function(value) {
        setValueToTargets(srcWidget.get("value"), targets, index);
      });
    } else {
      srcWidget.on("change", function(value) {
        setValueToTargets(value, targets, index);
      });
    }
  }

  settings.forEach(function(setting) {
    var srcWidgets = getWidgetsById(setting.src, registry, query);
    if (srcWidgets && srcWidgets.length > 0) {
      var targets = getTargetSettings(setting.targets);
      srcWidgets.forEach(function(srcWidget, index) {
        if (srcWidget) {
          setWidgetOnChangeEvent(srcWidget, targets, index);
        }
      });
    }
  });
});
}

function getScreenId() {
  var element = document.querySelector("div.pagetitle > div");
  if (!element) {
    return "";
  }
  return element.id;
}

function isEditScreen() {
  var screenId = getScreenId();
  if (screenId.lastIndexOf("insert", 0) === 0 ||
      screenId.lastIndexOf("update", 0) === 0 ||
      screenId.lastIndexOf("copy", 0) === 0 ||
      screenId.lastIndexOf("updateList", 0) === 0) {
    return true;
  }
  return false;
}

function getFormValues(form) {
  var isIgnoreInput = function(elem) {
    if ((typeof elem.name) === 'undefined' ||
        elem.name === '' || elem.name === 'SENDACTION' || elem.name.indexOf('action_') === 0 ||
        elem.type === 'button' || elem.type === 'file' ||
        elem.type === 'image' || elem.type === 'reset' ||
        elem.type === 'submit') {
      return true;
    }
    if ((elem.type === 'radio' || elem.type === 'checkbox') && !elem.checked) {
      return true;
    }
    return false;
  }

  var values = {};
  for (i = 0,l=form.elements.length; i<l; i++) {
    var elem = form.elements[i];
    if (isIgnoreInput(elem)) {
      continue;
    }
    values[elem.name] = elem.value;
  }
  return values;
}

function setRokuyo() {
  document.querySelectorAll("table:has(caption.schedule) > tbody > tr > td > span.jfcRokuyo")
    .forEach((rokuyoNode) => {
      let dateArray = rokuyoNode.dataset.date ?
        rokuyoNode.dataset.date.split("-").map((s) => parseInt(s, 10)) : null;
      if (dateArray) {
        rokuyoNode.textContent = getRokuyo(...dateArray);
      }
    });
}

function getUserAgent() {
  return window.navigator.userAgent.toLowerCase();
}

function isEdge() {
  const ua = getUserAgent();
  return ua.includes("edg");
}

/**
 * 一覧更新テーブルの初期化処理
 */
function initUpdateListTables(args) {
  args.modelIds.forEach((id) => {
    initUpdateListTable(id, args.isOutsidekeyModel);
  });
  // 一覧更新の追加行数を入力するダイアログを表示する関数を生成する
  createShowAddRowNumInputDialogFunc();
}

/**
 * 一覧更新テーブルの初期化処理
 */
function initUpdateListTable(modelId, isOutsidekeyModel) {
  // 対象の一覧更新テーブルを取得する
  const updateListTableBodies = getUpdateListTableBody(modelId, isOutsidekeyModel);
  if (!updateListTableBodies || updateListTableBodies.length === 0) {
    return;
  }
  // 多段レイアウトかどうか
  const isMultiRowTable =
    updateListTableBodies.some((updateListTableBody) => updateListTableBody.children[0].dataset.rownum !== undefined);

  // 削除チェックボックスがチェックされている行を非表示にする
  hideDeletedRows(updateListTableBodies);
  // 削除ボタン押下時の処理を設定する
  setBtnDeleteClickEvent(updateListTableBodies);

  // 削除チェックボックスにチェックがついている行(エラー行を除く)を非表示にする
  function hideDeletedRows(tbodies) {
    require(["dijit/registry"], (registry) => {
      Array.from(tbodies[0].querySelectorAll("tr:not(:has(> td:nth-child(1) > div[id$='_005d_002f_0040jfcerrorTooltip'] > div)) > td.display_field_buttons > div > div > input[type='checkbox']:checked"))
        .map((node) => {
          return node.id.split(":")[1];
        }).forEach((index) => {
          hideDeletedRow(tbodies, index, registry);
        });
      // エラー行で削除チェックボックスにチェックが付いている場合、チェックを外す
      tbodies[0].querySelectorAll("tr:has(> td:nth-child(1) > div[id$='_005d_002f_0040jfcerrorTooltip'] > div) > td.display_field_buttons > div > div > input[type='checkbox']:checked")
        .forEach((input) => {
          input.removeAttribute("checked");
        });
    });
  }

  // 引数の tbody 内の index 行を非表示にする
  function hideDeletedRow(tbodies, index, registry) {
    let isHideRow = false;
    let rowSelectQuery;
    if (isMultiRowTable) {
      // 多段レイアウトの場合、data 属性の rownum の行番号で削除対象行を取得する
      rowSelectQuery = `tr[data-rownum='${parseInt(index, 10) + 1}']`;
    } else {
      // 行インデックス値を id 属性の後方一致で削除対象行を取得する
      rowSelectQuery = `tr[id$='_detail_row_${index}']`;
    }
    tbodies.forEach((tbody) => {
      tbody.querySelectorAll(rowSelectQuery)
        .forEach((node) => {
          node.style = "display: none;";
          isHideRow = true;
          setWidgetValidationDisable(node, registry);
        });
    });
    if (!isHideRow) {
      return;
    }
    // 明細行テーブル右側余白をスクロールバーの有無に応じて調整する
    if (window.fixTableHeaderRowColumnFuncs && window.fixTableHeaderRowColumnFuncs[modelId]) {
      (window.fixTableHeaderRowColumnFuncs[modelId]).setScrollbarPaddingFunc();
    }
    // 削除対象行を非表示にした後にカスタマイズ関数を実行する
    if (window.afterHideDeletedRow) {
      window.afterHideDeletedRow();
    }
  }

  // 非表示にした行内の TextBox に入力チェックエラーがあると保存できなくなるため、
  // 行を非表示にする際に行内の TextBox の required 属性を false、入力チェック関
  // 数を無効にする
  function setWidgetValidationDisable(node, registry) {
    Array.from(node.querySelectorAll("input[type='text']:not([readonly='readonly'])"))
      .map((node) => registry.byId(node.id))
      .filter((widget) => widget)
      .forEach((widget) => {
        widget.set("required", false);
        widget.isValid = () => { return true; }
      });
  }

  // 削除ボタン押下時のコールバック関数を設定する
  function setBtnDeleteClickEvent(tbodies) {
    require(["dijit/registry", "dojo/ready"], function(registry, ready) {
      ready(function() {
        tbodies[0].querySelectorAll(`tr > td.display_field_buttons > span > input[type='button'][name^='btnULDelete']`)
          .forEach((node) => {
            const btnDelete = registry.byId(node.name);
            btnDelete.on("click", getBtnDeleteClickFunc(btnDelete, tbodies, registry));
          });
      });
    });
  }

  // 削除ボタン押下時のコールバック関数を返す
  function getBtnDeleteClickFunc(btnDelete, tbodies, registry) {
    const index = btnDelete.id.split(":")[1];
    const deleteCheckbox = getDeleteCheckbox(btnDelete, registry);
    return () => {
      // 削除ボタンを押下した行の削除チェックボックスにチェックを付ける
      if (deleteCheckbox) {
        deleteCheckbox.set("checked", true);
      }
      // 削除ボタンを押下した行を非表示にする
      hideDeletedRow(tbodies, index, registry);
    }
  }

  // 指定行内の削除チェックボックスを返す
  function getDeleteCheckbox(btnDelete, registry) {
    const deleteCheckboxNode =
      btnDelete.domNode.parentNode.querySelector("div > div > input[type='checkbox']");
    if (!deleteCheckboxNode) {
      return null;
    }
    return registry.byId(deleteCheckboxNode.id);
  }

  // 一覧更新のテーブルを取得する
  function getUpdateListTableBody(modelId, isOutsidekeyModel) {
    if (isOutsidekeyModel) {
      // 外部キー子モデルの一覧更新テーブルを取得
      return Array.from(document.querySelectorAll(`a[name='${modelId}'] ~ div table > tbody`));
    } else {
      // 一覧更新画面のテーブルを取得
      return Array.from(document.querySelectorAll("table[class^='display_table']:not(.scroll_table_header) > tbody"));
    }
  }
}

// 一覧更新の追加行数入力ダイアログを生成する関数
function createShowAddRowNumInputDialogFunc() {
  require(["dijit/TooltipDialog", "dijit/popup", "dojo/on"], (TooltipDialog, popup, on) => {
    // 押下されたボタン、アクションパラメータを保持する
    let clickedRowButton, clickedRowActionParam;
    // 追加行数入力ダイアログを保持する
    let jfcUlAddRowNumInputDialog;
    // ダイアログを閉じるイベントハンドルを保持する配列
    let closeDialogHandles = [];
    // 追加行数入力ダイアログの表示状態を保持する
    let isPopupOpen = false;

    // 追加行数送信用の隠し項目を form に生成する関数
    const createUlInsertCntHiddenItem = () => {
      const input = document.createElement("input");
      input.setAttribute("name", "jfcupdatelistinsertcnt");
      input.setAttribute("type", "hidden");
      const form = document.body.querySelector("form");
      form?.appendChild(input);
      return input;
    }

    // 追加行数入力ダイアログを生成する関数
    const createUlAddRowNumInputDialog = () => {
      // 追加行数送信用の隠し項目を生成する
      const input = createUlInsertCntHiddenItem();

      // 追加行数入力ダイアログのコンテンツ内容
      const jfcUlAddRowNumInputDialogContent = `<input data-dojo-id="jfcUlAddRowNumInput" data-dojo-type="dijit/form/NumberSpinner" data-dojo-props="value: 1, selectOnClick: true, constraints:{ min: 1, max: 50, places: 0 }" style="margin-right: 3px; width: 80px;" />
<button data-dojo-id="jfcBtnUlAddRow" data-dojo-type="wagby/Button">${res.BUTTON_ADD}</button><i id="jfcBtnCloseAddUlpRowNumDialog" class="fas fa-times-circle fa-lg" style="position: absolute; top: 0; padding: 5px 5px 4px 4px;"></i>`;

      // 追加行数入力ダイアログを初期化する
      jfcUlAddRowNumInputDialog = new TooltipDialog({
        id: "jfcUlAddRowNumInputDialog",
        content: jfcUlAddRowNumInputDialogContent,
        style: "width: 180px",
      });

      // 追加行数入力ダイアログ表示時の処理
      const dialogOnOpenFunc = () => {
        // 初期表示は追加行数を「1」とする
        jfcUlAddRowNumInput.set("value", 1);
        // 行数入力欄にフォーカスをセットする
        jfcUlAddRowNumInput.focus();
        // 行数入力欄の値変更時にサーバへ送信する隠し項目に値をセットする
        jfcUlAddRowNumInput.on("change", (value) => {
          input.value = isNaN(value) ? "" : value;
        });

        // ダイアログの追加ボタン押下時にダイアログを閉じてサブミットを行なう
        on.once(jfcBtnUlAddRow, "click", () => {
          closeDialog();
          setScrollPosition(clickedRowButton.id);
          doSubmitForm(clickedRowButton.valueNode.form, clickedRowActionParam, true);
        });

        // ×アイコンのマウスクリック時にダイアログを閉じる
        closeDialogHandles.push(on(document.getElementById("jfcBtnCloseAddUlpRowNumDialog"), "click", () => {
          closeDialog();
        }));

        // ダイアログ表示時にセットするとクリックイベントが
        // 即時実行されるため、500ms 遅らせる
        setTimeout(() => {
          // 行数入力の上下ボタンのクリックイベントでダイアログが閉じるため、
          // ダイアログ内のクリックイベントは伝播させないようにする
          on(jfcUlAddRowNumInputDialog.domNode, "click", (e) => {
            e.stopPropagation();
          });
          // ダイアログにフォーカスがある状態でESCキー押下でダイアログを閉じる
          closeDialogHandles.push(on(jfcUlAddRowNumInputDialog.domNode, "keyup", (e) => {
            if (e.keyCode === 27) {
              closeDialog();
            }
          }));
          // ブラウザウィンドウをマウスクリックした際にダイアログを閉じる
          closeDialogHandles.push(on(window.dc, "click", (e) => {
            closeDialog();
          }));
        }, 500);
      }

      // ダイアログを閉じる関数
      const closeDialog = () => {
        // 設定されたイベントハンドルを全て削除してダイアログを閉じる
        closeDialogHandles.forEach((handle) => {
          handle.remove();
        });
        closeDialogHandles = [];
        popup.close(jfcUlAddRowNumInputDialog);
        isPopupOpen = false;
      }

      // 追加行数入力ダイアログ表示時の処理
      jfcUlAddRowNumInputDialog.on("open", dialogOnOpenFunc);

      // 新規追加数が範囲外の場合、追加ボタンを押下不可とする
      jfcUlAddRowNumInputDialog.on("ValidStateChange", (isValid) => {
        jfcBtnUlAddRow.set("disabled", !isValid);
      });
    }

    // ダイアログを開く関数
    const openDialog = (button) => {
      popup.open({
        popup: jfcUlAddRowNumInputDialog,
        around: button.domNode,
      });
      isPopupOpen = true;
    }

    // 追加行数入力ダイアログを生成する
    createUlAddRowNumInputDialog();
    // 追加行数入力ダイアログを表示する関数
    // 一覧更新行の「+」ボタン押下時に実行される
    window.showJfcAddRowNumInputDialog = (button, actionParam) => {
      // 押下された「+」ボタンとサブミット時のアクションパラメータを保持する
      clickedRowButton = button;
      clickedRowActionParam = actionParam;
      // 押下された「+」ボタン付近に追加行数入力ダイアログを表示する
      if (isPopupOpen) {
        // 追加行数入力ダイアログが表示されている場合、ダイアログを閉じる
        // hide イベント発生から 100ms 後にダイアログを再表示する
        on.once(jfcUlAddRowNumInputDialog, "Hide", () => {
          setTimeout(() => {
            openDialog(button);
          }, 100);
        });
      } else {
        openDialog(button);
      }
    }
  });
}

/**
 * 任意検索項目の表示非表示を切り替える処理を設定する
 */
require(["dijit/registry", "dojo/dom-construct", "dojo/dom-style", "dojo/query", "dojo/ready"], function(registry, domConstruct, domStyle, query, ready) {
  window.setArbitaryConditionItems = function(CheckedMultiSelect, modelId, arbitaryConditionItemId) {
    // 検索項目のラベルを取得する
    const getLabelFromConditionContainer = function(container) {
      // ラベルの要素 div#label_<項目ID> 下の span タグのテキストを返す
      const labelDom = container.children[0];
      return labelDom ? labelDom.children[0].textContent.trim() : "";
    }

    const getConditionForm = function() {
      return document.getElementById(`condition${capFirst(modelId)}Cp`);
    }

    // 任意検索項目の検索項目のコンテナと項目ラベルをセットにしたオブジェクトを取得する
    const getArbitaryConditionProps = function(conditionForm) {
      // 検索条件項目のコンテナを取得する
      let arbitaryConditionProps = {};
      let options = [];
      arbitaryConditionItemId.forEach((itemId) => {
        const conditionContainer = query(`div.${modelId}_c_${itemId}`, conditionForm)[0];
        if (conditionContainer) {
          options.push({
            "label": getLabelFromConditionContainer(conditionContainer),
            "value": itemId,
          });
          arbitaryConditionProps[itemId] = {
            "container": conditionContainer,
          };
        }
      });
      arbitaryConditionProps.jfcMultiSelectOptions = options;
      return arbitaryConditionProps;
    }

    // 表示対象とした任意検索項目の id を返す関数を生成する
    const getSelectedArbitraryConditionItemFunc = function(selectedArbitraryConditionItemWidget) {
      return function() {
        return selectedArbitraryConditionItemWidget.get("value").split(",");
      }
    }

    // 表示対象とした任意検索項目の id をカンマ区切りで保存する関数を生成する
    const getSetSelectedArbitraryConditionItemFunc = function(selectedArbitraryConditionItemWidget) {
      return function(selectedArbitraryConditionItemIdArray) {
        selectedArbitraryConditionItemWidget.set("value", selectedArbitraryConditionItemIdArray.join(","));
      }
    }

    // 表示対象とした任意検索項目の id を保持する隠し項目の input 要素を取得する
    const getSelectedArbitraryConditionItemWidget = function() {
      // 任意検索項目を利用するモデルに項目ID wbSelectedArbitrarySearchItem で
      // 隠し項目が定義されている
      const selectedArbitraryConditionItemId = `${modelId}_cp_002fwbSelectedArbitraryConditionItemId`;
      const selectedArbitraryConditionItemWidget = registry.byId(selectedArbitraryConditionItemId);
      if (!selectedArbitraryConditionItemWidget) {
        console.error(`setArbitaryConditionItems node:[${selectedArbitraryConditionItemId}] not exists.`);
        return null;
      }
      return selectedArbitraryConditionItemWidget;
    }

    const getArbitaryConditionDisplayAttrFunc = function(selectedArbitraryConditionItemFunc, arbitaryConditionProps) {
      return function() {
        // 表示対象とした任意検索項目の id を保持する配列
        const selectedArbitraryConditionItemIdArray = selectedArbitraryConditionItemFunc();
        // 任意検索項目設定された項目 id から表示対象となっている id を除いて非表示にする
        arbitaryConditionItemId.forEach((itemId) => {
          const display = selectedArbitraryConditionItemIdArray.includes(itemId) ? "" : "none";
          const conditionProps = arbitaryConditionProps[itemId];
          if (conditionProps) {
            if (display === "none" && conditionProps.widgets) {
              // 非表示にする検索項目の検索条件をクリアする
              conditionProps.widgets.forEach((widget) => {
                widget.set("_onChangeActive", false);
                doClearWidgetValue(widget);
                widget.set("_onChangeActive", true);
              });
            }
            domStyle.set(conditionProps.container, "display", display);
          }
        });
      }
    }

    const createArbitaryConditionSettingDialog = function(conditionForm, arbitaryConditionProps, selectedArbitraryConditionItemFunc, setArbitaryConditionDisplayAttrFunc) {
      // 「検索の実行」ボタン等の表示エリアを取得する
      const buttonField = query("div.button_field:last-child")[0];
      // 検索ボタン表示エリアの最後に任意検索項目選択ダイアログ配置先となる div タグを生成する
      const arbitaryConditionMultiSelectDom = domConstruct.create("div", {
        "id": "jfc" + capFirst(modelId) + "ArbitaryConditionMultiSelect",
      }, buttonField);

      // 表示対象とした任意検索項目の id を保持する関数
      const selectedArbitraryConditionItemWidget = getSelectedArbitraryConditionItemWidget();
      const setSelectedArbitraryConditionItemFunc = getSetSelectedArbitraryConditionItemFunc(selectedArbitraryConditionItemWidget);
      // 任意検索項目選択ダイアログの生成
      const arbitaryConditionMultiSelect = new CheckedMultiSelect({
        "labelText": "任意検索項目を選択",
        "options": arbitaryConditionProps.jfcMultiSelectOptions,
        "style": "margin-left: 15px",
      }, arbitaryConditionMultiSelectDom);

      // 任意検索項目の変更フラグ
      var arbitaryConditionChanged = false;

      // 任意検索項目選択ダイアログが表示された際に変更フラグを初期化する
      arbitaryConditionMultiSelect.dropDownMenu.on("Open", function() {
        arbitaryConditionChanged = false;
      });

      // 任意検索項目が変更された際に選択された項目IDをカンマ区切りで
      // 隠し項目に保存し、変更フラグをセットする
      arbitaryConditionMultiSelect.on("change", function(value) {
        setSelectedArbitraryConditionItemFunc(value);
        arbitaryConditionChanged = true;
      });

      // 任意検索項目選択ダイアログが閉じる際に検索項目に変更があれば
      // 任意検索項目の表示・非表示を切り替える
      arbitaryConditionMultiSelect.dropDownMenu.on("Close", function() {
        if (!arbitaryConditionChanged) {
          // 任意検索項目が変更されていないため何もしない
          return;
        }
        setArbitaryConditionDisplayAttrFunc();
        arbitaryConditionChanged = false;
      });

      arbitaryConditionMultiSelect.startup();
      // 選択された任意検索項目にチェックを付ける
      arbitaryConditionMultiSelect.set("value", selectedArbitraryConditionItemFunc().join(","));
    }

    const getWidgetsFromConditionContainer = function(container) {
      // ラベルの要素 div#field_<項目ID> 下の入力欄を返す
      const fieldDom = container.children[1];
      return registry.findWidgets(fieldDom);
    }

    // 各検索項目のフィールド部にある Dojo のウィジェットを取得し、
    // widtes プロパティに保持しておく
    const setArbitraryConditionWidgets = function(arbitaryConditionProps) {
      for (const [key, prop] of Object.entries(arbitaryConditionProps)) {
        if (key !== "jfcMultiSelectOptions") {
          prop.widgets = getWidgetsFromConditionContainer(prop.container);
        }
      }
    }

    // 検索条件のフォームを取得する
    const conditionForm = getConditionForm();
    // 任意検索項目のラベルと入力欄を保持する項目コンテナの div 要素と項目ラベルを取得する
    const arbitaryConditionProps = getArbitaryConditionProps(conditionForm);

    // Dojo のウィジェット生成後に任意検索項目の入力欄を取得する
    ready(function() {
      // 選択された任意検索項目の項目 ID を保持する隠し項目を取得する
      const selectedArbitraryConditionItemWidget = getSelectedArbitraryConditionItemWidget();
      // 表示対象とした任意検索項目の id を返す関数
      const selectedArbitraryConditionItemFunc = getSelectedArbitraryConditionItemFunc(selectedArbitraryConditionItemWidget);
      // 任意検索項目の表示を切り換える関数を取得する
      const setArbitaryConditionDisplayAttrFunc = getArbitaryConditionDisplayAttrFunc(selectedArbitraryConditionItemFunc, arbitaryConditionProps);
      // 画面表示時の初期状態の任意検索項目の表示を切り換える
      setArbitaryConditionDisplayAttrFunc();
      // 任意検索項目の表示・非表示を切り替えるダイアログを生成する
      createArbitaryConditionSettingDialog(conditionForm, arbitaryConditionProps, selectedArbitraryConditionItemFunc, setArbitaryConditionDisplayAttrFunc);

      setArbitraryConditionWidgets(arbitaryConditionProps);
    });
  }
});

/**
 * 検索画面の検索結果の件数を返す関数
 */
function getJfcResultSize() {
  const resultcount = document.querySelector("div.display_resultcount");
  return Number(resultcount?.dataset.jfc_resultcount_size ?? "0");
}
