XPLATFORM 컴폰너트를 사용시 개발자 분들이 자주묻는 유형별로 해결방법을 가이드 합니다.
Application
애플리케이션의 mainframe, trays, widgets, global variables, global objects 로의 접근을 위해 사용되는 속성입니다.
function application_onload(obj:Object, e:LoadEventInfo) { for(var i = 0; i < application.all.length; i++) { trace("Object ==> "+application.all[i]+ "Object Name ==> "+ application.all[i].name); } }
Application에 포함된 Global변수의 값을 모두 trace를 통해 확인해 볼 수 있나요?
Application의 onduplicateexcution 이벤트에 들어온 값을 확인하는 방법
function application_onduplicateexcution(obj:Object, e:DuplicateExcutionEventInfo) { var temp =e.arguments; // GlobalValue의 Collection Property 입니다. trace("onduplicateexcution Event"); for (var i=0; i <temp.length;i++){ trace("::::::::::id:"+temp[i].name+"::::::::::value:"+temp[i].value); } }
Application의 실행경로 확인방법
Application의 실행경로 즉 ADL경로를 얻는 방법
애플리케이션에서 사용하는 ADL 경로를 갖는 속성입니다.
trace(application.xadl)
프로그램 실행경로를 알 수 있나요?
TypeDefinition의 Services에 등록된 Group별 경로를 얻는 방법
아래와 같이 services객체에 접근하여 해당 url을 얻어 오실 수 있습니다.
for(var i=0; i<application.services.length; i++) { trace(application.services[i] + " : " + application.services[i].url); }
스크립트를 이용한 폼경로 및 ROOT경로 얻는 방법
아래 코드함수를 이용하여 얻을 수 있습니다. 예) Edit00.value = GetThisUrl(); Edit01.value = GetProjectPath();
/******************************************************************************* ★ 설명 화면내에서 자기 자신화면의 Url을 얻어온다. ★ Parameter 없음 ★ return - 성공 = 자기 자신화면의 Url ( 절대경로 또는 Service::a.xfdl 형태로 return됨 ) - 실패 = "" ******************************************************************************/ function GetThisUrl() { var this_url, parent_type; // Division, Tab, PopupDiv인 경우에는 따로 처리해야 함 parent_type = GetObjType(parent); if( parent_type == "Div" || parent_type == "PopupDiv" || parent_type == "TabPage" ) this_url = parent.url; else this_url = this.getOwnerFrame().formurl; return this_url; } /******************************************************************************* ★ 설명 현재 실행되고 있는 Project의 Root Full Path를 얻어온다. ★ Parameter 없음 ★ return - 성공 = 현재 실행되고 있는 Project의 Root Full Path - 실패 = "" ★ 참고사항 현재 실행되고 있는 ADL Path는 application.xadl을 통해 얻을 수 있다. ★ 목적 Tool에서 system.execXPlatform을 하면 Project경로를 알수 없어 실행이 힘들기 때문에 만들었다. (???(BUG)) ★ BUG 모든 화면 Service는 Project내의 바로 한단계 아래의 Sub Directory이고 ADL은 Project Directory에 있다는 전제하에 만들어 졌다. 즉, Project=C:\A\, ADL=C:\A\ADL.xadl, Service=C:\A\Service\라는 가정하에 만들어졌다. ******************************************************************************/ function GetProjectPath() { var cur_xadl, filename, project_path; cur_xadl = application.xadl; if( IsNull(cur_xadl) ) return ""; filename = GetFileName(cur_xadl, true); if( IsNull(filename) ) return ""; // QuickView로 돌린 경우 if( filename == "empty_adl.xadl" ) { var this_url, pos; this_url = Replace( childframe.formurl, "\\", "/" ); pos = PosReverse( this_url, "/"); if( pos < 0 ) return ""; pos = PosReverse( this_url, "/", pos-1); if( pos < 0 ) return ""; project_path = childframe.formurl.substr(0, pos+1); } // Launch Project로 돌린 경우 else { var trim_path; project_path = GetFilePath(application.xadl); trim_path = LTrim(project_path, "file://"); if( trim_path != project_path ) project_path = Replace( trim_path, "/", "\\" ); } return project_path; } /******************************************************************************* ★ 설명 Object의 type을 문자열로 얻어온다. ★ parameter 1. oObj : type을 얻어올 Object (예 : mainframe, this.getOwnerFrame(), this, button,...) ★ return - 성공 = Object의 type문자열(예 : "MainFrame", "ChildFrame", "Form", "Button",...) - 실패 = "" ******************************************************************************/ function GetObjType(oObj) { var sType; if( IsNull(oObj) ) return ""; sType = oObj.toString().valueOf().substr(1,6); if( sType.toLowerCase() == "object" ) return Mid(oObj.toString().valueOf(), " ", "]"); return ""; } /******************************************************************************* ★ 설명 입력값이 null에 해당하는 경우 모두를 한번에 체크한다. ★ Parameter 1. sValue : 체크할 문자열( 예 : null 또는 undefined 또는 "" 또는 "abc" ) ★ return - sValue가 undefined, null, NaN, "", Array.length = 0인 경우 = true - 이외의 경우 = false ******************************************************************************/ function IsNull(sValue) { if( new String(sValue).valueOf() == "undefined") return true; if( sValue == null ) return true; if( ("x"+sValue == "xNaN") && ( new String(sValue.length).valueOf() == "undefined" ) ) return true; if( sValue.length == 0 ) return true; return false; } /******************************************************************************* ★ 설명 시작글자와 끝글자에 해당하는 글자의 사이에 있는 가운데 글자를 대소문자를 구별하여 찾는다. ( 예 : aaBBbbccdd에서 bb, dd사이의 글자 cc를 찾는다 ) ★ Parameter 1. sOrg : 원래 문자열( 예 : "aaBBbbccdd" ) 2. sStart : 찾고자 하는 시작 문자열(옵션 : Default = "")(예 : "bb" ) (만일, sStart=""이면 nStart부터 sEnd까지의 모든 문자열이 return된다.) 3. sEnd : 찾고자 하는 끝 문자열 (옵션 : Default = "")( 예 : "dd" ) (만일, sEnd=""이면 sStart부터 문자열의 끝까지의 모든 문자열이 return된다.) 4. nStart : 검색 시작위치 (옵션 : Default=0) ( 예 : 1 ) ★ return - 성공 = 가운데 글자 ( 예 : "cc" ) - 실패 = "" ******************************************************************************/ function Mid(sOrg, sStart, sEnd, nStart) { var pos_start, pos_end, ret_str; if( IsNull(sOrg) ) return ""; if( IsNull(sStart) ) sStart = ""; if( IsNull(sEnd) ) sEnd = ""; if( IsNull(nStart) ) nStart = 0; if( sStart == "" ) pos_start = nStart; else { pos_start = Pos(sOrg, sStart, nStart); if( pos_start < 0 ) return ""; } if( sEnd == "" ) pos_end = sOrg.length; else { pos_end = Pos(sOrg, sEnd, pos_start+sStart.length, nStart); if( pos_end < 0 ) return ""; } return sOrg.substring(pos_start+sStart.length, pos_end); } /******************************************************************************* ★ 설명 문자열의 위치를 대소문자 구별하여 찾는다 ★ Parameter 1. sOrg : 원래 문자열( 예 : "aaBBbbcc" ) 2. sFind : 찾고자 하는 문자열( 예 : "bb" ) 3. nStart : 검색 시작위치 (옵션 : Default=0) ( 예 : 1 ) ★ return - 성공 = 찾고자 하는 문자열의 시작위치 ( 예 : 4 ) - 실패 = -1 ******************************************************************************/ function Pos(sOrg, sFind, nStart) { if( IsNull(sOrg) || IsNull(sFind) ) return -1; if( IsNull(nStart) ) nStart = 0; return sOrg.indexOf(sFind, nStart); } /******************************************************************************* ★ 설명 File Path 문자열(예 : C:\a\b\filename.ext)에서 File명(예 : filename)을 추출 ★ Parameter 1. sPath : File Path 문자열 (예 : "C:\a\b\filename.ext") 2. bExt : extend를 return되는 File명에 포함시킬지 여부 ( 옵션 : Default=false ) - true : extend를 File명에 포함시킴 - false : extend를 File명에 포함시키지 않음 ★ return - 성공 = - bExt = true인 경우 ==> sPath에서 File명(예 : "filename.ext") - bExt = false인 경우 ==> sPath에서 File명(예 : "filename") - 실패 = "" ******************************************************************************/ function GetFileName( sPath, bExt ) { var start_pos, end_pos, tmp_pos, filename; if( IsNull(sPath) ) return ""; if( IsNull(bExt) ) bExt = false; start_pos = Math.max(PosReverse( sPath, "\\" ), PosReverse( sPath, "/" )); tmp_pos = PosReverse( sPath, "::"); if( tmp_pos > 0 ) tmp_pos++; start_pos = Math.max( start_pos, tmp_pos ); if( bExt == false ) { end_pos = PosReverse( sPath, "." ); if( end_pos < 0 ) end_pos = sPath.length; filename = sPath.substr( start_pos+1, end_pos-start_pos-1 ); } else { filename = sPath.substr( start_pos+1 ); } return filename; } /******************************************************************************* ★ 설명 문자열의 위치를 대소문자 구별하여 거꾸로 찾는다 ★ Parameter 1. sOrg : 원래 문자열( 예 : "aaBBbbcc" ) 2. sFind : 찾고자 하는 문자열( 예 : "BB" ) 3. nStart : 검색 시작위치 (옵션 : Default=문자열의 끝 ) ( 예 : 6 ) ★ return - 성공 = 찾고자 하는 문자열의 시작위치 ( 예 : 2 ) - 실패 = -1 ******************************************************************************/ function PosReverse(sOrg, sFind, nStart) { var pos; if( IsNull(sOrg) || IsNull(sFind) ) return -1; if( IsNull(nStart) ) nStart = sOrg.length-1; for( pos = nStart ; pos >= 0 ; pos-- ) { if( sOrg.substr( pos, sFind.length ) == sFind ) break; } return pos; } /******************************************************************************* ★ 설명 문자열을 대소문자 구별하여 치환한다 ★ Parameter 1. sOrg : 원래문자열 (예 : "aaBBbbccBB" ) 2. sRepFrom : 치환할 문자열 ( 예 : "BB" ) 3. sRepTo : 치환될 문자열 ( 예 : "xx" ) ★ return - 성공 = 치환된 문자열 ( 예 : "aaxxbbccxx" ) - 실패 = sOrg ******************************************************************************/ function Replace( sOrg, sRepFrom, sRepTo ) { var pos, nStart=0, sRet=""; if( IsNull(sOrg) ) return ""; if( IsNull(sRepFrom) ) return sOrg; if( IsNull(sRepTo) ) return sOrg; while(1) { pos = Pos( sOrg, sRepFrom, nStart ); if( pos < 0 ) { sRet += sOrg.substr( nStart ); break; } else { sRet += sOrg.substr( nStart, pos - nStart); sRet += sRepTo; nStart = pos+sRepFrom.length; } } return sRet; }
Application안에서 사용하는 컴포넌트의 ScrollBar의 사이즈를 조정하는 방법
그리드의 데이타가 많은 경우 가로/세로 스크롤이 발생하게 됩니다. 또한 마우스를 이용하의 움직일 수 있는 bar가 나타나게 되는데 이때 bar의 최소 사이즈를 지정하고 싶은경우가 있습니다. 이 경우에는 CSS를 이용하여 세팅을 할 수 있습니다.
ex) *>#vscrollbar { background : #929292b3; barminsize : 50; <---- 적당한 사이즈를 지정해 주시면 됩니다. }
해당 내용은 그리드 뿐 아니라, 폼, Div, TabPage 등 모든 스크롤에 대해 적용이 됩니다.
Form
frame 동기화 처리 방법
Frame의 로딩 순서가 랜덤하게 결정되어 sync 문제가 생길 경우 동기화시킬 수 있는 방안에 대해 기술합니다.
폼이 Load시 ASync방식으로 동작을 하기 때문에 시간차가 발생하는 경우입니다.
만약 다른 Frame에 함수를 호출하는 경우에 처리할 수 있습니다.
사용 예) 1) Global변수에 Count변수를 선언합니다. 예: gFCnt=0; 2) 프레임 정의 상단 프레임이 A라 가정하고 실제 함수가 포함되어 있다 가정 B프레임 실해 함수를 호출하는 프레임이라 가정 A의 프레임의 onLoad이벤트에서 다음과 같이 체크 if(gFCnt==1) { //B프레임이에서 이미 호출을 한번 했었다는 의미 그럼 자기자신의 함수를 호출 해줌 } else { gFCnt=1; //아직 B에서 호출하기 전 } B의 프레임의 onLoad이벤트에서 다음과 같이 체크 if(gFCnt==1) { //A가 정상적으로 먼저 Load가 된 경우 그럼 자기자신의 함수를 호출 해줌 } else { gFCnt=1; //아직 A가 호출하기 전 }
위와 같이 처리를 하면 반드시 순서에 상관없이 실행이 가능합니다.
즉 원하는 페이지가 Load되었으면 함수를 호출하고 Load된 이면 gFCnt에 값 1로 변경해 주고 해당 페이지가 Load되면 자기 자신의 함수를 호출해 주는 것입니다.
만약 반드시 B프레임에서 호출을 해야 하는 경우라면 A프레임에서 자기자신을 호출하는 것이 아니라 B프레임이 함수를 호출하여 다시 실행되도록 하면 되겠습니다.
Frame 동기화 방법
XPLATFORM [ChildFrame Close 시 Dataset 전달]
현상
기존에 사용하던 코드는 엔진에 존재했던 버그에 기반하여 사용된 예로엔진 코드 오류의 수정에 따라 버그가 수정되어 더이상 기존과 같은 코드는 사용하실 수 없습니다
해결방법
.close() 메소드를 호출하면 Form에 add되어 관리되는 object(Component, Dataset 등)는 Owner인 폼이 닫히기 때문에 함께 소멸과정을 진행하게 됩니다. 때문에 close() 메소드의 Argument를 Form의 Dataset을 직접 사용하지 말고removeChild() 후 Argument로 사용하거나 새로운 Dataset을 생성하여 Data를 복사한 후 rgument로 사용하여야 합니다.
사용 예) 방법1) removeChild 후 사용 var ds = this.removeChild("Dataset00"); close(ds); 방법2) 새로운 Dataset을 생성하여 Data를 복사한 후 사용 var ds = new Dataset; ds.assign(Dataset00); // 또는 ds.copyData(Dataset00); close(ds);
isValidObject 사용 방법
입력된 Object 또는 Name이 Form내에 존재하는 Object인지 여부를 확인하는 메소드 입니다.
기본 사용방법
사용 예) var bRet; bRet = isValidObject(Button00); bRet = isValidObject("Button00");
주의사항
TabPage, Div안에 포함된 Object를 체크하고자 한다면 아래와 같이 사용해야 합니다.
var bRet; bRet = Tab0.tabpage1.isValidObject(Button00); bRet = div00.isValidObject("Button00");
isValidObject가 정상적으로 체크되지 않습니다.
폼에 존재하는 컴포넌트의 경로를 얻는방법
XPLATFORM 폼에서 사용한 컴포넌트의 Full경로를 얻는방법에 대해 기술합니다.
화면유형
작업소스
function Button00_onclick(obj:Button, e:ClickEventInfo) { var arrRetComp = gf_GetCompFullName(this); for (var i=0; i<arrRetComp.length; i++) { trace(arrRetComp[i]); } } /********************************************************************************************* ** function name : gf_GetCompFullName() ** function description : Form에 존재하는 Component Full Name 조회 (Recusive 함수임) ** argument : obj 찾을 대상 obj ** strUpperComp 상위 Component ** return Type : ** ex : gf_GetCompFullName(this, "") *********************************************************************************************/ function gf_GetCompFullName(obj, strUpperComp) { if (strUpperComp == null || strUpperComp == undefined) strUpperComp = ""; var arrRet = new Array(); for (var i=0; i<obj.components.length; i++) { if (obj.components[i] instanceof Div || obj.components[i] instanceof PopupDiv || obj.components[i] instanceof Tabpage) { var compName = obj.components[i].name; if (strUpperComp.length > 0) compName = strUpperComp + "." + compName; var tmpArrRet = gf_GetCompFullName(obj.components[i], compName); if (tmpArrRet.length > 0) { arrRet = arrRet.concat(tmpArrRet); } //Composite Component 자체도 목록으로 볼 경우 arrRet.push(compName); } else if (obj.components[i] instanceof Tab) { var tabObj = obj.components[i]; var tabCompName = tabObj.name; if (strUpperComp.length > 0) tabCompName = strUpperComp + "." + tabCompName; for (var t=0; t<tabObj.components.length; t++) { var compName = tabCompName + "." + tabObj.components[t].name; var tmpArrRet = gf_GetCompFullName(tabObj.components[t], compName); if (tmpArrRet.length > 0) { arrRet = arrRet.concat(tmpArrRet); } //Composite Component 자체도 목록으로 볼 경우 arrRet.push(compName); } //Composite Component 자체도 목록으로 볼 경우 arrRet.push(tabCompName); } else { var compName = obj.components[i].name; if (strUpperComp.length > 0) compName = strUpperComp + "." + compName; arrRet.push(compName); } } return arrRet; } [ 결과 ] uxs (5328): Div01.div_Child.Button00 uxs (5328): Div01.div_Child uxs (5328): Div01 uxs (5328): Div00.Grid00 uxs (5328): Div00
폼에서 사용한 컴포넌트들의 경로를 알수 있나요 Div, Tagpage경우 상위정보를 포함한 경로를 얻고자 합니다.
폼에 함수의 존재유무를 체크하는 방법
마이플랫폼에서 제공하는 IsExistFunc함수를 엑스플랫폼 스크립트로 구현하였습니다.
소스 예) function Button00_onclick(obj:Button, e:ClickEventInfo) { check_function("exist_func"); } function check_function(str_func) { // 존재하지 않는 함수 체크 if(this[str_func] == undefined) { alert("존재안함"); } else { // "exist_func"이 함수 타입인지 체크 if (typeof exist_func == "function"); alert("존재함"); exist_func(); } } function exist_func() { }
XPLATFORM에서 함수유무를 체크할 수 있나요?
팝업 창 사이즈 변경 방법
부모 창에서 팝업창의 사이즈를 변경할 때 ChildFrame 생성 시 ID로 접근하여 사이즈를 변경해야 합니다. 폼의 사이즈를 변경하는 경우 childframe의 내부 폼 사이즈만 변경됩니다.
사용 예) var cfObj = new ChildFrame("cf",0,0,0,0,"Base::smChild.xfdl"); cfObj.showModal(this.getOwnerFrame(),""); cf.position.width=100; cf.position.height=100;
모달로 띄운 팝업 창을 동적으로 리사이징 처리방법을 알고 싶습니다.
팝업창의 사이즈를 변경하면 내부 폼의 사이즈만 변경됩니다.
팝업창으로 오픈된 화면의 사이즈를 변경하는 방법
XPLATFORM을 사용시 팝업창을 띄우고 동적으로 컴포넌트를 생성 후 폼의 사이즈를 조절하고 싶은 경우 자주 묻는 내용에 대해 알아봅니다.
사용 예) // 폼의 onload 에서 사이즈 변경 this.position.height = 100; //this(폼)의 크기를 설정 this.getOwnerFrame().position.height = 100; // this를 감싸고 있는 OwnerFrame(ChildFrame) 의 사이즈도 변경
팝업화면 크기가 변경되지 않습니다. (실제 폼영역은 변경이 되는데 오픈된 폼 사이즈가 변경이 되지 않습니다.)
Composit Component 데이터셋 바인딩 하는 방법
Composit component에 데이터셋을 바인딩하는 방법입니다.
Composit component 연결
별도의 getter, setter와 같은 함수를 composit component쪽에 만들어두고 메인 창에서 호출하는 방법을 사용하시면 유연한 데이터 처리를 할 수 있습니다.
Composit component 측에서 아래와 같이 함수를 만들어 줍니다.
메인 창에서 다음과 같이 호출하여 값을 대입합니다.
composit 컴퍼넌트 바인딩
userForm상속 override
userForm상속받아 override하는 방법입니다.
상속 override
UserForm을 상속받아 자바처럼 override가 가능 합니다. 컴퍼넌트의 이벤트를 override시에는 setHandler를 이용하여 자식창에서 정의한 이벤트를 연결하면되며, 일반 사용자 함수는 자식창에서 부모창과 동일한 이름의 이벤트를 만들어 정의하시면 됩니다.
아래 자식창의 소스 부분입니다.
아래는 부모창의 소스 입니다.
* ChildForm.xfdl <?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="ChildForm" classname="ChildForm" inheritanceid="parentForm" position="absolute 0 0 471 396" titletext="New Form" onload="ChildForm_onload"> <Layouts> <Layout> <Button id="Button01" taborder="0" position="absolute 37 192 152 235" onclick="Button01_onclick" text="부모창변경이벤트"/> <Button id="Button02" taborder="1" text="부모창기본이벤트" position="absolute 38 249 158 299" onclick="Button02_onclick"/> </Layout> </Layouts> <Script type="xscript4.0"><![CDATA[ function Button01_onclick(obj:Button, e:ClickEventInfo) { super.Button00.userdata = "child"; trace(super.Button00.userdata); } function ChildForm_onload(obj:Form, e:LoadEventInfo) { var rtn = super.Button00.onclick.setHandler(1, child_onClick); trace(rtn); } function child_onClick(obj:Button, e:ClickEventInfo){ trace("test / "+super.Button00.userdata); if(super.Button00.userdata == "parent") return; alert("child"); } function Button02_onclick(obj:Button, e:ClickEventInfo) { super.Button00.userdata = "parent"; trace(super.Button00.userdata); } ]]></Script> </Form> </FDL>
* parentForm.xfdl <?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="parentForm" classname="parentForm" inheritanceid="" position="absolute 0 0 394 221" titletext="New Form" onload="parentForm_onload"> <Layouts> <Layout> <Button id="Button00" taborder="0" text="부모창버튼" position="absolute 24 30 250 144" onclick="Button00_onclick" userdata="parent"/> </Layout> </Layouts> <Script type="xscript4.0"><![CDATA[function Button00_onclick(obj:Button, e:ClickEventInfo) { if(Button00.userdata == "child") return; trace(Button00.userdata); alert("parent"); } ]]></Script> </Form> </FDL>
Component Method에 대한 Override 기능문의
상속시 override 가능한지
Script
개행문자
스크립트를 이용한 개행문자 처리방법입니다.
Button04.text = 'ABC' + String.fromCharCode(13) + String.fromCharCode(10) + 'DEF';
마이플랫폼에서 개행문자 처리시 chr(13)+chr(10)를 통해 스크립트 변환이 가능했는데요
XPLATFORM에서는 어떻게 사용하나요?
Grid
XPLATFORM 그리드(Grid)에서 Row Index정보와 컬럼 Index정보 확인방법
그리드를 이용하여 일련번호(Row Index)를 표현할 수 있습니다. 이때 그리드에서 제공되는 메소드 currow를 이용하면 쉽게 구현이 가능합니다.
또한 그리드의 Expr 함수를 구현할 경우 Row의 Index정보로 사용이 가능합니다.
그리드를 이용하여 Expr 함수 구현시 컬럼 Index를 참조하는 경우 self.col 이용하여 컬럼의 Index정보를 구할 수 있습니다.
사용 예) expr:fnExprType(currow) expr:fnExprCol(self.col)
Grid의 autosizingtype=row일 때 한 줄짜리 row의 디자인 시 높이 유지하는 방법
row가 autosizing이 될 때 특정 row에 줄 바꿈 한 데이터가 있는 경우 자동으로 늘어나면 한 줄짜리row는 높이가 줄어드는데 디자인 한 높이를 유지하는 방법.
원인
아래 설정으로 한 row가 줄 바꿈 된 여러 줄일 경우 자동으로 늘어나면서 한 줄짜리 Row인 경우 디자인한 높이를 유지하지 않고 줄어드는 현상이 있음.
autosizingtype=row cellsizingtype=row extendsizingtype=row
해결방법
grid 내부셀의 autosizerow="limitmin"로 설정하면 해당 Cell의 내용의 크기가 최초 디자인된 Cell의 크기보다 작을 때에는 최초 크기를 유지합니다
Grid의 autosizingtype=row일 때 한 줄짜리 row의 디자인 시 높이 유지하는 방법
treegrid에서 레벨1과 레벨2 사이 가로 간격 조정
TreeGrid의 레벨1과 레벨2 사이의 자간과 같이 가로 간격을 띄우는 방법에 대해 알아봅니다.
사용 예)
padding속성에 expr을 걸어서 처리할 수 있습니다. fn_getlvl(lvl) 에서 level 컬럼의 level 정보를 넘겨서 스크립트에서 처리할 수 있습니다.
//스크립트 function fn_getlvl(lvl) { if(lvl==3 || lvl==4) return '0 0 0 100'; } //Style padding 속성 fn_getlvl(lvl)
treegrid에서 레벨1과 레벨2 사이 가로 간격을 띄울 수 있나요?
그리드 ToolTipText표현
주의사항
그리드 속성 중 tooltiptype의 hover를 선택해 주어야 각 Cell이동시 tooltiptext가 변경이 됩니다.
그리드 tooltiptext가 한번은 보여지는데 각 cell 이동시에는 값이 변경되지 않습니다.
그리드의 셀에 class 지정방법 입니다.
그리드의 셀에도 class를 별도로 지정을 할 수가 있습니다.
Css에 셀에 적용되도록 추가합니다.
Grid>#body>Cell.aaa { background : yellow; background2 : pink; }
그리드 컬럼에만 style을 지정할 수 있나여?
TreeGrid 사용 시 text 색상 개별 적용방법
Tree grid에서 내부 속성인 color컬럼을 데이터셋의 색상 컬럼을 만들어서 바인딩하고 항목별로 색상을 지정할 수 있습니다.
각 컬럼 셀마다 색상을 개별로 지정할 수 있습니다.
사용 예)
<?xml version="1.0" encoding="utf-8"?> <FDL version="1.2"> <TypeDefinition url="..\..\default_typedef.xml"/> <Form id="comp_treeview1" classname="comp_treeview1" inheritanceid="" position="absolute 0 0 560 343" titletext="New Form"> <Script type="xscript4.0"><![CDATA[]]></Script> <Layout> <Grid id="Grid05" taborder="0" position="absolute 16 15 168 193" binddataset="ds_bind" autofittype="col" treeusebutton="use" treeuseline="true" treeusecheckbox="false" treeinitstatus="expand,all" dropformat="TEXT,CSV" ondrag="Grid05_ondrag" oncellclick="Grid05_oncellclick" style="linetype:onlyvert;"> <Formats> <Format id="default"> <Columns> <Column size="40"/> </Columns> <Rows> <Row size="24"/> </Rows> <Band id="body"> <Cell displaytype="tree" edittype="tree" style="background:white;background2:white;color:BIND(color);" text="bind:text" treelevel="bind:level"/> </Band> </Format> </Formats> </Grid> <Grid id="Grid00" taborder="1" position="absolute 203 16 546 194" binddataset="ds_bind"> <Formats> <Format id="default"> <Columns> <Col size="80"/> <Col size="80"/> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="level"/> <Cell col="1" disptype="normal" text="text"/> <Cell col="2" disptype="normal" text="color"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:level"/> <Cell col="1" disptype="normal" text="bind:text"/> <Cell col="2" disptype="normal" text="bind:color"/> </Band> </Format> </Formats> </Grid> </Layout> <Objects> <Dataset preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" id="ds_bind"> <ColumnInfo> <Column type="STRING" size="255" id="level"/> <Column type="STRING" size="255" id="text"/> <Column type="STRING" size="256" id="color"/> </ColumnInfo> <Rows> <Row> <Col id="level">0</Col> <Col id="text">a</Col> <Col id="color">#0000ff</Col> </Row> <Row> <Col id="level">1</Col> <Col id="text">b</Col> <Col id="color">#00ff00</Col> </Row> <Row> <Col id="level">2</Col> <Col id="text">c</Col> <Col id="color">#ff0000</Col> </Row> <Row> <Col id="level">0</Col> <Col id="text">d</Col> <Col id="color">#0000ff</Col> </Row> <Row> <Col id="level">0</Col> <Col id="text">e</Col> <Col id="color">#00ff00</Col> </Row> <Row> <Col id="level">1</Col> <Col id="text">f</Col> <Col id="color">#ff0000</Col> </Row> </Rows> </Dataset> </Objects> </Form> </FDL>
treeGrid에서 text의 색상을 개별로 설정하고 싶습니다.
Grid ComboFilter 사용방법
Grid에서 선택combo 값에 따라 다음 콤보 값 및 다른 row의 콤보 값 변경 방법.
첫 번째 콤보 선택 값에 따라 두 번째 콤보의 리스트 값이 변경되어 보여줘야 할 경우 처리하는 방법. Grid의 ondropdown 이벤트에서 데이터셋의 filter로 콤보 값을 보여주고 oncloseup 이벤트에서 콤보 리스트가 닫히는 경우 filter를 풀어줘서 처리합니다.
사용 예) function grd_main_ondropdown(obj:Grid, e:GridEditEventInfo) { ds_dtl.filter( "grp_cd == '" + ds_main.getColumn(e.row,"grp_cd") + "'" ); } function grd_main_oncloseup(obj:Grid, e:GridEditEventInfo) { ds_dtl.filter(""); }
소스 ) <?xml version="1.0" encoding="utf-8"?> <FDL version="1.2"> <TypeDefinition url="..\..\default_TypeDef.xml"/> <Form id="Grid" inheritanceid="" cachelevel="" position="absolute 0 0 800 619" version="" titletext="그리드 콤보필터"> <Layout> <Grid id="grd_main0" taborder="0" binddataset="ds_main0" scrollbars="alwaysvert" cellsizingtype="col" tooltiptype="hover" position="absolute 27 24 758 170"> <Formats> <Format id="default"> <Columns> <Column size="150"/> <Column size="200"/> </Columns> <Rows> <Row size="20" band="head"/> <Row size="20"/> </Rows> <Band id="head"> <Cell displaytype="normal" style="align:center;font:HDCardBold,8,antialias;" text="그룹"/> <Cell col="1" displaytype="normal" style="font:HDCardBold,8,antialias;" text="코드명"/> </Band> <Band id="body"> <Cell displaytype="text" edittype="text" style="align:center;" text="bind:grp_cd" combodisplay="edit"/> <Cell col="1" displaytype="combo" edittype="combo" style="align:center;" text="bind:dtl_cd" combodataset="expr:grp_cd==1?'ds_dtl0':grp_cd==2?'ds_dtl1':'ds_dtl2'" combocodecol="cd" combodatacol="nm"/> </Band> </Format> </Formats> </Grid> <Grid id="grd_main" taborder="1" binddataset="ds_main" scrollbars="alwaysvert" autoenter="select" useinputpanel="false" selecttype="cell" cellsizingtype="col" ondropdown="grd_main_ondropdown" oncloseup="grd_main_oncloseup" position="absolute 27 264 758 380" tooltiptype="hover"> <Formats> <Format id="default"> <Columns> <Column size="150"/> <Column size="200"/> <Column size="200"/> </Columns> <Rows> <Row size="20" band="head" fix="fixed"/> <Row size="20"/> </Rows> <Band id="head"> <Cell displaytype="normal" style="align:center;font:HDCardBold,8,antialias;" text="그룹"/> <Cell col="1" displaytype="normal" style="font:HDCardBold,8,antialias;" text="코드"/> <Cell col="2" displaytype="normal" style="font:HDCardBold,8,antialias;" text="코드명"/> </Band> <Band id="body"> <Cell displaytype="combo" edittype="combo" style="align:center;" text="bind:grp_cd" combodataset="ds_grp" combocodecol="grp_cd" combodatacol="grp_nm" combodisplay="edit"/> <Cell col="1" displaytype="combo" edittype="combo" style="align:center;" text="bind:dtl_cd" combodataset="ds_dtl" combocodecol="cd" combodatacol="cd"/> <Cell col="2" displaytype="combo" edittype="combo" style="align:center;" text="bind:dtl_nm" combodataset="ds_dtl" combocodecol="nm" combodatacol="nm"/> </Band> </Format> </Formats> </Grid> <Grid id="Grid00" taborder="2" binddataset="ds_dtl" useinputpanel="false" selecttype="cell" useselcolor="false" oncelldblclick="Grid00_oncelldblclick" position="absolute 353 392 760 572"> <Formats> <Format id="default"> <Columns> <Column size="80"/> <Column size="80"/> <Column size="80"/> </Columns> <Rows> <Row size="24" band="head"/> <Row size="24"/> </Rows> <Band id="head"> <Cell text="grp_cd"/> <Cell col="1" text="cd"/> <Cell col="2" text="nm"/> </Band> <Band id="body"> <Cell style="background:EXPR(getRowType(currow)==16?"yellow":"");" text="bind:grp_cd"/> <Cell col="1" text="bind:cd"/> <Cell col="2" text="bind:nm"/> </Band> </Format> </Formats> </Grid> </Layout> <Objects> <Dataset id="ds_main0" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="grp_cd" type="STRING" size="256"/> <Column id="dtl_cd" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="grp_cd">1</Col> </Row> <Row> <Col id="grp_cd">2</Col> </Row> <Row> <Col id="grp_cd">3</Col> </Row> </Rows> </Dataset> <Dataset id="ds_dtl0" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="cd" type="STRING" size="256"/> <Column id="nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="cd">1</Col> <Col id="nm">코드1</Col> </Row> <Row> <Col id="cd">2</Col> <Col id="nm">코드2</Col> </Row> </Rows> </Dataset> <Dataset id="ds_dtl1" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="cd" type="STRING" size="256"/> <Column id="nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="cd">3</Col> <Col id="nm">코드3</Col> </Row> <Row> <Col id="cd">4</Col> <Col id="nm">코드4</Col> </Row> </Rows> </Dataset> <Dataset id="ds_dtl2" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="cd" type="STRING" size="256"/> <Column id="nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="cd">5</Col> <Col id="nm">코드5</Col> </Row> <Row> <Col id="cd">6</Col> <Col id="nm">코드6</Col> </Row> </Rows> </Dataset> <Dataset id="ds_dtl" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="grp_cd" type="STRING" size="256"/> <Column id="cd" type="STRING" size="256"/> <Column id="nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="grp_cd">1</Col> <Col id="cd">1</Col> <Col id="nm">코드1</Col> </Row> <Row> <Col id="grp_cd">1</Col> <Col id="cd">2</Col> <Col id="nm">코드2</Col> </Row> <Row> <Col id="grp_cd">2</Col> <Col id="cd">3</Col> <Col id="nm">코드3</Col> </Row> <Row> <Col id="grp_cd">2</Col> <Col id="cd">4</Col> <Col id="nm">코드4</Col> </Row> <Row> <Col id="grp_cd">3</Col> <Col id="cd">5</Col> <Col id="nm">코드5</Col> </Row> <Row> <Col id="grp_cd">3</Col> <Col id="cd">6</Col> <Col id="nm">코드6</Col> </Row> </Rows> </Dataset> <Dataset id="ds_main" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="grp_cd" type="STRING" size="256"/> <Column id="dtl_cd" type="STRING" size="256"/> <Column id="dtl_nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="grp_cd">1</Col> <Col id="dtl_nm">코드1</Col> </Row> <Row> <Col id="grp_cd">2</Col> <Col id="dtl_nm">코드3</Col> </Row> <Row> <Col id="grp_cd">3</Col> <Col id="dtl_nm">코드5</Col> </Row> </Rows> </Dataset> <Dataset id="ds_grp" preload="true" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true"> <ColumnInfo> <Column id="grp_cd" type="STRING" size="256"/> <Column id="grp_nm" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="grp_cd">1</Col> <Col id="grp_nm">1그룹</Col> </Row> <Row> <Col id="grp_cd">2</Col> <Col id="grp_nm">2그룹</Col> </Row> <Row> <Col id="grp_cd">3</Col> <Col id="grp_nm">3그룹</Col> </Row> </Rows> </Dataset> </Objects> <Script type="xscript4.0"><![CDATA[ function grd_main_ondropdown(obj:Grid, e:GridEditEventInfo) { ds_dtl.filter( "grp_cd == '" + ds_main.getColumn(e.row,"grp_cd") + "'" ); } function grd_main_oncloseup(obj:Grid, e:GridEditEventInfo) { ds_dtl.filter(""); } ]]></Script> </Form> </FDL>
그리드 콤보에서 필터하는 방법
Grid combofilter처리 문의
윈도우 탐색기에서 Drop 활용 방법
XPLATFORM 폼 또는 컴포넌트에 윈도우파일탐색기로 파일을 선택하여서 떨어트려서 해당 경로를 이용하는 방법을 설명합니다.
그리드에 해당 경로 파일 가져오는 방법
그리드 속성의 dropformat를 filedrop로 설정합니다.
ondrop이벤트를 추가합니다
소스 예) function Grid00_ondrop(obj:Grid, e:GridDragEventInfo) { var objDataObj = new DragDataObject(); gfn_uploadfile_ondrop(e.dragdata,ds_MFileup); } function gfn_uploadfile_ondrop(objDataObj, objDS) { var arrbuff = objDataObj.getData(DragDataFormats.FILEDROP); var nFileCnt = 1; var strValue= ""; var nRow; var filefath; var nFileCnt = arrbuff.length; for(var i=0; i<nFileCnt; i++) { if(!gfnIsEmpty(arrbuff[i])){ strValue = fnc_getFileName(arrbuff[i]); nRow = objDS.addRow(); objDS.setColumn(nRow, "fullname", arrbuff[i]); objDS.setColumn(nRow, "filename", strValue); } } } function gfnIsEmpty(val) { var sVal = new String(val); val = new String(val); if (val == null || val == "null" || sVal.trim().length <= 0 || escape(val) == "undefined") { return true; } else { return false; } } function fnc_getFileName(strPath){ var i_idx = strPath.lastIndexOf('\\') + 1; var strFileName = ""; if (i_idx > 0) strFileName = strPath.substr(i_idx); trace(strFileName); return strFileName; }
파일을 선택하여서 해당 그리드 위에 떨어 트립니다.
해당 파일 경로를 가져올수 있습니다.
이미지 뷰어 활용
Dropformat을 지정합니다.
이미지 뷰어 컴포넌트에 ondrop 이벤트를 추가 합니다.
function ImageViewer00_ondrop(obj:ImageViewer, e:DragEventInfo) { var objDataObj = new DragDataObject(); var arrbuff = e.dragdata.getData(DragDataFormats.FILEDROP); trace(arrbuff); ImageViewer00.image =arrbuff ; }
파일을 떨어 트려서 이미지를 보여줍니다.
해당 경로의 파일 경로를 가져오는 것입니다.
VirtualFile로 해당 파일 접근시 send box가 나오게 됩니다.
연속으로 파일을 가져올 경우 누적 되는 현상이 나오면 스크립트 끝에 return true;로 처리합니다.
윈도우 탐색기와 연동 방법 문의
drop사용 방법 문의
그리드에 Password(보안) 처리방법
XPLATFORM 그리드에서 주민번호 입력 및 출력시 뒷자리 등을 보호하고 싶을데 처리방법에 대해 알아봅니다.
Mask " {####} "
그리드 Mask에서 {###} 형태로 지정하는 경우 실제 데이타는 정상적으로 들어나, 입력 및 표현시 ***로 변경되어 출력이 됩니다.
소스 예) <?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="gridMask" classname="gridMask" inheritanceid="" position="absolute 0 0 1024 768" titletext="New Form"> <Layouts> <Layout> <Grid id="Grid00" taborder="0" useinputpanel="false" position2="absolute l:35 w:502 t:34 h:174" positiontype="position2" binddataset="Dataset00" formats="<Formats> <Format id="default"> <Columns> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="Column0"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:Column0"/> </Band> </Format> </Formats> "> <Formats> <Format id="default"> <Columns> <Column size="80"/> </Columns> <Rows> <Row size="24" band="head"/> <Row size="24"/> </Rows> <Band id="head"> <Cell text="Column0"/> </Band> <Band id="body"> <Cell edittype="normal" text="bind:Column0" mask="###{###}"/> </Band> </Format> </Formats> </Grid> <Grid id="Grid01" taborder="1" useinputpanel="false" position2="absolute l:36 w:508 t:228 h:235" positiontype="position2" binddataset="Dataset00" formats="<Formats> <Format id="default"> <Columns> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="Column0"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:Column0"/> </Band> </Format> </Formats> "> <Formats> <Format id="default"> <Columns> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="Column0"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:Column0"/> </Band> </Format> </Formats> </Grid> </Layout> </Layouts> <Objects> <Dataset id="Dataset00" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"> <ColumnInfo> <Column id="Column0" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="Column0">123456789</Col> </Row> </Rows> </Dataset> </Objects> </Form> </FDL>
그리드에 주민번호 표현시 *표현 가능한가?
그리드에 drag이벤트시에 스크롤움직일때 drag이벤트 발생 방지
그리드 Drag이벤트 지정시에 그리드위에서 발생하는 모든 drag는 이벤트를 발생시킵니다. 즉, 스크롤을 움직여도 발생하게됩니다. 스크롤시에 drag이벤트 발생방지 하는 방법입니다.
그리드 스크롤시 Drag 이벤트 방지 처리
OnDrag이벤트는 그리드 위에서 스크롤을 잡아 움직여도 발생을 하게 됩니다. 해당 영역은 그리드의 ondrag이벤트에서 GridDragEventInfo의 정보중 col부분을 활용하여 처리하면 됩니다. trace(e.col)로 확인해보면 스크롤 영역은 -1을 리턴하게 되어있습니다. 조건문으로 -1일 경우 return false를 하게되면 이벤트 발생을 하지 않습니다..
그리드 스크롤시 Drag이벤트
Grid 여러줄 표시하기
데이터가 그리드 셀의 길이보다 많이 나올 경우 처리하는 방법입니다
Wordwrap 속성
WordWrap속성은 그리드 셀 길이보다 데이터가 많을 경우 셀 길이만큼씩 줄바꿈을 처리해줍니다.
속성은 그리드 더블 클릭시 셀속성에서 “wordwrap”속성을 확인할 수 있습니다.
다음과 그림을 보면 데이터가 셀보다 길경우 잘리는 현상을 볼 수 있습니다.
WordWrap속성을 지정하면 다음 그림과 같이 여러줄을 볼 수 있습니다.
참고사항
Row를 데이터 길이 만큼만 자동으로 늘어 나게 처리하려면 그리드의 속성을 아래와 같이 지정하세요 autosizingtype=row Extendsizetype =row 위와 같이 지정하면 데이터 row가 데이터만큼 높이들이 지정됩니다.
그리드 컬럼 줄바꾸기
그리드 셀에 blinkCell 메소드 적용방법
그리드 셀에 blinkCell 메소드 적용시 css에도 해당 스타일이 추가가 되어야 합니다.
사용방법
Css에 아래와 같이 추가 합니다.
Grid>#body>Cell:blinked { background : blue; background2 : blue; color : red; color2 : red; selectbackground : blue; selectcolor : red; }
blinkCell 메소드 적용시 반응이 없습니다.
Grid에서 vsscroll을 하단으로 이동시 다음 데이타를 전송하는 방법
XPLATFORM의 그리드의 스크롤을 맨 하단으로 내렸을때 데이타를 조회하고자 하는 경우 해당 이벤트를 얻는방법에 대해 기술힙니다.
Grid onvscroll
Grid의 onvscroll 이벤트의 이벤트 핸들러의 값을 참조하여 분기 처리가능
사용 예) function Grid00_onvscroll(obj:Grid, e:ScrollEventInfo) { if (e.type == "last" || e.type == "trackend") //실제 transaction호출하심 됩니다. }
e : EventObject 속성 (XPLATFORM 도움말 참고 )
그리드 vscroll의 맨 마지막을 구별하는 방법
Grid summary를 상단에 표현하는 방법
XPLATFORM의 Grid에 포현되는 summary를 상단에 표현하는 방법에 대히 개술합니다.
그리드 속성
summarytype : top (Grid에 합계를 나타내는 Summary Band의 위치를 상단에 위치하게 할지 여부를 설정합니다.
Default : default
'default' SummaryBand는 하단에, RightBand는 우측에 표시됩니다.
'top' SummaryBand는 상단에, RightBand는 우측에 표시됩니다.
'left' SummaryBand는 하단에, RightBand는 좌측에 표시됩니다.
'lefttop' SummaryBand는 상단에, RightBand는 좌측에 표시됩니다.
그리드 합계를 상단에 표현하는 방법
그리드의 Cell Position이 변경될때 발생하는 이벤트
XPLATFORM의 그리드에서 Cell이 이동하거나 마우스로 선택되었을때 발생하는 이벤트에 대해 알아봅니다.
onselectchanged 이벤트 사용
사용 예) function Grid00_onselectchanged(obj:Grid, e:GridSelectEventInfo) { trace("Grid00_onselectchanged" + "=>" + e.cell); }
마이플랫폼에서 제공되던 그리드 이벤트 OnCellPosChanged와 같은 이벤트는 무엇인가요?
그리드의 Cell이 변경되었을때 발생하는 이벤트는 무엇인가요?
그리드에 스크롤이 있는 경우 PageUp/PageDown의 이동 갯수를 설정하는 방법
XPLATFORM의 그리드를 사용시 데이타 건수가 많은 경우 스크롤이 발생합니다. 이때 키보드 PageUp/PageDown을 이용하여 페이지 단위로 이동이 가능하게 됩니다. 이 경우 이동하는 갯수를 페이지 단위가 특정 Row건수별로 이동하는 방법에 대해 알아봅니다.
Grid의 onvscroll이벤트 사용 (3 Row씩 이동하는 방법)
소스 예) var nPrePos = -1; function Grid00_onvscroll(obj:Grid, e:ScrollEventInfo) { if(e.type == "pageup") { if(nPrePos == -1) { Grid00.vscrollbar.pos = e.pos + Grid00.pagerowcount - 3; } else { Grid00.vscrollbar.pos = nPrePos - 3; } } else if(e.type == "pagedown") { if(nPrePos == -1) { Grid00.vscrollbar.pos = e.pos + Grid00.pagerowcount - 3; } else { Grid00.vscrollbar.pos = nPrePos + 3; } } else if(e.type == 'none') { if(nPrePos == -1) { Grid00.vscrollbar.pos = 3; } } nPrePos = Grid00.vscrollbar.pos; }
그리드의 PageUp/PageDown 스크롤 이동 갯수를 제어하는 방법
그리드 속성 중 autofittype사용시 주의사항
autofittype 속성을 "col/both/col,allrow"로 지정한 경우 format column size를 기준으로 그리드 넓이에 맞게 열의 크기가 조정되므로 resize나 setRealColSize 메소드 호출을 통한 실제 행의 크기 변경은 불가능합니다. 즉 resize시 비정상동작할 수 있습니다.
해결방안
그리드의 이벤트 oncolresized 이벤트와 onlbuttonup 이벤트를 이용하여 스크립트를 통해 그리드 col 사이즈를 변경할 수 있도록 로직구현을 하셔야 합니다.
var arrNewSize = new Array(); function Grid00_oncolresized(obj:Grid, e:GridSizeChangedEventInfo) { arrNewSize[e.formatindex] = e.newvalue; if(e.formatindex < Grid00.getFormatColCount() - 1) { arrNewSize[e.formatindex + 1] += e.oldvalue - e.newvalue; } Grid00.visible = false; Grid00.autofittype = ""; for(var i = 0; i < Grid00.getFormatColCount(); i++) { Grid00.setFormatColProperty(i, "size", arrNewSize[i]); } Grid00.formats = "<formats>" + Grid00.getCurFormatString() + "</formats>"; Grid00.autofittype = "col"; Grid00.visible = true; } function Grid00_onlbuttonup(obj:Grid, e:GridMouseEventInfo) { for(var i = 0; i < Grid00.getFormatColCount(); i++) { arrNewSize[i] = Grid00.getRealColSize(i); } }
소스
<?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="test" classname="test" inheritanceid="" position="absolute 0 0 506 300" titletext="New Form"> <Layouts> <Layout> <Grid id="Grid00" taborder="0" useinputpanel="false" anchor="all" position="absolute 14 56 422 265" positiontype="position" binddataset="Dataset00" autofittype="col" cellsizingtype="col" autofitminwidth="500" oncolresized="Grid00_oncolresized" onlbuttonup="Grid00_onlbuttonup"> <Formats> <Format id="default"> <Columns> <Col size="80"/> <Col size="80"/> <Col size="80"/> <Col size="80"/> <Col size="80"/> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="Column0"/> <Cell col="1" disptype="normal" text="Column1"/> <Cell col="2" disptype="normal" text="Column2"/> <Cell col="3" disptype="normal" text="Column3"/> <Cell col="4" disptype="normal" text="Column4"/> <Cell col="5" disptype="normal" text="Column5"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:Column0"/> <Cell col="1" disptype="normal" text="bind:Column1"/> <Cell col="2" disptype="normal" text="bind:Column2"/> <Cell col="3" disptype="normal" text="bind:Column3"/> <Cell col="4" disptype="normal" text="bind:Column4"/> <Cell col="5" disptype="normal" text="bind:Column5"/> </Band> </Format> </Formats> </Grid> </Layout> </Layouts> <Objects> <Dataset id="Dataset00" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"> <ColumnInfo> <Column id="Column0" type="STRING" size="256"/> <Column id="Column1" type="STRING" size="256"/> <Column id="Column2" type="STRING" size="256"/> <Column id="Column3" type="STRING" size="256"/> <Column id="Column4" type="STRING" size="256"/> <Column id="Column5" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row/> <Row/> <Row> <Col id="Column1">1</Col> </Row> <Row> <Col id="Column1">1</Col> </Row> </Rows> </Dataset> <Dataset id="Dataset01" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"/> </Objects> <Script type="xscript4.0"><![CDATA[var arrNewSize = new Array(); function Grid00_oncolresized(obj:Grid, e:GridSizeChangedEventInfo) { arrNewSize[e.formatindex] = e.newvalue; if(e.formatindex < Grid00.getFormatColCount() - 1) { arrNewSize[e.formatindex + 1] += e.oldvalue - e.newvalue; } Grid00.visible = false; Grid00.autofittype = ""; for(var i = 0; i < Grid00.getFormatColCount(); i++) { Grid00.setFormatColProperty(i, "size", arrNewSize[i]); } Grid00.formats = "<formats>" + Grid00.getCurFormatString() + "</formats>"; Grid00.autofittype = "col"; Grid00.visible = true; } function Grid00_onlbuttonup(obj:Grid, e:GridMouseEventInfo) { for(var i = 0; i < Grid00.getFormatColCount(); i++) { arrNewSize[i] = Grid00.getRealColSize(i); } } ]]></Script> </Form> </FDL>
Excel(엑셀)
엑셀 sheet의 자리수 제한으로 export 시 주의점
엑셀 sheet의 자릿 수 제한으로 export 시 마이플랫폼에서 sheet의 자리 수를 고려하지 않으면 정상 출력되지 않고 프로세스에 excel 프로세스가 남아있는 경우가 있습니다.
이러한 경우 개발 시 엑셀사양에 대한 확인이 필요하겠습니다.
참고로 excel 2007인 경우 sheet의 최대자리수가 31자입니다.
32자를 스크립트에서 넣어 처리할 경우 위와 같은 문제가 발생하게 됩니다.
엑셀 출력 시 프로세스가 남아있습니다.
엑스플랫폼에서 이미지를 엑셀로 출력하는 방법
엑스플랫폼에서 이미지를 엑셀로 출력하는 방법을 기술합니다.
ExportObject 객체를 이용하여 출력합니다
사용 예) var rtn = ImageViewer00.saveToImage("temp.jpg","JPG",100); //이미지 임시파일로 저장 Grid01.setCellProperty( "Body", 0, "text", "file://"+system.convertRealPath("%DOCUMENT%")+"temp.jpg"); var objExport = new ExportObject(); objExport.exporttype = ExportTypes.EXCEL; objExport.activepagename = 'abc'; objExport.addExportItem(ExportItemTypes.GRID, Grid00, "abc!A1"); objExport.addExportItem(ExportItemTypes.GRID, Grid01,"abc!A6","","","","selectstyle","image","background"); //이미지 출력 objExport.export();
Grid 내용을 엑셀 Export시 image?
엑셀출력 - image
사용자 계정 컨트롤을 가장 높음으로 설정 시 엑셀이 C드라이브에 생성 안됨
현상
사용자 계정 컨트롤을 가장 높음으로 설정 시 엑셀이 C드라이브에 생성 안됨
확인방법
c:\에 기존에 작성된 엑셀파일을 다른 이름으로 저장하면 관리자 권한이 필요하다는 경고창이 나옵니다.
사용자 계정컨트롤을 낮게 설정하면 정상적으로 엑셀파일이 생성됩니다.
Win7에서 엑셀 출력이 안됩니다.
그리드를 export시 엑셀이 실행 되지 않는 경우
MiPlatform에서 그리드를 엑셀로 출력시 엑셀이 실행되지 않는 경우 참고사항입니다.
원인
ExportExcelEx시 인자값으로 SHEET명을 주게 되는데 이때 SHEET명이 31글자 이상 되게 되면 SHEET명이 들어가지 않습니다.
엑셀의 제한사항입니다. ( SHEET명을 31글자 미만으로 지정하시기 바랍니다. )
해당 내용은 MiPlatform/XPLATFORM 모두 해당이 됩니다.
특정 화면에서 엑셀출력이 안됩니다.
Div
Div에서 마우스 상하스크롤 범위지정 방법
Div에 연결된 폼이 있을 경우 상하스크롤을 마우스 휠로 움직일 경우 여러 줄씩 움직일 경우 원하는 범위를 지정하여 움직일 수 있습니다.
Div에서 연결된 폼의 onmousewheel 이벤트에서 스크롤의 범위를 지정해주면 됩니다.
function Grid_Property_treeitemimage_onmousewheel(obj:Form, e:MouseWheelEventInfo) { this.vscrollbar.pos -= e.amount / 3; // <= 조절 범위 임의 지정 return true; }
웹 브라우저 띄울 때 주소 창 생략하는 방법
XPlatform에서 주소 창 없이 웹 페이지의 팝업 띄우는 방법
DataSet
DataSet의 Event사용시 주의사항
DataSet의 이벤트 사용시 event객체에 reason이 있는 경우가 있습니다. reason있는 경우에는 해당 이벤트가 여러번 일어날 수 있으므로 반드시 case에 따른 reason 처리를 해주어야 합니다.
예) 이벤트 onrowsetchanged의 경우 function Dataset00_onrowsetchanged(obj:Dataset, e:DSRowsetChangeEventInfo) { if(e.reason == 40) trace("40==" + e.row); } else if(e.reason == 12) trace("12==" + e.row); } }
function Dataset00_onload(obj:Dataset, e:DSLoadEventInfo) { if(e.reason == 0) //데이타가 다 조회된 경우 이벤트 처리 trace(obj.getRowCount()); } }
DataSet의 이벤트가 여러 번 실행됩니다.
자식창의 Dataset 을 부모창에서 사용하는 방법
this.getOwnerFrame() 이용하여 자식창의 데이터셋에 접근
getOwnerFrame 사용
this.getOwnerFrame().all 를 이용하여 오픈한 자식창의 object 값 확인
자식창 오픈 시 사용했던 아이디값을 이용하여 자식폼의 데이터셋에 접근
사용 예) function Button03_onclick(obj:Button, e:ClickEventInfo) { var arrFramelist = this.getOwnerFrame().all; trace(arrFramelist); trace(arrFramelist.length); trace(arrFramelist["modaless"].form.ds_sub.saveXML()); //modaless 는 오픈시의 id 값 //ds_sub 데이터셋 이름 }
BigDecimal과 Float 컬럼 타입의 범위
BigDecimal, Float 컬럼 타입의 표현 범위 입니다.
BigDecimal 은 일반적으로 얘기하는 Decimal로 보시면 됩니다.
float 는 부동소숫점 형식으로 보시면 됩니다.
BigDecimal
저장하는 방식의 차이인데 decimal 이 유효숫자 자릿수가 더 큽니다. (- ±1.0 × 10E-28 ~ ±7.9 × 10E28 범위와 28-29개의 유효 자릿수를 가져야 한다.)
현재 XP9 에서는 BigDecimal 자료형의 Precision 은 정수부 소수부 합쳐서 32자리 입니다.
자바의 BigDecimal 은 임이의 Precision 을 가질수 있으나 XP는 제품의 사용특성상 성능을
위해서 내부적으로 정해진 Buffer 범위가 존재합니다.
최대숫자는 금융권에서 취급가능한 범위를 고려하였습니다.
예)
BigDecimal amount = new BigDecimal("0.00000009969066466412");
amount = amount.setScale(32, RoundingMode.HALF_UP);
Float
float 는 유효자릿수 17자리입니다. (±4.94065645841246544E-324 ~ ±1.79769313486231570E+308 정도 됩니다.
BigDecimal과 Float 컬럼타입의 범위?
DataSet의 getCaseCount
XPLATFORM의 DataSet의 Row Type별 건수를 확인하는 방법에 대해 기술합니다.
DataSet Sort Method 설명
Method | 간략설명 | Syntax |
---|---|---|
getCaseCount | Dataset에서 지정된 범위안에서 조건식을 만족하는 Row 수를 구하는 Method 입니다. | Dataset.getCaseCount(strCmpExpr[,nStart[,nEnd]]) |
사용 예) trace(Dataset00.getCaseCount('getRowType(rowidx)==1')); trace(Dataset00.getCaseCount('getRowType(rowidx)==4')); //Dataset.ROWTYPE_EMPTY 0 존재하지 않는 Row 상태 //Dataset.ROWTYPE_NORMAL 1 초기 Row 상태 //Dataset.ROWTYPE_INSERT 2 추가된 Row 상태 //Dataset.ROWTYPE_UPDATE 4 수정된 Row 상태 //Dataset.ROWTYPE_DELETE 8 삭제된 Row 상태 //Dataset.ROWTYPE_GROUP 16 Group 정보 Row 상태 * rowidx 에 대한 설명은 XPLATFORM Help(Reference Guide) Appendix->Dataset Expression을 참고하세요
DataSet의 getCaseCount를 이용한 Row Type별 건수 구하기
DataSet의 Filter(like) 사용방법
XPLATFORM의 DataSet 정보를 이용하여 Filter를 통해 원하는 값 정보를 추출할 수 있습니다. 이때 SQL문의 Like기능을 구현하는 방법에 대해 기술합니다.
function btn_execute0_onclick(obj:Button, e:ClickEventInfo) { ds_data.filter("String(COL0).indexOf('" + (edt_input.value).replace("'","\\'") + "') >= 0"); }
<?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="Comp_Dataset_SearchFilter" classname="Script_String_HalfToFull" inheritanceid="" position="absolute 0 0 800 600" titletext="Comp_Dataset_SearchFilter"> <Layouts> <Layout> <Grid id="grd_output" taborder="1" binddataset="ds_data" position="absolute 94 90 426 310" formats="<Formats> <Format id="default"> <Columns> <Col size="80"/> <Col size="80"/> <Col size="80"/> <Col size="80"/> <Col size="80"/> </Columns> <Rows> <Row band="head" size="24"/> <Row band="body" size="24"/> </Rows> <Band id="head"> <Cell col="0" disptype="normal" text="COL1"/> <Cell col="1" disptype="normal" text="COL2"/> <Cell col="2" disptype="normal" text="COL3"/> <Cell col="3" disptype="normal" text="COL4"/> <Cell col="4" disptype="normal" text="COL5"/> </Band> <Band id="body"> <Cell col="0" disptype="normal" text="bind:COL1"/> <Cell col="1" disptype="normal" text="bind:COL2"/> <Cell col="2" disptype="normal" text="bind:COL3"/> <Cell col="3" disptype="normal" text="bind:COL4"/> <Cell col="4" disptype="normal" text="bind:COL5"/> </Band> </Format> </Formats> " autofittype="col"> <Formats> <Format id="default"> <Columns> <Column size="150"/> </Columns> <Rows> <Row size="24" band="head"/> <Row size="24"/> </Rows> <Band id="head"> <Cell text="COL0"/> </Band> <Band id="body"> <Cell text="bind:COL0"/> </Band> </Format> </Formats> </Grid> <Static id="Static00" text="input" position2="absolute l:50 w:37 t:50 h:30" positiontype="position2"/> <Edit id="edt_input" taborder="1" autoselect="true" autoskip="true" position2="absolute l:94 w:140 t:50 h:30" positiontype="position2" value="Look"/> <Button id="btn_execute0" taborder="1" text="like filter" onclick="btn_execute0_onclick" position2="absolute l:242 w:90 t:50 h:30" positiontype="position2"/> <Static id="Static01" text="output" position2="absolute l:50 w:37 t:88 h:30" positiontype="position2"/> <Button id="btn_execute1" taborder="1" text="unfilter" onclick="btn_execute1_onclick" position2="absolute l:339 w:90 t:50 h:30" positiontype="position2"/> </Layout> </Layouts> <Objects> <Dataset id="ds_data" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"> <ColumnInfo> <Column id="COL0" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="COL0">Please Look After Mon</Col> </Row> <Row> <Col id="COL0">Steve Jobs hardback</Col> </Row> <Row> <Col id="COL0">The "Help</Col> </Row> <Row> <Col id="COL0">Game of Thrones Boxed Set</Col> </Row> <Row> <Col id="COL0">THE GIVER</Col> </Row> <Row> <Col id="COL0">The Hunger Games</Col> </Row> <Row> <Col id="COL0">TALES OF A FOURTH GRADE NOTHING</Col> </Row> <Row> <Col id="COL0">The Twilight Saga</Col> </Row> <Row> <Col id="COL0">Eat, Pray, Love</Col> </Row> <Row> <Col id="COL0">Harry Potter and the Deathly Hallows</Col> </Row> <Row> <Col id="COL0">No Talking</Col> </Row> <Row> <Col id="COL0">The Wednesday Wars</Col> </Row> <Row> <Col id="COL0">The Kite Runner</Col> </Row> <Row> <Col id="COL0">Charlie and the Chocolate Factory</Col> </Row> <Row> <Col id="COL0">Dead Poet's Society</Col> </Row> <Row> <Col id="COL0">High School Musical</Col> </Row> <Row> <Col id="COL0">PRIDE AND PRE JUDICE</Col> </Row> <Row> <Col id="COL0">WHEN MY NAME WAS KEOKO</Col> </Row> <Row> <Col id="COL0">The Notebook</Col> </Row> <Row> <Col id="COL0">Old Man and the Sea</Col> </Row> </Rows> </Dataset> </Objects> <Script type="xscript4.0"><![CDATA[/* * File Name : Comp_Dataset_SearchFilter * Discription : Dataset Filter사용시 like%기능 처리하기 */ function btn_execute0_onclick(obj:Button, e:ClickEventInfo) { ds_data.filter("String(COL0).indexOf('" + (edt_input.value).replace("'","\\'") + "') >= 0"); } function btn_execute1_onclick(obj:Button, e:ClickEventInfo) { ds_data.filter(""); } ]]></Script> </Form> </FDL>
검색시 '처리를 위해 \\'값을 변환하는 과정을 처리하였습니다.
Button
버튼에 이미지 적용시 이미지 좌우간격 지정
버튼의 좌측에 이미지 적용시 좌우 4픽셀씩 고정여백을 지정하는 방법입니다.
사용 예) Css에 아래와 같이 추가 합니다. Button.test { background : yellow; border : 0 none transparent; bordertype : normal 0 0; color : red; image : URL('IMG::btn_NextO.png'); imagealign : left middle; imagepadding : 0 0 0 -8; padding : 0 0 0 12; }
버튼에 이미지 적용시 고정여백을 지정하고 싶습니다.
Radio
Radio Contents
Radio 컴퍼넌트 데이터셋 없이 사용하는 방법입니다.
Radio contents 사용방법
Radio Component에 데이터셋 없이 사용이 가능합니다.
Radio 속성창에서 innerdataset 부분에 보시면 데이터셋 선택할 수 있는 콤보버튼과 “…”버튼이 있습니다.
“…” 버튼을 선택 하면 다음과 같은 화면이 뜹니다.
위에서 데이터셋 사용과 같이 row를 추가하고 추가된 row에 값을 아래와 같이 대입합니다.
그리고 확인 버튼을 누르면 데이터셋이 바인딩된 것처럼 사용할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="tip_combo" classname="tip_combo" inheritanceid="" position="absolute 0 0 442 182" titletext="New Form"> <Layouts> <Layout> <Radio id="Radio00" taborder="0" position="absolute 24 30 304 80" codecolumn="codecolumn" datacolumn="datacolumn"> <Dataset id="innerdataset"> <ColumnInfo> <Column id="codecolumn" size="256"/> <Column id="datacolumn" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="codecolumn">0</Col> <Col id="datacolumn">테스트1</Col> </Row> <Row> <Col id="codecolumn">1</Col> <Col id="datacolumn">테스트2</Col> </Row> </Rows> </Dataset> </Radio> </Layout> </Layouts> </Form> </FDL>
Radio만드는 법
Radio 글자 색상
Radio 컴퍼넌트의 item별 색상 지정 하는 방법입니다
Radio 컴퍼넌트의 item별 색상 지정
Radio에 연결할 innerdataset에 색상 컬럼을 추가하여 연결하면 item별로 색상이 지정가능 합니다.
아래와 같이 Raido 속성의 color 부분에 위에서 만든 컬럼을 바인딩하면 됩니다.
소스 예) <?xml version="1.0" encoding="utf-8"?> <FDL version="1.2"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="radio" classname="radio" inheritanceid="" position="absolute 0 0 1024 768" titletext="New Form"> <Layout> <Radio id="Radio01" taborder="1" innerdataset="@Dataset00" codecolumn="Column0" datacolumn="Column1" direction="vertical" onitemclick="Radio00_onitemclick" position="absolute 53 75 635 165" rowcount="2" style="color:BIND(color);"/> </Layout> <Objects> <Dataset id="Dataset00" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"> <ColumnInfo> <Column id="Column0" type="STRING" size="256"/> <Column id="Column1" type="STRING" size="256"/> <Column id="color" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="Column0">전체</Col> <Col id="Column1">전체</Col> <Col id="color">red</Col> </Row> <Row> <Col id="Column0">가나다라</Col> <Col id="Column1">가나다라</Col> <Col id="color">yellow</Col> </Row> <Row> <Col id="Column0">가나다라</Col> <Col id="Column1">가나다라</Col> <Col id="color">blue</Col> </Row> <Row> <Col id="Column1">2</Col> <Col id="Column0">2</Col> <Col id="color">black</Col> </Row> <Row> <Col id="Column0">3</Col> <Col id="Column1">3</Col> <Col id="color">white</Col> </Row> <Row> <Col id="Column1">4</Col> <Col id="Column0">4</Col> <Col id="color">green</Col> </Row> </Rows> </Dataset> </Objects> <Script type="xscript4.0"><![CDATA[ function Radio00_onitemclick(obj:Radio, e:RadioMouseEventInfo) { } ]]></Script> </Form> </FDL>
라디오 컴포넌트에 데이터셋의 데이터별로 색을 지정할 수 있나요?
Radio InnerDataSet 접근방법
Radio컴포넌트의 경우 InnerDataSet 속성을 통해 codecolumn, datacolumn을 개발시 세팅이 가능합니다. 이후 조건에 따라 개발시 세팅된 정보에 대해 수정 또는 추가를 하고자 하는 경우 접근방법입니다.
스크립트를 이용한 접근방법
접슨방법 Radio.innerdataset.insertRow() 처럼 dataset접근을 할 수 있습니다.
Radio00.innerdataset.insertRow(0); Radio00.innerdataset.setColumn(0,"codecolumn",'code값'); Radio00.innerdataset.setColumn(0,"datacolumn","data값"); trace(Radio00.innerdataset.saveXML());
Radio의 innerdataset을 스크립트로 제어(변경)할 수 있나요?
Radio의 Item의 길이에 따라 size변경 방법
Radio item의 text 길이에 따라 가변 size를 설정하는 기능이 없었습니다. 따라서 item의 최대 길이에 따라 영역이 설정되었는데 이에 대한 해결방법이 추가되었습니다.
처리방법
1. columncount와 rowcount의 값이 모두 -1로 설정 한 경우, Radio의 사이즈에 따라 text의 길이에 맞게 자동정렬하는 기능이 추가되었습니다. 2. columncount의 Default값이 -1에서 0으로 변경되었습니다. 3. rowcount의 Default값이 -1에서 0으로 변경되었습니다.
적용버전
20121127(9.2.0.130)
ImageViewer
ImageViewer를 이용하여 이미지 표현시 URL로 링크된 파일이 실제 서버에 존재하는지 체크할 수 있는 방법
ImageViewer에 연결된 URL경로에 대한 파일존재 여부는 체크할 수 없습니다. 만약 파일이 없는 경우 디폴트 이미지로 표현을 하고자 한다면 서비스(jsp,java,asp)등을 만들어 파일을 체크할 수 있는 로직을 구현해야 합니다.
Jsp 소스 예)
<%@ page contentType="application; charset=MS949"%> <%@ page language="java" import="java.util.*,java.io.*" %><% String filename = ""; String filepath = "C:\\TEMP\\"; String filegubun = ""; int intTemp = 0; try{ filename = request.getParameter("filename"); //filegubun = request.getParameter("filepath"); filepath = filepath + filename; File file = new File(filepath); byte b[] = new byte[4096]; response.setHeader("Content-Disposition", "attachment;filename=" + filename + ";"); if (file.isFile()) { BufferedInputStream fin = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream outs = new BufferedOutputStream(response.getOutputStream()); int read = 0; try { while ((read = fin.read(b)) != -1){ outs.write(b,0,read); } outs.close(); fin.close(); } catch (Exception e) { } finally { if(outs!=null) outs.close(); if(fin!=null) fin.close(); } } else { filepath = "C:\\TEMP\\" + "default.jpg"; //디폴트 이미지를 표현 File file2 = new File(filepath); BufferedInputStream fin = new BufferedInputStream(new FileInputStream(file2)); BufferedOutputStream outs = new BufferedOutputStream(response.getOutputStream()); int read = 0; try { while ((read = fin.read(b)) != -1){ outs.write(b,0,read); } outs.close(); fin.close(); } catch (Exception e) { } finally { if(outs!=null) outs.close(); if(fin!=null) fin.close(); } } }catch (Exception e){ }finally{ } %>
화면 스크립트 코딩 예)
ImageViewer00.image = "URL('http://localhost:8080/MiAPI/ImageCheck.jsp?filename=aa.jgp')";
ImageViewer에 연결된 이미지경로에 파일이 존재하는지 체크할 수 있나요?
Tab
우측 마우스로 선택된 탭 버튼 삭제
Tab 컴퍼넌트에서 우측 마우스로 선택된 탭 버튼 삭제하는 방법입니다
Tab에서 우측마우스로 좌표 받아 삭제 할 수 있습니다.
우측 마우스 이용하여 popupMenu를 좌표값에 따라 나타나게 합니다
좌표값을 받는 방법은 system.clientToScreenX(obj, e.clientX); 와 같이 화면에서 컴퍼넌트의 위치를 받아온뒤 컴퍼넌트에서 클릭된 좌표를 받아 처리를 하면 됩니다. 그리고 탭에서 우측 마우스 클릭시에는 선택된 탭버튼이 활성화가 되지 않으므로 바로 삭제를 하게되면 펼처진 탭이 삭제 됩니다.
선택된 탭버튼의 index를 받기 위해서 Tab00.getIndex(e.clientX, e.clientY) 와 같이 좌표를 이용해 받아 처리하면 됩니다
사용 예)
소스 예) <?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\default_typedef.xml"/> <Form id="N124381" classname="N124381" inheritanceid="" position="absolute 0 0 634 332" titletext="New Form"> <Layouts> <Layout> <Tab id="Tab00" taborder="0" tabindex="0" scrollbars="autoboth" position="absolute 24 16 597 304" onrbuttondown="Tab00_onrbuttondown"> <Tabpages> <Tabpage id="tabpage1" text="tabpage1"/> <Tabpage id="tabpage2" text="tabpage2"/> <Tabpage id="tabpage3" text="tabpage3"/> <Tabpage id="tabpage4" text="tabpage4"/> </Tabpages> </Tab> <PopupMenu id="PopupMenu00" position="absolute 168 46 356 230" innerdataset="@Dataset00" captioncolumn="Column1" levelcolumn="Column0" idcolumn="Column2" onmenuclick="PopupMenu00_onmenuclick"/> </Layout> </Layouts> <Objects> <Dataset id="Dataset00" firefirstcount="0" firenextcount="0" useclientlayout="false" updatecontrol="true" enableevent="true" loadkeymode="keep" loadfiltermode="keep" reversesubsum="false"> <ColumnInfo> <Column id="Column0" type="STRING" size="256"/> <Column id="Column1" type="STRING" size="256"/> <Column id="Column2" type="STRING" size="256"/> </ColumnInfo> <Rows> <Row> <Col id="Column0">0</Col> <Col id="Column1">삭제</Col> <Col id="Column2">0</Col> </Row> </Rows> </Dataset> </Objects> <Script type="xscript4.0"><![CDATA[ function Tab00_onrbuttondown(obj:Tab, e:TabMouseEventInfo) { var nX = system.clientToScreenX(obj, e.clientX); var nY = system.clientToScreenY(obj, e.clientY); trace(nX + " / "+ nY); PopupMenu00.trackPopup(nX, nY); } function PopupMenu00_onmenuclick(obj:PopupMenu, e:MenuClickEventInfo) { if(e.id == 0){ Tab00.removeTabpage(Tab00.getIndex(e.clientX, e.clientY)); } } ]]></Script> </Form> </FDL>
onRbutton 이벤트에서 현재 눌린 버튼의 인덱스 가져오는 방법
TabPage를 마우스로 선택하여 이동하는 방법
Tab의 ondrag이벤트를 이용하여 TabPage를 이동하는 샘플입니다.
소스
<?xml version="1.0" encoding="utf-8"?> <FDL version="1.4"> <TypeDefinition url="..\..\default_typedef.xml"/> <Form id="TabTilteDragChange" classname="TabTilteDragChange" inheritanceid="" position="absolute 0 0 1024 768" titletext="New Form" ondrop="TabTilteDragChange_ondrop"> <Layouts> <Layout> <Tab id="Tab00" taborder="3" tabindex="0" scrollbars="autoboth" position="absolute 16 37 589 263" dropformat="UNICODETEXT,TEXT,CSV,FILEDROP" dragscrolltype="none" ondrag="Tab00_ondrag"> <Tabpages> <Tabpage id="tabpage1" text="tabpage1"/> <Tabpage id="tabpage2" text="tabpage2"/> <Tabpage id="tabpage3" text="tabpage3"/> <Tabpage id="tabpage4" text="tabpage4"/> <Tabpage id="tabpage5" text="tabpage5"/> </Tabpages> </Tab> <ImageViewer id="imgDrag" taborder="4" visible="false" position="absolute 663 54 816 80" style="background:@gradation;border:1px solid #697070ff ;color:#f24a00ff;bordertype:round 5 5 lefttop righttop;font:Viner Hand ITC,16,antialias;gradation:linear 0,0 #ffffffb3 0,100 #ffffff00;"/> </Layout> </Layouts> <Script type="xscript4.0"><![CDATA[function Tab00_ondrag(obj:Tab, e:DragEventInfo) { var nDragIdx = Tab00.getIndex(e.canvasX, e.canvasY); var strTitle = Tab00.tabpages[nDragIdx].text e.dragdata = new DragDataObject() ; e.dragdata.setData(DragDataFormats.TEXT, nDragIdx); imgDrag.text = strTitle; var objFont = new Font(); var objFontOrg = Tab00.currentstyle.font; var strFontType = new String(objFontOrg.type + ""); objFont.size = objFontOrg.size; objFont.name = objFontOrg.face; objFont.antialias = strFontType.indexOf("antialias") >= 0 ? true : false; objFont.bold = strFontType.indexOf("bold") >= 0 ? true : false; objFont.italic = strFontType.indexOf("italic") >= 0 ? true : false; objFont.strike = strFontType.indexOf("strike") >= 0 ? true : false; objFont.underline = strFontType.indexOf("underline") >= 0 ? true : false; imgDrag.font = Tab00.currentstyle.font; var objPainter = imgDrag.canvas.getPainter(); var objSize = objPainter.getTextSize(strTitle, objFont); imgDrag.position.width = objSize.cx + Tab00.currentstyle.buttonpadding.left + Tab00.currentstyle.buttonpadding.right; imgDrag.position.height = objSize.cy + Tab00.currentstyle.buttonpadding.top + Tab00.currentstyle.buttonpadding.bottom; e.dragimage = imgDrag.saveToImageObject(); return true; } function TabTilteDragChange_ondrop(obj:Form, e:DragEventInfo) { if(e.fromobject == Tab00) { var nDragIdx = e.dragdata.getData(DragDataFormats.TEXT); var nDropIdx = Tab00.getIndex(e.canvasX - Tab00.position.x, e.canvasY - Tab00.position.y); Tab00.moveTabpage(nDragIdx, nDropIdx); } } ]]></Script> </Form> </FDL>
File/Down,Up
파일업로드/다운로드 기능 구현시 발생될 수 있는 문제점들에 관한 처리 방법과 사용방법을 정리한 문서입니다.
아래 링크파일을 클릭하여 관련문서를 다운로드 할 수 있습니다.
FileDownload 객체 동적 사용방법
사용 예)
var FileDownload00 = new FileDownload(); FileDownload00.init("FileDownload00", 100, 100, 400 ,500); var strFileName = ds_uploadresult.getColumn(0,"fileName"); FileDownload00.downloadfilename = strFileName; FileDownload00.downloadurl=http://xxx.xxx.xxx.xxx/cs/fileDownload.jsp?file="+strFileName; this.addChild("FileDownload00", FileDownload00); FileDownload00.show(); var bSucc = FileDownload00.download();
FileDownload 객체 동성 생성 사용방법을 알고 싶습니다.
FileDownload 객체 동성 생성 시 화면이 꺼져버립니다.
ActiveX
OCX 등록 및 사용 방법 및 주의 할점
엑스플랫폼에서 외부 OCX(ActiveX)를 사용하는 방법 및 주의사항을 기술합니다.
UxSutio에서 OCX컴포넌트 생성 후 CLSID아이디 지정
ocx컴포넌트 폼에 디자인 후 progid를 지정합니다.
동적생성방법
var objActiveX = new ActiveX로 생성하여서 사용합니다.
소스 예) var objActiveX = new ActiveX("SActiveX1", 10, 10, 800, 800); this.addChild("SActiveX1", objActiveX); objActiveX.progid="shell.explorer.2"; objActiveX.show(); objActiveX.Navigate2(http://www.tobesoft.com);
주의사항
ActiveX 속성의windowed, popupstyle, adjustalpha에 따라서 구동이 틀려 집니다.
Windowed =true; 설정하지 않으면 mid폼 구조에서 정상 작동하지 않습니다.
단 해당 ActiveX가 Windowed를 지원해야합니다.
팝업에서 사용시 popupstyle= true; 설정하지 않으면 정상 구동하지 않을 수 있습니다.
팝업을 layered =true로 설정시 해당 해당 ActiveX에 따라서 구동하지 않을 수 있습니다.
ActiveX 호출 후 폼을 정상적으로 닫지 않을 경우 ActiveX가 남아 있게 됩니다.
정상 설치가 안된 ActiveX를 호출 및 로딩을 하게 되면 비정상 종료가 발생합니다.
ActiveX위에 버튼 및 기타 컴포넌트를 올릴수 없습니다.
ActiveX가 웹 전용일 경우 정상 작동하지 않습니다.
OCX등록방법
퀵뷰로는 나오는데 화면에 나오지 않습니다.
화면에 나온뒤에 사라지지 않습니다.
OCX등록화면을 열면 비정상 종료가 발생합니다.
팝업에서는 나오지 않습니다.
MSIE(웹브라우저)
MSIE에 페이지 호출시 스크롤 제어방법입니다.
MSIE에 페이지 호출시 웹페이지의 사이즈에 상관없이 무조건 스크롤이 자동으로 생기게 되는데(비활성화 형태)
이때 스크롤이 나오지 않도록 처리할 수 있습니다.
MSIE의 DocumentComplet 이벤트에서(페이지 로딩이 완료된 시점) 아래와 같이 스크롤을 제어할 수 있습니다.
사용 예) function ActiveX00_DocumentComplete(obj:ActiveX, e) { var objDom = obj.Document.body; objDom.scroll = 'no'; //msie의 속성을 지정하는 scrollbar }
MSIE의 스크롤을 없앨 수 있나요?
MSIE에 값 셋팅 방법
스크립트에서 HTML 내용을 만들어 웹페이지로 MSIE에 보여주는 방법 입니다.
스크립트로 HTML 문자열을 만든 후 innerHtml을 이용하여 적용할 수 있습니다.
사용 예) function Form_onload(obj:Form, e:LoadEventInfo) { ActiveX00.Navigate2("about:blank"); } function ActiveX00_DocumentComplete(obj:ActiveX, e) { ActiveX00.Document.body.innerHTML= "<html><body>출력하고자 하는 내용 기술</body></html>"; }
MSIE에 HTML문자열을 적용할 수 있나요?
internet Explorer 폼 밖으로 띄울 때 주소 창 없이 띄우는 방법
ie창을 띄우는 경우 주소 창 및 메뉴 등을 없애고 띄우는 방법입니다.
설정방법
XPlatform 툴바에서 ActiveX를 선택하여 폼 위에 그린 후 속성인 progid를 클릭하면 아래의 창이 뜨고 Microsoft Web Browser를 선택하고 Insert 버튼을 누릅니다.
아래 소스와 같이 옵션에 0을 설정하면 ie창에서 보이지 않습니다. MSIE0.Navigate("about:blank"); MSIE0.Navigate("javascript:window.open('http://daum.net','popup','width=1024px,height=768px,top=0,left=0,menubar=0,toolbar=0,location=0,directories=0,status=01,status=no,scrollbars=no')");
웹 브라우저 띄울 때 주소 창 생략하는 방법
XPlatform에서 주소 창 없이 웹 페이지의 팝업 띄우는 방법
MSIE에 호출된 화면의 항목 제어방법
MSIE(shell.explorer)에 웹페이지를 호출 하였을 경우 웹페이지의 항목을 제어하고자 하는 경우 제어 방법입니다.
사용방법
MiPlatform
var objDocument = AxMSIE.Document; var objHtmlElementCollection = objDocument.All(); var Item0; Item0 = objHtmlElementCollection.item("pasteBtn"); Item0.value = ds_CONT.GetColumn(0,"CONT"); Item0.Click();
XPLATFORM
XPLATFORM 에서는 제어방식을 아래와 같이 하셔야 합니다.
웹사이트에서 버튼이 동작 되지 않는 경우 대부분 Javascript의 객체를 MSDOM에서 사용하는
document.all을 사용하기 때문에 그렇습니다.
var objDocument = msIE.Document; var objHtmlElementCollection = objDocument.getElementById("pasteBtn"); objHtmlElementCollection.value = ds_CONT.GetColumn(0,"CONT"); objHtmlElementCollection.Click();
MSIE을 이용한 POST 전송 방법
MSIE에서 데이터 전송시 get방식이 아닌 post 전송 방법입니다.
소스 예) var JSESSIONID = "123456789"; var Headers = "Content-Type: application/x-www-form-urlencoded\r\n"; var objBuffer = new Buffer("JSESSIONID=" + JSESSIONID+"&arg1=tobesoft"); //"_new" 등으로 IE 브라우져로 띄우면 유지안됨 ActiveX00.Navigate2("http://localhost:8078/keris/JTest.jsp", "", "_self", objBuffer.data, Headers);
주의사항
"_new" 등으로 IE 브라우져로 띄우면 유지안됨
Msie post로 데이터값 넘기는 방법
MSIE 스크립트 실행방법
MS InternetExplorer 11버전 이상에서 함수 호출방법이 변경에 따른 실행방법입니다.
ExtCommonApi를 이용하여 InternetExplorer 버전체크 및 실행방법은 아래 소스를 참고하세요.
var objExt = new ExtCommon(); IE_Gbn = objExt.regGetValue("HKEY_LOCAL_MACHINE", "SOFTWARE\\Microsoft\\Internet Explorer\\", "Version", "S"); IE_Gbn = IE_Gbn.substr(0,1); //설치된 IE 버전별로 분기처리 함. IE버전이 9보다 작을 경우 //IE버전이 9 이상일 경우 if( IE_Gbn < 9 ) objDoc.parentWindow.execScript("callXp('" + encodeURI( v_inVal ) + "')", "JavaScript"); else objDoc.parentWindow.callXp(encodeURI( v_inVal ));
execScript가 IE11이상에서 적용안됨
직접 함수호출을 할 수 있으나 IE9이전 버전에서는 execScript만 사용이 가능하여
버전별 체크를 통해 소스구현
ActiveX에 포함되어 있는 Obj정보와 Event값을 확인하는 방법
ActiveX를 사용하는 경우 Object에 포함된 속성 및 Event(이벤트에) 속성을 확인해야 하는 경우 있습니다. XPLATFORM에서는 기본적으로 ActiveX에 대한 값을 표현해 주지 않기 때문에 해당 ActiveX의 메뉴얼을 참조해서 사용해야 하는데 이 불편함을 아래와 같이 확인이 가능합니다.
function ActiveX00_BeforeNavigate2(obj:ActiveX, e) { var x, y; for (x in obj) { trace(x + " : " + obj[x]); } for (y in e) { trace(y + " : " + e[y]); } }
ActiveX를 사용하려고 하는데 이벤트 사용시 obj, e에 포함된 값을 확인할 수 있나요?
ExtCommon
Xplatform Extcomon API 사용방법
UXSTUDIO에서 기본 제공되는 API외에 추가 확장 컴포넌트를 등록하는 방법 입니다. 본 내용은 ExtCommon API DLL파일을 추가하는 방법 입니다.
UXSTUDIO 추가 방법
TypeDefinition에서 bin컴포넌트를 아무거나 하나 추가합니다.
추가후 해당 bin컴포넌트 ID, ClassName, Module이름을 ExtCommond으로 변경합니다.
Extcomon.dll을 UXSTUDIO가 설치된 폴더에 복사합니다
사용방법
사용 예) //ExtCommon 선언 후 호출하여서 사용합니다. var objExtCommon = new ExtCommon(); var sUserIP = objExtCommon.getIPAddress(); alert(objExtCommon.getIPAddress
최신 Extcomon 다운로드 방법
고객지원센터 홈페이지 에서 다운로드 가능합니다. www.miplatform.co.kr -> support -> Xplatform -> tip
Extcomon이 로딩이 안될경우 해당 경로에 파일 있는지 확인합니다.
2012년 Xplatform의 경우 Extcomon 버전도 2012년으로 사용 해야합니다.
Extcomon 매뉴얼의 경우 다운 받으시는 zip속에 있습니다.
ExtCommon파일은 투비소프트 기술지원 홈페이지(XPLATFORM-TIP게시판)을 통해
다운로드 및 최신파일을 받으실 수 있습니다.
해당 파일은 개발시 XPLATFORM 엔진폴더에 복사해 주어야 하며,
배포(운영)시에는 컴포넌트 폴더에 파일이 존재해야 합니다.
ExtCommon을 어떻게 추가하나요?
Extcomon 사용방법 문의
Extcommon API중 자주묻는 질문
ext_OleServerBusyTimeout :사용하는 이유
사용하고자 하는 ActiveX 컨트롤또는 DCOM 클라이언트가 어떤 이유로 인해 응답하지 못하고 있는 상태일 때 사용.(다음과 같은 이유에서 발생할 수 있습니다.) 1. ActiveX 컨트롤이 초기화되기 전에 클라이언트 애플리케이션이 이를 사용하려고 시도할 때 2. 시스템이 느리거나 동시에 많은 애플리케이션이 동작 중이어서 ActiveX 컨트롤이 응답하지 못하는 경우 3. ActiveX 컨트롤의 설계에 문제가 있어서 응답이 늦도록 제작되어 있을 때