부록 A.컴포지트 컴포넌트 샘플

Edit

넥사크로 모듈 디벨로퍼는 "베타" 버전입니다.

- "베타" 기간 동안 일부 제품 기능은 변경될 수 있습니다.

- 온라인 매뉴얼 URL은 변경될 수 있습니다.

- 가이드에서 사용한 샘플 코드는 아래 링크에서 내려받을 수 있습니다.

https://github.com/TOBESOFT-DOCS/SIMPLE_MODULE_PROJECT/archive/master.zip

https://github.com/TOBESOFT-DOCS/SIMPLE_MODULE_PROJECT

넥사크로 모듈 디벨로퍼에서 작성된 컴포지트 컴포넌트 샘플을 소개합니다. 샘플로 작성된 코드이며, 코드의 적합성을 검증하지는 않았습니다.

A.1우편번호 검색

Daum에서 제공하는 우편번호 검색 API를 사용한 예제입니다. 검색된 결과값을 Edit 컴포넌트에 입력합니다.

우편번호 검색 API에 대해서는 아래 링크를 참고하세요.

http://postcode.map.daum.net/guide

1

컴포지트 컴포넌트의 화면을 아래와 같이 구성합니다.


컴포넌트

id

기타 속성

1

Edit

editPostcode

displaynulltext: 우편번호

readonly: true

2

Edit

editAddress

displaynulltext: 도로명주소

readonly: true

3

Edit

editDetailAddress

displaynulltext: 상세주소

4

Button

btnFindPostcode

text: 우편번호 찾기

2

Class Definition 탭에서 생성자 코드를 아래와 같이 수정합니다.

간단하게 샘플을 구현하기 위해 NRE에서의 실행은 구현하지 않았습니다. 생성자가 호출되면서 필요한 API 스크립트를 처리할 수 있도록 합니다.

nexacro.DaumPostCode = function (id, left, top, width, height, right, bottom, minwidth, maxwidth, minheight, maxheight, parent)
{
    nexacro._CompositeComponent.call(this, id, left, top, width, height, right, bottom, minwidth, maxwidth, minheight, maxheight, parent);
    if(system.navigatorname != "nexacro")
    {
        nexacro.load_daumpostcode();
    }
    else
    {
        trace("DaumPostCode composite component supports only the web browsers");
    }
};

3

API 스크립트를 최초 로딩하는 load_daumpostcode 함수를 아래와 같이 작성합니다.

동적으로 스크립트를 삽입하는 방식이며, 여러 개의 컴포넌트를 배치하는 경우에는 한 번만 코드를 삽입하도록 합니다.

nexacro.daumpostcode_loaded = false;
nexacro.load_daumpostcode = function()
{
    if (nexacro.daumpostcode_loaded)
    {
        return;
    }
    nexacro.daumpostcode_loaded = true;
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//dmaps.daum.net/map_js_init/postcode.v2.js?autoload=false";
    document.body.appendChild(script);
};

4

사용자가 검색한 결과값을 쉽게 확인할 수 있도록 postcode, address, detailAddress 3개의 속성을 추가합니다.

postcode 속성으로 생성된 코드를 아래와 같이 수정합니다. 다른 속성도 같은 방식으로 수정합니다.

_pDaumPostCode.postcode = "";
_pDaumPostCode.set_postcode = function (v)
{
    if(this.form.editPostcode)
    {
        this.form.editPostcode.set_value(v);
    }
    this.postcode = v;
};

5

우편번호 찾기 Button 컴포넌트 클릭 시 검색창을 띄워주는 스크립트를 아래와 같이 작성합니다.

실제 반환값(data)에서 확인할 수 있는 속성값은 여러가지이지만, 예제에서는 우편번호와 도로명 주소값만 확인합니다.

var that = this;
this.btnFindPostcode_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    if(daum)
    {
        daum.postcode.load(function(){
            new daum.Postcode({
                oncomplete: function(data) {
                    that.parent.set_postcode(data.zonecode);
                    that.parent.set_address(data.roadAddress);
                }
            }).open();
        });
    }
};

6

상세주소를 입력하는 Edit 컴포넌트에 사용자가 값을 입력했을 때 해당 값을 detailAddress 속성에서 처리할 수 있도록 onchanged 이벤트 함수를 아래와 같이 추가합니다.

this.editDetailAddress_onchanged = function(obj:nexacro.Edit,e:nexacro.ChangeEventInfo)
{
    this.parent.set_detailAddress(e.postvalue);
};

7

모듈을 배포하고 넥사크로 스튜디오에 설치합니다.

NRE 실행을 지원하지 않아 에뮬레이터에서는 테스트할 수 없고 배포 후 웹브라우저에서 기능을 확인합니다.

8

DaumPostCode 컴포넌트를 화면에 배치하고 NRE에서 실행합니다.

화면에 컴포넌트는 보이지만, 정상적으로 동작할 수 없습니다. Output 창에서 출력된 메시지를 확인할 수 있습니다.

9

