diff --git a/src/main/webapp/WEB-INF/jsp/include/tail.jsp b/src/main/webapp/WEB-INF/jsp/include/tail.jsp
index 1432a20e..829e5f3c 100644
--- a/src/main/webapp/WEB-INF/jsp/include/tail.jsp
+++ b/src/main/webapp/WEB-INF/jsp/include/tail.jsp
@@ -61,6 +61,8 @@
">
">
+
+">
diff --git a/src/main/webapp/resources/js/fims/cmmn/detect.js b/src/main/webapp/resources/js/fims/cmmn/detect.js
new file mode 100644
index 00000000..fd2e6ec4
--- /dev/null
+++ b/src/main/webapp/resources/js/fims/cmmn/detect.js
@@ -0,0 +1,272 @@
+/**************************************************************************
+* 엘리먼트 doctx탐지 및 이벤트 실행(실행 메소드이름 필수)
+**************************************************************************/
+function detectElementEvent(){
+ if(arguments.length < 1){
+ console.log('메소드 이름은 필수 입니다.');
+ return;
+ }
+ let methodName = arguments[0];
+ let sp = methodName.split(".");
+ if(sp.length > 3){
+ console.log('depth가 너무 깁니다.');
+ return;
+ }
+
+ var args = Array.prototype.slice.call(arguments);
+ args.shift();
+
+ let element = event.target;
+
+ let doctx;
+ if(element.hasAttribute("data-ref-doctx")){
+ doctx = element.getAttribute("data-ref-doctx");
+ } else {
+ doctx = element.detectDoctx();
+ element.setAttribute("data-ref-doctx", doctx);
+ }
+
+ //pageObject 전역객체가 있고, pageObject 내부에 doctx를 키로 갖는 객체가 있으면
+ if((window.pageObject !== undefined) && (pageObject[doctx] !== undefined)){
+ let curPO = pageObject[doctx];
+
+ //STEP 1 : "pageObject전역객체.doctx명"에서 찾는다.
+ if(sp.length == 1){
+ if(curPO[methodName] !== undefined && curPO[methodName] instanceof Function){
+ curPO[methodName].apply(curPO, args); //실행
+ return;
+ }
+ } else if(sp.length == 2){
+ if(curPO[sp[0]] !== undefined
+ && curPO[sp[0]][sp[1]] !== undefined
+ && curPO[sp[0]][sp[1]] instanceof Function){
+ curPO[sp[0]][sp[1]].apply(curPO[sp[0]], args); //실행
+ return;
+ }
+ } else if(sp.length == 3){
+ if(curPO[sp[0]] !== undefined
+ && curPO[sp[0]][sp[1]] !== undefined
+ && curPO[sp[0]][sp[1]][sp[2]] !== undefined
+ && curPO[sp[0]][sp[1]][sp[2]] instanceof Function){
+ curPO[sp[0]][sp[1]][sp[2]].apply(curPO[sp[0]][sp[1]], args); //실행
+ return;
+ }
+ }
+
+ //STEP 2 : "pageObject전역객체.doctx명.ctrl또는control"에서 찾는다.
+ if(sp.length == 1){
+ let findedCtrl = null;
+ if(curPO["ctrl"] !== undefined){
+ findedCtrl = curPO["ctrl"];
+ } else if(curPO["control"] !== undefined){
+ findedCtrl = curPO["control"];
+ }
+ if(findedCtrl != null){
+ if(findedCtrl[methodName] !== undefined && findedCtrl[methodName] instanceof Function){
+ findedCtrl[methodName].apply(findedCtrl, args); //실행
+ return;
+ }
+ }
+ }
+ }
+
+ //STEP 3 : doctx를 갖는 DatasetControl 전역객체에서 찾는다.
+ if(sp.length == 1){
+ let findedCtrl = null;
+ for(var member in window){
+ if(window[member] instanceof DatasetControl){
+ if(window[member].doctx == doctx){
+ findedCtrl = window[member];
+ }
+ }
+ }
+ if(findedCtrl != null){
+ if(findedCtrl[methodName] !== undefined && findedCtrl[methodName] instanceof Function){
+ findedCtrl[methodName].apply(findedCtrl, args); //실행
+ return;
+ }
+ }
+ }
+
+ console.log('메소드를 찾을 수 없습니다.');
+ return;
+}
+
+
+/**************************************************************************
+* 검색버튼 클릭 이벤트 탐지 및 실행
+**************************************************************************/
+function detectListSearch(){
+ let inference = [
+ "Data_Open", //델파이(클린파킹)
+ "search", //DatasetControl
+ "searchList", "fnSearch", "fnSearchList"
+ ];
+
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 엑셀버튼 클릭 이벤트 탐지 및 실행
+**************************************************************************/
+function detectExcelDown(){
+ let inference = [
+ "fnExcel", "fnExcelDown", "excelDown"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 초기화버튼 클릭 이벤트 탐지 및 실행
+**************************************************************************/
+function detectInit(){
+ let inference = [
+ "fnInit", "fnResetAndChangeBiz", "fnReset"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 그리드 클릭 이벤트탐지 및 실행
+**************************************************************************/
+function detectGridClick(){
+ let inference = [
+ "setCurrent", //DatasetControl
+ "clickList", "fnClickList"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 그리드 더블클릭 이벤트탐지 및 실행
+**************************************************************************/
+function detectGridDoubleClick(){
+ let inference = [
+ "getInfo", //DatasetControl
+ "dblclickList", "fnDblclickList"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 그리드 체크박스 체크 이벤트탐지 및 실행
+**************************************************************************/
+function detectGridCheck(){
+ let inference = [
+ "select", //DatasetControl
+ "checkList", "fnCheckList"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+
+/**************************************************************************
+* 새 정보 입력화면 호출 버튼 클릭 이벤트탐지 및 실행
+**************************************************************************/
+function detectOpenNew(){
+ let inference = [
+ "newInfo", "getInfo", //DatasetControl
+ "fnCreate"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 저장 버튼 클릭 이벤트탐지 및 실행
+**************************************************************************/
+function detectSave(){
+ let inference = [
+ "save", //DatasetControl
+ "fnSave"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+/**************************************************************************
+* 삭제 버튼 클릭 이벤트탐지 및 실행
+**************************************************************************/
+function detectRemove(){
+ let inference = [
+ "remove", //DatasetControl
+ "fnDelete", "fnRemove"
+ ];
+ var args = Array.prototype.slice.call(arguments);
+ detectByInference(inference, args);
+}
+
+
+/**************************************************************************
+* 이벤트 추론
+**************************************************************************/
+function detectByInference(inference, args){
+
+ let element = event.target;
+
+ let doctx;
+ if(element.hasAttribute("data-ref-doctx")){
+ doctx = element.getAttribute("data-ref-doctx");
+ } else {
+ doctx = element.detectDoctx();
+ element.setAttribute("data-ref-doctx", doctx);
+ }
+
+ //pageObject 전역객체가 있고, pageObject 내부에 doctx를 키로 갖는 객체가 있으면
+ if((window.pageObject !== undefined) && (pageObject[doctx] !== undefined)){
+ let curPO = pageObject[doctx];
+
+ //STEP 1 : "pageObject전역객체.doctx명"에서 찾는다.
+ for(let keyword of inference){
+ if(curPO.hasOwnProperty(keyword)){
+ if(curPO[keyword] instanceof Function){
+ curPO[keyword].apply(curPO, args);
+ return;
+ }
+ }
+ }
+
+ //STEP 2 : "pageObject전역객체.doctx명.ctrl또는control"에서 찾는다.
+ let findedCtrl = null;
+ if(curPO["ctrl"] !== undefined){
+ findedCtrl = curPO["ctrl"];
+ } else if(curPO["control"] !== undefined){
+ findedCtrl = curPO["control"];
+ }
+ if(findedCtrl != null){
+ for(let keyword of inference){
+ if(findedCtrl[keyword] !== undefined && findedCtrl[keyword] instanceof Function){
+ findedCtrl[keyword].apply(findedCtrl, args);
+ return;
+ }
+ }
+ }
+ }
+
+ //STEP 3 : doctx를 갖는 DatasetControl 전역객체에서 찾는다.
+ let findedCtrl = null;
+ for(var member in window){
+ if(window[member] instanceof DatasetControl){
+ if(window[member].doctx == doctx){
+ findedCtrl = window[member];
+ }
+ }
+ }
+ if(findedCtrl != null){
+ for(let keyword of inference){
+ if(findedCtrl[keyword] !== undefined && findedCtrl[keyword] instanceof Function){
+ findedCtrl[keyword].apply(findedCtrl, args);
+ return;
+ }
+ }
+ }
+
+ console.log('메소드를 찾을 수 없습니다.');
+ return;
+}