교육샘플 열기
1
프로젝트 오픈
다운 받은 폴더의 압축을 푼 다음 교육 교재인 EduSysN 프로젝트를 오픈합니다. [menu] File > Open > Project : "EduSysN.xprj"를 선택하여 프로젝트를 오픈합니다.
2
Generate
다운 받은 교육 교재의 소스를 Generate 합니다. [menu] Generate > Application 를 선택하여 재너레이트 시킵니다.
화면의 구성
[샘플] Form::Form_ScriptSample1.xfdl
Form_ScriptSample1의 Form 구성
1 (Time 0_00_04;37)
NO | 구성 | 구성내용 |
---|---|---|
1 | 검색조건 | 재직상태, 성명, 부서, 입사일자를 기준으로 사원정보 검색 ( * 부서명은 Like 조건 ) |
2 | 사원목록 | 1에서 선택한 조건의 Dataset 'ds_emp'에 있는 사원 정보 List |
3 | 기본정보 | 2에서 선택한 'ds_emp'에 있는 사원의 상세정보 |
4 | 상세정보 | 2에서 선택한 사원의 상세정보 (발령사항 - ds_appoint) ( * 학력사항과 경력사항은 없음) |
개발시 가장 기본이 되는 마스터/디테일 형태로 구성되어 있습니다.
NO | 설명 |
---|---|
1 | 조회조건에 부서명은 Like 조건이므로 부서명의 일부만 입력해도 된다. 입사일자는 2014년도 까지 데이터가 존재하므로 from 입사일자 조건에 값을 지운다. |
2 | [조회] 버튼을 클릭하면 2에 사원목록을 표시합니다. 이때 부서명도 함께 표시됩니다. 화면의 ds_emp에는 DEPT_NAME 컬럼이 없으나 조회 시 서버에서 호출해오는 Dataset에는 DEPT_NAME 컬럼이 있습니다. |
3 | 2의 row를 선택하면 해당 정보가 3과 4에 출력합니다. |
4 | [입력] 버튼을 클릭하면 선택한 'ds_emp'에 있는 사원의 데이터를 추가합니다. |
5 | [삭제] 버튼을 클릭하면 선택한 'ds_emp'에 있는 사원의 데이터를 삭제합니다. |
6 | [저장] 버튼을 클릭하면 데이터 validation 을 체크하고 이상이 없는 경우 작업한 내용을 서버로 저장합니다. |
Dataset의 구성
NO | 구성 | 구성내용 | 화면구성 |
---|---|---|---|
1 | ds_emp | 선택 된 부서에 해당하는 사원정보 | 화면의 좌측 사원목록 데이터 |
2 | ds_pos | 직급 코드 정보 | 기본정보의 직급콤보의 데이터 |
3 | ds_appoint | 발령사항 Data | 상세정보의 발령사항의 데이터 |
4 | ds_status | 재직상태 | 검색조건의 재직상태의 데이터 |
- ds_pos 와 ds_status 는 코드성 데이터
ds_pos / ds_status
<ColumnInfo> <Column id="CODE" type="STRING" size="32"/> <Column id="CODE_NAME" type="STRING" size="32"/> </ColumnInfo>
ds_emp
<ColumnInfo> <Column id="EMPL_ID" type="STRING" size="10" description="사원번호"/> <Column id="FULL_NAME" type="STRING" size="50" description="성명"/> <Column id="DEPT_CD" type="STRING" size="10" description="부서코드"/> <Column id="POS_CD" type="STRING" size="10" description="직급코드"/> <Column id="HIRE_DATE" type="DATE" size="10" description="입사일자"/> <Column id="RETIRE_DATE" type="DATE" size="256" description="퇴사일자"/> <Column id="GENDER" type="STRING" size="10" description="성별"/> <Column id="PHONE_NO" type="STRING" size="10" description="연락처"/> <Column id="EMAIL" type="STRING" size="10" description="이메일"/> <Column id="STATUS" type="STRING" size="10" description="상태"/> <Column id="MEMO" type="STRING" size="256" description="특이사항"/> <Column id="CHK" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="EMPL_ID">TS0123</Col> <Col id="FULL_NAME">Maria Kim</Col> <Col id="DEPT_CD">01</Col> <Col id="POS_CD">03</Col> <Col id="HIRE_DATE">20101003</Col> <Col id="GENDER">M</Col> <Col id="PHONE_NO">01723641258</Col> <Col id="EMAIL">mariakim@tobe.com</Col> <Col id="STATUS">A</Col> </Row> <Row> <Col id="EMPL_ID">TS0105</Col> <Col id="FULL_NAME">John Park</Col> <Col id="DEPT_CD">02</Col> <Col id="POS_CD">04</Col> <Col id="HIRE_DATE">20051011</Col> <Col id="GENDER">W</Col> <Col id="PHONE_NO">01774212521</Col> <Col id="EMAIL">johnpark@tobe.com</Col> <Col id="STATUS">A</Col> </Row> <Row> <Col id="EMPL_ID">TS0815</Col> <Col id="FULL_NAME">Henry Hong</Col> <Col id="DEPT_CD">03</Col> <Col id="POS_CD">03</Col> <Col id="HIRE_DATE">20070206</Col> <Col id="GENDER">M</Col> <Col id="PHONE_NO">01755669913</Col> <Col id="EMAIL">henryhong@tobe.com</Col> <Col id="STATUS">A</Col> </Row> <Row> <Col id="EMPL_ID">TS0717</Col> <Col id="FULL_NAME">Serry Park</Col> <Col id="DEPT_CD">04</Col> <Col id="POS_CD">02</Col> <Col id="HIRE_DATE">20090512</Col> <Col id="GENDER">W</Col> <Col id="PHONE_NO">01758998487</Col> <Col id="EMAIL">serrypark@tobe.com</Col> <Col id="STATUS">B</Col> </Row> <Row> <Col id="EMPL_ID">TS1001</Col> <Col id="FULL_NAME">Dennis An</Col> <Col id="DEPT_CD">01</Col> <Col id="POS_CD">04</Col> <Col id="HIRE_DATE">20010109</Col> <Col id="GENDER">M</Col> <Col id="PHONE_NO">01752563217</Col> <Col id="EMAIL">dennisan@tobe.com</Col> <Col id="STATUS">B</Col> </Row> <Row> <Col id="EMPL_ID">TS1225</Col> <Col id="FULL_NAME">Jackson Yu</Col> <Col id="DEPT_CD">02</Col> <Col id="POS_CD">03</Col> <Col id="HIRE_DATE">20160202</Col> <Col id="GENDER">W</Col> <Col id="PHONE_NO">01726532234</Col> <Col id="EMAIL">jacksonyu@tobe.com</Col> <Col id="STATUS">C</Col> </Row> </Rows>
ds_appoint
<ColumnInfo> <Column id="EMPL_ID" type="STRING" size="256"/> <Column id="APPOINT_DATE" type="DATE" size="256"/> <Column id="APPOINT_TYPE" type="STRING" size="256"/> <Column id="MEMO" type="STRING" size="256"/> <Column id="START_DATE" type="DATE" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="EMPL_ID">TS0123</Col> <Col id="APPOINT_DATE">20101003</Col> <Col id="START_DATE">20101003</Col> <Col id="MEMO">입사</Col> </Row> <Row> <Col id="EMPL_ID">TS0105</Col> <Col id="APPOINT_DATE">20051011</Col> <Col id="START_DATE">20051011</Col> <Col id="MEMO">입사</Col> </Row> <Row> <Col id="EMPL_ID">TS0815</Col> <Col id="APPOINT_DATE">20070206</Col> <Col id="START_DATE">20070206</Col> <Col id="MEMO">입사</Col> </Row> <Row> <Col id="EMPL_ID">TS0717</Col> <Col id="APPOINT_DATE">20090512</Col> <Col id="START_DATE">20090512</Col> <Col id="MEMO">입사</Col> </Row> <Row> <Col id="EMPL_ID">TS1001</Col> <Col id="APPOINT_DATE">20010109</Col> <Col id="START_DATE">20010109</Col> <Col id="MEMO">입사</Col> </Row> <Row> <Col id="EMPL_ID">TS1225</Col> <Col id="APPOINT_DATE">20160202</Col> <Col id="START_DATE">20160202</Col> <Col id="MEMO">입사</Col> </Row> </Rows>
component 명명규칙
컴포넌트에 id를 지정하는 이유는 스크립트에서 컴포넌트를 분별할 수 있도록 하기 위해서다.
1 (Time 0_00_04;37)
의미가 있는 컴포넌트는 접두어(Prefix) + 의미 있는 단어로 조합해서 사용 ex)btn_Save
의미가 없는 컴포넌트는 자동생성된 id를 그냥 사용 ex) Static00
스크립트 분석하기
반복 또는 중복 되는 스크립트가 많다.
코드 데이터 가져올 때 2개의 transaction을 하나로 합칠 수 있다.
재직상태를 비동기로 처리해서 callback에 넣어둘 수 있다.
Form의 onload 이벤트
- this.Form_onload
onload : Form 에 등록된 모든 컴포넌트와 데이터가 로드된 후 발생하는 이벤트입니다.
초기값 설정
검색조건 입사일자 From~To 셋팅하기 ( From 일자는 이번 달 1일 ~ To 일자는 오늘 날짜 )
코드 데이터 가져오기 ( 직급, 재직 상태 ) - jsp 실행해서 보여주기
검색조건의 재직상태 '전체' 표현하기
this.Form_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo) { // 초기값 설정 // 조회조건 입사일자 From:이번달 1일, To:오늘날짜 var objDate = new Date(); var sYear = objDate.getFullYear().toString(); var sMonth = (objDate.getMonth()+1).toString().padLeft(2, "0"); var sDay = objDate.getDate().toString().padLeft(2, "0"); this.div_search.form.cal_from.set_value(sYear+sMonth+"01"); this.div_search.form.cal_to.set_value(sYear+sMonth+sDay); // 코드 데이터 가져오기 - 직급, 재직상태 // 직급 var sSvcID = "svcPositionCode"; var sURL = "SvcUrl::select_tbn_code_pos.jsp"; var sInDs = ""; var sOutDs = "ds_pos=out_pos"; var sParam = ""; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); // 재직상태 var sSvcID = "svcStatusCode"; var sURL = "SvcUrl::select_tbn_code_status.jsp"; var sInDs = ""; var sOutDs = "ds_status=out_status"; var sParam = ""; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack, false); //재직상태 '전체' 표현 this.ds_status.insertRow(0); this.ds_status.setColumn(0, "CODE", "ALL"); this.ds_status.setColumn(0, "CODE_NAME", "전체"); // 재직상태 '전체' 선택 this.div_search.form.rdo_status.set_value("ALL"); //화면 로드시 데이터 조회 // this.btn_search_onclick(); };
재직상태의 '전체'를 표현하기 위해 select_tbn_code_status.jsp를 호출할 때 Transaction의 7번째 인자를 false지정했습니다
7번째는 동기/비동기 통신을 의미합니다.
false를 하게 되면 동기통신으로 하겠다는 것을 의미합니다.
동기(Sync)통신의 처리방식은 서비스를 호출하고 데이터를 다 받을 때까지 다음 스크립트가 동작하지 않고 대기하고 데이터를 다 받으면 다음 라인의 스크립트가 진행합니다.
성능향상을 위해 비동기(Async) 통신방식을 권장합니다.
조회
- this.btn_search_onclick
조회 버튼을 클릭했을 때 사원정보와 상세정보를 가져옵니다. 검색조건에 조건을 줄 때 부서는 부서명 Like이고 입사일자는 시작일을 빼고 조회합니다.
입사일자가 오래전이라 조건을 줄 때 입사일자 시작일을 빼고 조회를 해야 데이터가 조회됩니다.
사원정보 가져오기
// 사원정보 가져오기 var sSvcID = "svcSelectEmp"; var sURL = "SvcUrl::select_tbn_emp.jsp"; var sInDs = ""; var sOutDs = "ds_emp=out_emp"; var sParam = "pStatus=" + this.div_search.form.rdo_status.value + " pName=" + nexacro.wrapQuote(this.div_search.form.ed_name.value) + " pDept=" + nexacro.wrapQuote(this.div_search.form.edt_dept.value) + " pDateFrom=" + this.div_search.form.cal_from.value + " pDateTo=" + this.div_search.form.cal_to.value; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack, false);
- 가져온 사원정보를 가지고 상세정보를 조회 하기 위해 동기통신을 이용하였습니다.
상세정보 가져오기
// 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(this.ds_emp.rowposition, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack);
콜백함수
this.fn_callback = function(svcID, errCD, errMSG) { if(errCD < 0){ this.alert("Error: " + svcID + " " + errMSG); return; } }
입력
- this.btn_add_onclick
ds_emp에 row 추가하기
사원 데이터 입사일자에 오늘일자 설정
ds_emp에 입사일 컬럼에 오늘일자 값 추가하기
var nRow = this.ds_emp.addRow(); this.div_detail.form.edt_name.setFocus(); //사원 데이터 입사일자에 오늘일자 설정 var objDate = new Date(); var sToday = objDate.getFullYear().toString(); sToday += (objDate.getMonth()+1).toString().padLeft(2, "0") sToday += objDate.getDate().toString().padLeft(2, "0"); this.ds_emp.setColumn(nRow, "HIRE_DATE", sToday);
삭제
- this.btn_del_onclick
삭제여부를 묻기
ds_emp에 해당 row 삭제하기
if(this.confirm("선택된 자료를 삭제 하시겠습니까?")){ this.ds_emp.deleteRow(this.ds_emp.rowposition); }
저장
- this.btn_save_onclick
기존 데이터의 보존을 위해서 실제 저장은 안되고 있습니다.
validation
1
성명 필수입력 항목 체크
var sName = this.ds_emp.getColumn(i, "FULL_NAME"); if(sName == null || sName.length == 0){ this.alert("성명은 필수입력 항목입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.edt_name.setFocus(); return; }
2
사원번호 필수입력 항목 체크
var sId = this.ds_emp.getColumn(i, "EMPL_ID"); if(sId == null || sId.length == 0){ this.alert("사원번호는 필수입력 항목입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.msk_id.setFocus(); return; }
3
사원번호 5자리 체크
if(sId.trim().length != 5){ this.alert("사원번호는 5자리 입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.msk_id.setFocus(); return; }
저장하기
var sSvcID = "svcSaveEmp"; var sURL = "SvcUrl::save_tbn_emp.jsp"; var sInDs = "in_emp=ds_emp:u"; var sOutDs = ""; var sParam = "in_var1="+nexacro.wrapQuote(this.titletext) + " in_var2="+this.name ; var sCallBack = "fn_callback_save"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack);
콜백함수
this.fn_callback_save = function(svcID, errCD, errMSG) { if(errCD < 0){ this.alert("Error: " + svcID + " " + errMSG); return; } if(svcID == "svcSaveEmp"){ this.alert("저장되었습니다."); } }
부서 팝업
- this.div_detail_btn_pop_dept_onclick
Form::Popup_DeptSearch.xfdl 부서선택 팝업창을 띄운다.
콜백함수에서 선택된 부서코드와 부서명 가져와서 ds_emp 데이터 셋에 값 넣기
this.div_detail_btn_pop_dept_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { var objChild = new ChildFrame("popDept", 0, 0, 300, 400); objChild.set_formurl("Form::Popup_DeptSearch.xfdl"); objChild.set_openalign("center middle"); objChild.set_dragmovetype("all"); objChild.showModal(this.getOwnerFrame() , {} , this , "fn_callback_pop"); }; this.fn_callback_pop = function(sPopupId, sReturn) { if(sPopupId == "popDept") { if(sReturn.length > 0){ var arrRtn = sReturn.split("|"); this.ds_emp.setColumn(this.ds_emp.rowposition, "DEPT_CD" , arrRtn[0]); this.ds_emp.setColumn(this.ds_emp.rowposition, "DEPT_NAME", arrRtn[1]); } } }
사원목록 Grid
Cell 클릭 시 상세정보 가져오기
- grd_emp_oncellclick
this.grd_emp_oncellclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { // 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(this.ds_emp.rowposition, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); };
사원관리 ds_emp의 rowposition 변경 시 상세정보 가져오기
- this.ds_emp_onrowposchanged
this.ds_emp_onrowposchanged = function(obj:nexacro.NormalDataset,e:nexacro.DSRowPosChangeEventInfo) { trace("ds_emp_onrowposchanged"); // 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(e.newrow, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); };
this.ds_emp_onrowposchanged 이벤트에서 또 상세정보를 가져오는 서비스를 호출했네요 이것은 언제 사용할까요 ? row의 포지션이 변경될 때 발생하는 이벤트입니다. 방금 그리드 oncellclick의 경우에는 마우스를 이용해서 사용하는 경우 데이터를 잘 가져옵니다. 하지만 마우스가 아닌 키보드를 이용하는 경우에는 데이터를 가져오지 못해요 이것을 해결하기 위해 this.ds_emp_onrowposchanged 이벤트에서 서비스를 가져오도록 작성을 했습니다.
동일한 작업을 2개의 이벤트에서 작업하고 있는 것을 확인할 수 있습니다.
// 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(this.ds_emp.rowposition, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack);
Head 클릭
- this.tab_detail_Tabpage1_grd_appoint_onheadclick
전체 선택/ 해제 하기 (obj.setCellProperty("Head", e.cell, "text", sText); )
정렬하기 ( this.fn_girdSort(obj, e) )
var sType = obj.getCellProperty("head", e.cell, "displaytype"); var sText = ""; if(sType == "checkboxcontrol"){ var objDs = obj.getBindDataset(); if(objDs.getRowCount() < 1) return; sText = obj.getCellProperty("head", e.cell, "text"); sText = (sText == "1" ? "0" : "1"); for(var i=0; i < objDs.rowcount; i++){ objDs.setColumn(i, "CHK", sText); } obj.setCellProperty("Head", e.cell, "text", sText); }
this.CONST_NONE_MARK = ""; this.CONST_ASC_MARK = "↑"; this.CONST_DESC_MARK = "↓"; this.fn_gridSort = function (obj, e) { if(obj.getCellProperty("head", e.cell, "displaytype") == "checkboxcontrol") return; var objDs = obj.getBindDataset(); var sColId = obj.getCellProperty("body", e.cell, "text").split(":"); var sHeadText = ""; for(var i = 0; i<obj.getCellCount("head"); i++) { sHeadText = obj.getCellText(-1, i) ; if(i == e.cell){ if (sHeadText.substr(sHeadText.length-1) == this.CONST_ASC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1) + this.CONST_DESC_MARK); objDs.set_keystring("S:-" + sColId[1]); } else if (sHeadText.substr(sHeadText.length-1) == this.CONST_DESC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1) + this.CONST_ASC_MARK); objDs.set_keystring("S:+" + sColId[1]); } else { obj.setCellProperty("head", i, "text", sHeadText + this.CONST_ASC_MARK); objDs.set_keystring("S:+" + sColId[1]); } } else { if(sHeadText != null & sHeadText != ""){ if (sHeadText.substr(sHeadText.length - 1) == this.CONST_ASC_MARK || sHeadText.substr(sHeadText.length - 1) == this.CONST_DESC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1)); } } } } }
상세정보 > 발령사항 > Grid
Head 클릭 시 정렬하기
this.tab_detail_Tabpage1_grd_appoint_onheadclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { this.fn_gridSort(obj, e); };
소스 분석에 대한 개인의견 정리
지금까지 스크립트를 함께 살펴봤는데 어러분이 볼 때 어떤 느낌이 들까요 잘 짜인 스크립트일까요? 아니면 문제가 있는 스크립트일까요?
만약 잘못된 소스라고 생각한다면 어떤 것 때문에 그렇게 생각하시나요?
의견정리
중복되는 스크립트 정리하기
서비스 호출 방식이 동기식(Sync) 방식을 비동기식(Async)으로 수정하기
여러 번 서비스를 호출해서 각각 코드를 받아 온 부분을 한번의 서비스 호출로 여러 개의 코드 받아오기
콜백함수 수정하기 (비동기에 의한 처리 추가, 여러 개의 콜백 하나로 합치기)
전체소스
this.Form_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo) { // 초기값 설정 // 조회조건 입사일자 From:이번달 1일, To:오늘날짜 var objDate = new Date(); var sYear = objDate.getFullYear().toString(); var sMonth = (objDate.getMonth()+1).toString().padLeft(2, "0"); var sDay = objDate.getDate().toString().padLeft(2, "0"); this.div_search.form.cal_from.set_value(sYear+sMonth+"01"); this.div_search.form.cal_to.set_value(sYear+sMonth+sDay); // 코드 데이터 가져오기 - 직급, 재직상태 // 직급 var sSvcID = "svcPositionCode"; var sURL = "SvcUrl::select_tbn_code_pos.jsp"; var sInDs = ""; var sOutDs = "ds_pos=out_pos"; var sParam = ""; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); // 재직상태 var sSvcID = "svcStatusCode"; var sURL = "SvcUrl::select_tbn_code_status.jsp"; var sInDs = ""; var sOutDs = "ds_status=out_status"; var sParam = ""; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack, false); //재직상태 '전체' 표현 this.ds_status.insertRow(0); this.ds_status.setColumn(0, "CODE", "ALL"); this.ds_status.setColumn(0, "CODE_NAME", "전체"); // 재직상태 '전체' 선택 this.div_search.form.rdo_status.set_value("ALL"); //화면 로드시 데이터 조회 // this.btn_search_onclick(); }; // Retrieve Button this.btn_search_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { // 사원정보 가져오기 var sSvcID = "svcSelectEmp"; var sURL = "SvcUrl::select_tbn_emp.jsp"; var sInDs = ""; var sOutDs = "ds_emp=out_emp"; var sParam = "pStatus=" + this.div_search.form.rdo_status.value + " pName=" + nexacro.wrapQuote(this.div_search.form.edt_name.value) + " pDept=" + nexacro.wrapQuote(this.div_search.form.edt_dept.value) + " pDateFrom=" + this.div_search.form.cal_from.value + " pDateTo=" + this.div_search.form.cal_to.value; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack, false); // 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(this.ds_emp.rowposition, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); }; this.fn_callback = function(svcID, errCD, errMSG) { if(errCD < 0){ this.alert("Error: " + svcID + " " + errMSG); return; } } // Add Button this.btn_add_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { var nRow = this.ds_emp.addRow(); this.div_detail.form.edt_name.setFocus(); //사원 데이터 입사일자에 오늘일자 설정 var objDate = new Date(); var sToday = objDate.getFullYear().toString(); sToday += (objDate.getMonth()+1).toString().padLeft(2, "0") sToday += objDate.getDate().toString().padLeft(2, "0"); this.ds_emp.setColumn(nRow, "HIRE_DATE", sToday); }; // Delete Button this.btn_del_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { if(this.confirm("선택된 자료를 삭제 하시겠습니까?")){ this.ds_emp.deleteRow(this.ds_emp.rowposition); } }; // Save Button this.btn_save_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { for(var i=0; i<this.ds_emp.rowcount; i++) { if(this.ds_emp.getRowType(i) == 1) continue; var sName = this.ds_emp.getColumn(i, "FULL_NAME"); if(sName == null || sName.length == 0){ this.alert("성명은 필수입력 항목입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.edt_name.setFocus(); return; } var sId = this.ds_emp.getColumn(i, "EMPL_ID"); if(sId == null || sId.length == 0){ this.alert("사원번호는 필수입력 항목입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.msk_id.setFocus(); return; } if(sId.trim().length != 5){ this.alert("사원번호는 5자리 입니다."); this.ds_emp.set_rowposition(i); this.div_detail.form.msk_id.setFocus(); return; } } var sSvcID = "svcSaveEmp"; var sURL = "SvcUrl::save_tbn_emp.jsp"; var sInDs = "in_emp=ds_emp:u"; var sOutDs = ""; var sParam = "in_var1="+nexacro.wrapQuote(this.titletext) + " in_var2="+this.name ; var sCallBack = "fn_callback_save"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); }; this.fn_callback_save = function(svcID, errCD, errMSG) { if(errCD < 0){ this.alert("Error: " + svcID + " " + errMSG); return; } if(svcID == "svcSaveEmp"){ this.alert("저장되었습니다."); } } this.grd_emp_oncellclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { trace("grd_emp_oncellclick"); // 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(this.ds_emp.rowposition, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); }; this.ds_emp_onrowposchanged = function(obj:nexacro.NormalDataset,e:nexacro.DSRowPosChangeEventInfo) { trace("ds_emp_onrowposchanged"); // 상세정보 가져오기 var sEmpID = this.ds_emp.getColumn(e.newrow, "EMPL_ID"); var sSvcID = "svcSelectDetail"; var sURL = "SvcUrl::select_tbn_emp_appoint.jsp"; var sInDs = ""; var sOutDs = "ds_appoint=out_appoint"; var sParam = "pEmpID='" + sEmpID + "'"; var sCallBack = "fn_callback"; this.transaction(sSvcID, sURL, sInDs, sOutDs, sParam, sCallBack); }; this.div_detail_btn_pop_dept_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { var objChild = new ChildFrame("popDept", 0, 0, 300, 400); objChild.set_formurl("Form::Popup_DeptSearch.xfdl"); objChild.set_openalign("center middle"); objChild.set_dragmovetype("all"); objChild.showModal(this.getOwnerFrame() , {} , this , "fn_callback_pop"); }; this.fn_callback_pop = function(sPopupId, sReturn) { if(sPopupId == "popDept") { if(sReturn.length > 0){ var arrRtn = sReturn.split("|"); this.ds_emp.setColumn(this.ds_emp.rowposition, "DEPT_CD" , arrRtn[0]); this.ds_emp.setColumn(this.ds_emp.rowposition, "DEPT_NAME", arrRtn[1]); } } } this.grd_emp_onheadclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { var sType = obj.getCellProperty("head", e.cell, "displaytype"); var sText = ""; if(sType == "checkboxcontrol"){ var objDs = obj.getBindDataset(); if(objDs.getRowCount() < 1) return; sText = obj.getCellProperty("head", e.cell, "text"); sText = (sText == "1" ? "0" : "1"); for(var i=0; i < objDs.rowcount; i++){ objDs.setColumn(i, "CHK", sText); } obj.setCellProperty("Head", e.cell, "text", sText); } else{ this.fn_gridSort(obj, e); } }; this.tab_detail_Tabpage1_grd_appoint_onheadclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { this.fn_gridSort(obj, e); }; this.CONST_NONE_MARK = ""; this.CONST_ASC_MARK = "↑"; this.CONST_DESC_MARK = "↓"; this.fn_gridSort = function (obj, e) { if(obj.getCellProperty("head", e.cell, "displaytype") == "checkboxcontrol") return; var objDs = obj.getBindDataset(); var sColId = obj.getCellProperty("body", e.cell, "text").split(":"); var sHeadText = ""; for(var i = 0; i<obj.getCellCount("head"); i++) { sHeadText = obj.getCellText(-1, i) ; if(i == e.cell){ if (sHeadText.substr(sHeadText.length-1) == this.CONST_ASC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1) + this.CONST_DESC_MARK); objDs.set_keystring("S:-" + sColId[1]); } else if (sHeadText.substr(sHeadText.length-1) == this.CONST_DESC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1) + this.CONST_ASC_MARK); objDs.set_keystring("S:+" + sColId[1]); } else { obj.setCellProperty("head", i, "text", sHeadText + this.CONST_ASC_MARK); objDs.set_keystring("S:+" + sColId[1]); } } else { if(sHeadText != null & sHeadText != ""){ if (sHeadText.substr(sHeadText.length - 1) == this.CONST_ASC_MARK || sHeadText.substr(sHeadText.length - 1) == this.CONST_DESC_MARK) { obj.setCellProperty("head", i, "text", sHeadText.substr(0, sHeadText.length - 1)); } } } } }