화면에 Button 컴포넌트를 추가하고 onclick 이벤트를 아래와 같이 작성합니다.

우편번호 검색 후 해당 속성에 데이터가 처리되었는지 확인합니다.

this.Button00_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    trace(this.DaumPostCode00.postcode);
    trace(this.DaumPostCode00.address);
};

10

QuickView(Ctrl + F6)로 웹브라우저에서 실행 후 "우편번호 찾기" 버튼을 클릭하면 팝업창으로 우편번호를 검색할 수 있습니다. 검색된 결과값을 클릭하면 Edit 컴포넌트에 값이 들어가는 것을 확인할 수 있습니다.

11

예제에서 추가한 버튼 클릭 시 검색된 결과값을 컴포넌트의 속성에서 확인할 수 있습니다. 개발자 도구 콘솔탭에서 출력되는 값을 확인합니다.

A.2토글 버튼

토글 버튼은 체크박스와 비슷하지만, 물리적인 스위치 이미지를 표현한 형태입니다. 모바일 앱에서 주로 사용하며 웹에서도 자주 볼 수 있습니다.

예제에서 구현한 샘플은 아래 링크를 참조했습니다.

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_switch

1

컴포지트 컴포넌트의 화면을 아래와 같이 구성합니다.


컴포넌트

id

기타 속성

1

Static

staticToggleBox

witdh: 100%

height: 100%

background: #CCCCCC

2

Static

staticTogglebutton

witdh: 50%

height: 100%

background: #FFFFFF

border: 4px solid #cccccc

2

토글 버튼의 모양을 변경할 수 있는 toggleType 속성에서 사용할 EnumInfo 항목을 추가합니다.

"rectangle", "rounded" 2가지 속성값을 Enum 형태로 사용하기 위해 아래와 같이 EnumInfo 항목을 먼저 추가합니다.

3

toggleType 속성을 추가합니다.

edittype 항목은 "Enum"으로 설정하고 enuminfo 항목은 이전 단계에서 생성한 "ToggleType"으로 설정합니다. defaultvalue 항목값은 "rectangle"으로 지정합니다.

4

자동 생성된 toggleType 속성 관련 스크립트 코드를 아래와 같이 수정합니다.

선택한 속성값에 따라 Static 컴포넌트의 borderRadius 속성값을 조정해 모양을 변경합니다.

_pToggleButton.toggleType = "rectangle";
_pToggleButton.set_toggleType = function (v)
{
    this.toggleType = v;
    var togglebackground = this.form.staticToggleBox;
    var togglebutton = this.form.staticTogglebutton;
    if(togglebackground) {
        if(v=="rounded")
        {
            togglebackground.set_borderRadius(this.form.height+"px");
            togglebutton.set_borderRadius("50%");
        }
        else
        {
            togglebackground.set_borderRadius(undefined);
            togglebutton.set_borderRadius(undefined);
        }
    }
};

5

색상을 지정하는 toggleOnColor, toggleOffColor 2개 속성을 추가하고 스크립트 코드를 아래와 같이 수정합니다.

_pToggleButton.toggleOnColor = "#2196F3";
_pToggleButton.toggleOffColor = "#CCCCCC";

_pToggleButton.set_toggleOnColor = function (v)
{
    this.toggleOnColor = v;
    this._changecolor(this.value);
};    

_pToggleButton.set_toggleOffColor = function (v)
{
    this.toggleOffColor = v;
    this._changecolor(this.value);
};

6

value 속성을 추가하고 스크립트 코드를 아래와 같이 수정합니다.

_pToggleButton.value = false;

_pToggleButton.set_value = function (v)
{
    v = this._isChecked(v);
    if (this.value != v) {
        if (this.applyto_bindSource("value", v)) {
            this._setValue(v);
            this._changebutton(this.value);
        }
    }    
};

_pToggleButton._setValue = function (v) {
    this.value = v;
};

7

컴포넌트가 생성되었을때 처리하는 코드를 추가합니다.

Project Explorer에서 ToggleButton.xcdl 파일을 선택하고 속성창에서 on_create_contents 항목을 추가하고 아래와 같이 코드를 수정합니다. Animation 오브젝트는 컴포넌트 클릭 시 버튼의 on, off 상태 변경 시 애니메이션 효과를 적용하기 위해 초기화합니다.

_changecolor 함수는 value 값에 따라 색상을 변경하는 코드인데, 앱에서 컴포넌트가 초기화될때 바로 기본값을 적용할 수 없어서 on_create_contents 함수에서 다시 한번 적용하는 코드를 추가합니다.

_pToggleButton.on_create_contents = function ()
{
    nexacro._CompositeComponent.prototype.on_create_contents.call(this);
    var aniObj = new nexacro.Animation("aniToggleBtn", this);
    aniObj.set_easing("linear");
    aniObj.set_duration(300);
    this.form.addChild("aniToggleBtn", aniObj);
    this.form.aniToggleBtn.addTarget("AniItem00", this.form.staticTogglebutton, "left:0");
    this._changecolor(this.value);
};

_pToggleButton._changecolor = function (value) {
    var backgroundvalue = this.toggleOffColor;
    var bordervalue = "4px solid "+this.toggleOffColor;
    var togglebackground = this.form.staticToggleBox;
    var togglebutton = this.form.staticTogglebutton;
        
    if(value) {
        backgroundvalue = this.toggleOnColor;
        bordervalue = "4px solid "+this.toggleOnColor;
    }
    if(togglebackground) {
        togglebackground.set_background(backgroundvalue);
        togglebutton.set_border(bordervalue);        
    }
}

8

Script 탭에서 Static 컴포넌트의 onclick 이벤트 함수를 아래와 같이 작성합니다.

컴포지트 컴포넌트에 포함된 Static 컴포넌트 클릭 시 상위 컴포넌트의 onclick 이벤트를 처리합니다.

this.staticToggleBox_onclick = function(obj:nexacro.Static,e:nexacro.ClickEventInfo)
{
    this.parent.on_fire_onclick(obj, e.pretext, e.prevalue, e.posttext, e.postvalue);
};

this.staticTogglebutton_onclick = function(obj:nexacro.Static,e:nexacro.ClickEventInfo)
{
    this.parent.on_fire_onclick(obj, e.pretext, e.prevalue, e.posttext, e.postvalue);
};

9

다시 Class Definition 탭으로 돌아와 on_fire_onclick 함수에서 필요한 함수 몇 가지를 추가합니다.

_pToggleButton.value = false;
_pToggleButton.readonly = false;

_pToggleButton._isChecked = function (value) {
    return nexacro._toBoolean(value);
};

_pToggleButton.on_fire_canchange = function (obj, prevalue, postvalue) {
    if (this.canchange && this.canchange._has_handlers)
    {
        var evt = new nexacro.CheckBoxChangedEventInfo(this, "canchange", prevalue, postvalue);
        return this.canchange._fireCheckEvent(this, evt);
    }
    return true;
};

_pToggleButton._changebutton = function (postvalue) {
    var leftvalue = 0;
    this._changecolor(postvalue);
    if(postvalue) {
        leftvalue = this.form.width/2;
    }
        
    if(this.form.aniToggleBtn)
    {
        this.form.aniToggleBtn.items[0].props = "left:"+leftvalue;
        this.form.aniToggleBtn.play();
    }
}

_pToggleButton.on_fire_onchanged = function (obj, prevalue, postvalue) {
    if (this.onchanged && this.onchanged._has_handlers)
    {
        var evt = new nexacro.CheckBoxChangedEventInfo(this, "onchanged", prevalue, postvalue);
        return this.onchanged.fireEvent(this, evt);
    }
};

10

on_fire_onclick 함수를 아래와 같이 작성합니다.

_pToggleButton.on_fire_onclick = function (button, alt_key, ctrl_key, shift_key, screenX, screenY, canvasX, canvasY, clientX, clientY, from_comp, from_refer_comp) {
    if (!this.enable || this.readonly) {
        return false;
    }
        
    var pre_val = this.value;
    var post_val;
    if (this._isChecked(pre_val)) {
        post_val = false;
    } else {
        post_val = true;
    }
        
    var ret = this.on_fire_canchange(this, pre_val, post_val);
    if (ret) {
        if (this.applyto_bindSource("value", post_val)) {
            this._setValue(post_val);
        }
            
        if (pre_val !== post_val) {
            this._changebutton(post_val);
            this.on_fire_onchanged(this, pre_val, post_val);
        }
    }
        
    return nexacro.Component.prototype.on_fire_onclick.call(this, button, alt_key, ctrl_key, shift_key, screenX, screenY, canvasX, canvasY, clientX, clientY, from_comp, from_refer_comp);
};

11

애뮬레이터에서 동작 여부를 확인합니다.

  • 컴포넌트 클릭 시 토글 애니메이션 재생 여부

  • 컴포넌트 클릭 시 버튼이 토글되면서 색상이 바뀌는지 여부

  • 스크립트로 속성 지정 시 속성값이 적용되는지 여부

12

바인딩 처리에 필요한 오브젝트 인터페이스 함수를 추가합니다.

_pToggleButton.on_init_bindSource = function (columnid, propid, ds)
{
    if (propid == "value") {
        this._setValue(this._isChecked(undefined));
        this._changebutton(this.value);
    }
};    
    
_pToggleButton.on_change_bindSource = function (propid, ds, row, col)
{
    if (propid == "value") {
        this._setValue(this._isChecked(ds.getColumn(row, col)));
        this._changebutton(this.value);
    }
};    
    
_pToggleButton.on_getBindableProperties = function ()
{
    return "value";
};

13

모듈을 배포하고 넥사크로 스튜디오에 설치합니다.

14

ToggleButton 컴포넌트를 화면에 배치하고 QuickView(Ctrl + F6)로 웹브라우저에서 실행 후 버튼 동작과 이벤트가 발생하는지 확인합니다.