14.Calendar

14.1Calendar 소개

일상생활 속에서도 날짜를 입력해야 할 일이 많습니다. 예를 들어 회원 가입 시에 생년월일을 입력하기도 하고 극장에서 영화를 예매할 때 관람 일자를 선택하기도 합니다. 다른 항목과 다르게 날짜는 입력하는 형식이 정해져 있습니다. Calendar 컴포넌트는 사용자가 좀 더 편하고 빠르게 원하는 항목을 입력하고 확인할 수 있는 기능을 제공합니다.

HTML5 Input 요소에 추가된 type 속성값 중에서 'date'를 사용하면 달력과 같은 기능을 사용할 수 있습니다. 날짜를 선택하는 기능은 동작하지만 웹브라우저에 따라 사용자에게 보이는 방식이 다릅니다. 때문에 넥사크로플랫폼에서 사용하는 Calendar 컴포넌트는 HTML5 Input 요소와 별개로 독자적으로 구현된 컴포넌트를 사용합니다.

14.1.1사용 예

Calendar 컴포넌트는 상황에 따라 입력하는 방식이 달라집니다.

14.1.2Calendar 만들기

1

Calendar 컴포넌트 생성하기

툴바에서 Calendar를 선택한 후, Form 위에 드래그 앤 드롭해 생성합니다. type 속성값에 따라 화면에 보이는 형식이 달라지기 때문에 Calendar 컴포넌트를 3개 생성하고 각각 type 속성값을 다르게 지정합니다. Calendar 컴포넌트에서 지원하는 type 속성값은 아래와 같습니다.

normal (default)
monthonly
spin

type 속성값이 "normal"인 경우에는 달력 모양 아이콘을 클릭하면 달력이 펼쳐집니다. 원하는 날짜를 클릭해서 선택하면 달력은 사라집니다. type 속성값이 "monthonly"인 경우에는 달력이 펼쳐진 상태입니다. 원하는 날짜를 선택하면 선택된 값을 처리하는 스크립트를 별도 작성해야 합니다. type 속성값이 "spin"인 경우에는 달력 모양 아이콘 대신 날짜값을 이동할 수 있는 스핀 버튼이 나타납니다.

type 속성값을 'monthonly'로 지정한 경우에는 달력이 펼쳐진 형태로 표시됩니다. 컴포넌트의 크기가 자동으로 변경되지는 않기 때문에 속성값 수정 후 컴포넌트의 크기를 조정해주어야 합니다.

2

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행합니다. Calendar 생성 후 type 속성을 별도로 설정하지 않으면 'normal'로 설정되어 동작합니다.

14.2날짜 형식 바꾸기

나라마다 날짜를 표기하는 형식이 다릅니다. 나라별 형식은 보통 locale 속성값을 수정하면 자동으로 처리됩니다. 보통 가장 많이 사용하는 형식을 기본값으로 설정하는데 해당 형식 외에 다른 형식을 원하면 날짜 형식을 바꿀 수 있습니다.

14.2.1예제

사용자가 dateformat 속성값을 변경했을 때 화면에 표시되는 날짜 형식이 바뀌는 것을 확인할 수 있습니다. 입력창에 입력할 수 있는 날짜 형식은 정해져 있습니다. 형식에 어긋나는 값을 입력하면 입력된 값이 dateformat으로 적용되지 않고 그대로 입력한 값을 보여줍니다.

sample_calendar_01.xfdl

dateformat 항목에 입력할 수 있는 형식은 아래와 같습니다.

strFormat ::= <maskchar> | 'LONGDATE' | 'SHORTDATE'
<maskchar> ::= [<Year>] [<Month>] [<Day>] [<Week>] [<Hour>] [<Minute>] [<Second>] [<MiliSec>]

'LONGDATE', 'SHORTDATE'로 속성값을 지정하는 경우에는 locale 속성값에 따라 사전에 지정된 형식이 적용됩니다. 년도, 월, 일 항목을 배치하는 순서가 지역에 따라 달라집니다. 예제에서 locale 항목을 바꾸면서 어떻게 적용되는지 확인할 수 있습니다.

<maskchar> 속성값을 지정하는 경우에는 locale 속성과 상관없이 지정된 날짜 형식으로 변경됩니다. 강제적으로 보이는 날짜 형식을 고정하기 위해 사용합니다. 단, <week> 항목은 설정된 locale에 따라 표시됩니다.

14.2.2예제에서 사용한 핵심 기능

locale 속성

국가 및 언어를 설정합니다. 언어[_국가] 코드의 조합으로 사용합니다. 예를 들어 미국에서 사용하는 영어를 지정하고 싶다면 'en_US'를 속성값으로 지정합니다. 대소문자를 가리지 않고 언더바(_) 대신 하이픈(-)을 사용할 수 있습니다. 국가코드를 지정하지 않고 언어코드만 지정해도 동작합니다. 'EN_US', 'en-US', 'EN' 모두 같은 형식으로 처리합니다.

locale 속성을 언어코드로만 지정하는 경우에는 해당 언어의 대표적인 국가로 자동 설정됩니다. 예를 들어 '영어'를 설정하면 대표적인 국가인 '미국'을 지정합니다. 언어가 같더라도 국가에 따라 표기가 다를 수 있습니다. 뉴질랜드에서 사용하는 locale 코드는 'en_NZ'인데 날짜를 표기하는 형식이 'en_US'와 다릅니다.

dateformat 속성

컴포넌트에 포커스가 없을 때 화면에 표시되는 날짜 형식을 설정합니다. 화면에 보여주는 형식을 지정하는 것이기 때문에 실제 컴포넌트가 가지고 있는 value값에는 영향을 미치지 않습니다.

dateformat 속성은 대소문자를 구분합니다. 입력할 수 있는 항목은 아래와 같습니다.


'LONGDATE', 'SHORTDATE'

[<Year>] 'yy', 'yyyy'

[<Month>] 'M', 'MM'

[<Day>] 'd', 'dd'

[<Week>] 'ddd'

[<Hour>] 'h', 'hh', 'H', 'HH'

[<Minute>] 'm', 'mm'

[<Second>] 's', 'ss'

[<MiliSec>] 'sss'

14.2.3예제 구현 방법

1

화면 구성하기

Static, Edit, Calendar, Button 컴포넌트를 예제 화면과 같이 배치합니다. Static 컴포넌트는 입력 항목의 타이틀을 표기하고 Edit 컴포넌트는 locale 속성값과 dateformat 속성값을 입력받습니다.

2

Button 컴포넌트 이벤트 함수 작성하기

Button 컴포넌트를 선택한 후 onclick 이벤트 함수를 작성합니다. Button 컴포넌트 클릭 시 Edit 컴포넌트에 입력한 속성값을 Calendar 컴포넌트에 적용합니다.

this.btnChange_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    this.calDisplay.set_locale(this.editLocale.value);
    this.calDisplay.set_dateformat(this.editDateformat.value);
};

3

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 locale, dateformat을 입력하면서 Calendar 컴포넌트에 보이는 값을 확인합니다.

14.3오늘 날짜 구하기

오늘 날짜를 표시하는 기능은 어느 시스템에서든 기본적인 기능입니다. 윈도우 운영체제를 사용하고 있다면 화면 오른쪽 하단에 시계와 오늘 날짜가 표시됩니다. 달력을 실행하면 오늘 날짜가 선택된 상태로 표시됩니다. 날짜를 기준으로 검색조건을 작성할 때도 오늘 날짜 기준으로 이전 1주일, 이전 1개월 이런 식으로 지정하기 때문에 오늘 날짜를 처리하는 기능은 가장 기본적인 기능입니다.

14.3.1예제

버튼 클릭 시 오늘 날짜를 화면에 출력합니다. 화면이 출력될 때 바로 오늘 날짜가 보이길 원한다면 Form 오브젝트의 onload 이벤트 함수에서 스크립트를 처리할 수 있습니다. 이번 예제는 오늘 날짜를 구하는 방법을 설명하는 것이기 때문에 버튼 클릭 시 동작하는 방식으로 처리합니다.

sample_calendar_02.xfdl

14.3.2예제에서 사용한 핵심 기능

Date

Date 오브젝트로 날짜와 시간을 처리합니다. 생성된 Date 오브젝트는 현재 시각에 대한 정보를 담고 있습니다. getFullYear와 같은 메소드를 사용해 원하는 항목값만 추출할 수 있습니다.

getFullYear, getMonth, getDate

Date 오브젝트에서 연도, 월, 일 값을 Integer 형태로 추출하는 메소드입니다. Integer 형태로 값을 추출하기 때문에 YYYYMMDD 형태로 값을 표현하기 위해서는 toString 메소드를 사용해 문자열로 변환 후 값을 합쳐주어야 합니다. getMonth 메소드는 1월은 0, 12월은 11로 반환하기 때문에 실제 사용하는 월을 표기하기 위해서는 1을 더해주어야 합니다.

padLeft

String 오브젝트에서 지정한 길이로 문자열을 만들기 위해 사용하는 메소드입니다. 예를 들어 "1"이라는 문자를 "01"로 표현하려고 할 때 아래와 같이 사용합니다. 첫 번째 파라미터(2)는 만들 문자열 길이입니다. 두 번째 파라미터("0")는 왼쪽에 채울 문자열입니다. 원래 문자열의 길이를 뺀 나머지 길이만큼 해당 문자열이 채워집니다.

var dummy = "1".padLeft(2,"0"); // "01"
var dummy = "1".padLeft(5,"*"); // "****1"
value

Calendar 컴포넌트에 표시되는 날짜값을 갖는 속성입니다. value 속성값은 editformat 속성값에 따라 입력할 수 있는 값이 달라집니다. editformat 속성의 default 값이 'yyyyMMdd' 8자리값이기 때문에 아래 예제에서는 해당 형태로 문자열을 만들어 value 값으로 설정합니다.

14.3.3예제 구현 방법

1

화면 구성하기

Calendar, Button 컴포넌트를 예제 화면과 같이 배치합니다.

2

Button 컴포넌트 이벤트 함수 작성하기

Button 컴포넌트를 선택한 후 onclick 이벤트 함수를 작성합니다. Button 컴포넌트 클릭 시 오늘 날짜를 계산해 Calendar 컴포넌트에 적용합니다.

this.btnToday_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    var currDate = new Date();
    var year = currDate.getFullYear().toString().padLeft(4, "0");
    var month = (currDate.getMonth()+1).toString().padLeft(2, "0");
    var day = currDate.getDate().toString().padLeft(2, "0");

    this.calToday.set_value(year+month+day);
};

3

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 오늘 날짜가 정상 출력되는지 확인합니다.

14.4Trailing day 보여주기

Calendar 컴포넌트는 월 단위로 날짜를 표시합니다. 이때 이달에 해당하는 날짜만 표시할지 아니면 이전, 이후 월에 해당하는 날짜를 같이 보여줄지 옵션으로 설정할 수 있습니다. default 값은 false이며 이달에 해당하는 날짜만 표시합니다.

현재월에 해당하는 날짜만 선택해야 하는 경우 사용자가 선택할 수 있는 날짜만 보여주고 선택하게 할 수 있다는 장점이 있습니다.

14.4.1예제

Radio 컴포넌트를 사용해 해당 속성값을 선택한 후 Calendar 컴포넌트가 어떻게 보이는지 확인할 수 있습니다.

sample_calendar_03.xfdl

14.4.2예제에서 사용한 핵심 기능

usetrailingday

Calendar 컴포넌트에 표시되는 날짜 표기를 해당 월에 해당하는 날짜만 표시할지 이전달, 다음달에 해당하는 날짜도 표기할지 설정합니다.

type

Calendar 컴포넌트는 type 속성값에 따라 화면에 표시되는 모습이 달라집니다. 이번 예제에서는 usetrailingday 속성값이 어떻게 적용되는지 바로 확인하기 위해 type 속성값을 'monthonly'로 설정했습니다.

Boolean

Radio 컴포넌트에서 선택한 값은 문자열 형태로 전달됩니다. usetrailingday 속성은 true 또는 false처럼 Boolean 속성값을 지정해주어야 하는데 이때 Boolean 메소드를 사용하면 값을 변환할 수 있습니다.

Boolean 메소드를 사용할 때 false 값으로 처리되는 경우는 아래와 같습니다. 그 외의 값은 모두 true 값으로 처리합니다. 예제에서도 false 값으로 처리하기 위해 Radio 컴포넌트의 codecolumn 데이터를 공백문자로 설정했습니다.


Boolean()

Boolean(0)

Boolean(null)

Boolean('')

Boolean(false)

14.4.3예제 구현 방법

1

화면 구성하기

Calendar, Radio 컴포넌트를 예제 화면과 같이 배치합니다.

2

속성값 지정하기

Calendar 컴포넌트의 type 속성값을 'monthonly'로 수정합니다. 컴포넌트의 height 값도 적절히 수정해주어야 합니다. width값과 같은 값으로 설정하면 보기 좋게 출력됩니다. Radio 컴포넌트는 innerdataset 값을 아래와 같이 설정합니다. 이때 false에 해당하는 codecolumn 값은 공백문자로 설정해야 합니다.

코드상에서는 ''도 공백문자로 처리되지만 넥사크로 스튜디오에서 codecolumn 항목에 ''을 입력하면 인용부호 자체를 문자로 인식합니다. 때문에 ''대신 공백문자를 입력해야 합니다.

3

Radio 컴포넌트 이벤트 함수 작성하기

Radio 컴포넌트를 선택한 후 onitemchanged 이벤트 함수를 작성합니다. Radio 컴포넌트의 항목 선택 시 해당하는 값을 Calendar 컴포넌트의 usetrailingday 속성값으로 설정합니다.

this.radioTrailingday_onitemchanged = function(obj:nexacro.Radio,e:nexacro.ItemChangeEventInfo)
{
    this.calToday.set_usetrailingday(Boolean(this.radioTrailingday.value));
};

4

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 선택에 따라 Calendar 컴포넌트의 모습이 바뀌는지 확인합니다.

14.5날짜 간 차이 계산하기

날짜 간 차이를 계산하는 것은 생활 속에서도 자주 사용하는 기능입니다. 예를 들어 시험을 앞두고 있다면 오늘 날짜를 기준으로 얼마나 공부할 수 있는 날이 남아있는지 궁금할 수 있습니다. 그리고 여자친구를 만나고 있다면 처음 만난 지 며칠이 되었는지 확인해야 할 경우도 있습니다. 이런 경우뿐 아니라 회사에서 급여를 계산할 때도 날짜를 기준으로 처리하는 경우가 자주 발생합니다.

14.5.1예제

두 개의 Calendar 컴포넌트에서 날짜를 입력받아 차이를 계산해 출력합니다.

sample_calendar_04.xfdl

14.5.2예제에서 사용한 핵심 기능

getYear, getMonth, getDay

화면에 표시되는 날짜값은 locale 속성값 설정에 따라 달라질 수 있어서 년, 월, 일을 가져오기 위해 별도 메소드를 사용했습니다. getMonth 메소드는 1월을 0으로 처리하고 있어서 별도 연산을 추가했습니다.

getTime

Date 오브젝트의 메소드로 시간값을 밀리세컨드 단위로 반환합니다. 두 개의 날짜를 연산으로 비교하기 위해 밀리초 단위로 변환하기 위해 사용합니다.

abs

날짜 계산 시 From 항목에 들어가는 날짜가 To 항목에 들어가는 날짜보다 나중이면 결과값이 음수로 표기되는데 이를 바로잡기 위해 Math 오브젝트의 abs 메소드를 사용합니다. abs 메소드는 입력된 값의 절댓값을 반환합니다.

14.5.3예제 구현 방법

1

화면 구성하기

Calendar, Edit, Button, Static 컴포넌트를 예제 화면과 같이 배치합니다.

2

Button 컴포넌트 이벤트 함수 작성하기

Button 컴포넌트를 선택한 후 onclick 이벤트 함수를 작성합니다. Button 컴포넌트 클릭 시 두 개의 Calendar 컴포넌트에서 선택된 값을 비교해 Edit 컴포넌트에 계산된 값을 출력합니다.

this.btnCal_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    var fromDate = new Date();
    var toDate = new Date();
    var calDate;
    var day = 1000*60*60*24;
    
    fromDate.setFullYear(this.calFrom.getYear());
    fromDate.setMonth(this.calFrom.getMonth()-1);
    fromDate.setDate(this.calFrom.getDay());
    
    toDate.setFullYear(this.calTo.getYear());
    toDate.setMonth(this.calTo.getMonth()-1);
    toDate.setDate(this.calTo.getDay());
    
    calDate = fromDate.getTime() - toDate.getTime();
    
    this.editDay.set_value(Math.abs(calDate/day));
}

getTime 메소드가 밀리세컨드값을 반환하는데 이를 날짜값으로 변환하기 위해 day 변수를 사용합니다. day 변수에 담긴 값은 1일을 밀리세컨드로 환산한 값입니다. (24시간 * 60분 * 60초 * 1000)

3

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 날짜를 선택하고 버튼을 클릭해 날짜 간 차이를 계산합니다.

14.6연도와 주로 날짜 구간 계산하기

업무에 따라 특정 날짜 구간을 주 단위로 처리하는 경우가 있습니다. 예를 들어 정기적으로 회의를 진행한다면 '2016년 32주차 정기 회의'라고 표시하는 경우가 있습니다. 이런 경우 2016년의 32주차라는 것이 어떤 날짜 구간을 의미하는 것인지 계산해야 할 필요가 있는 것이지요.

14.6.1예제

연도와 주차를 숫자로 입력받아 해당하는 날짜 구간 시작일을 Calendar 컴포넌트에 표시합니다.

sample_calendar_05.xfdl

14.6.2예제에서 사용한 핵심 기능

getDay

Date 오브젝트의 getDay 메소드는 0부터 6까지 요일값을 반환합니다. 0은 일요일, 6은 토요일입니다. 예제에서는 주차의 시작을 일요일로 처리하기 때문에 1주차를 계산하기 위해 해당 연도의 1월 1일을 설정한 다음 해당 일이 일요일인지 확인합니다.

Calendar 컴포넌트에도 getDay 메소드가 있습니다. 이 메소드는 요일이 아니라 날짜값을 반환합니다. Calendar 컴포넌트에서 요일값을 구하려면 getDayOfWeek 메소드를 사용해야 합니다.

addDate

Date 오브젝트의 날짜 연산을 처리하는 메소드입니다. 파라미터로 지정한 숫자만큼 더한 날짜값을 반환합니다. 해당 Date 오브젝트의 날짜값이 변경되며 성공적으로 처리한 경우에는 밀리세컨드 단위로 계산된 날짜값을 반환합니다. 파라미터로 지정한 숫자가 음수면 지정한 숫자만큼 뺀 날짜값을 반환합니다.

parseInt

파라미터로 지정한 문자열을 정수 형태의 숫자로 변환하는 메소드입니다. 예를 들어 Edit 컴포넌트에 입력된 값은 문자열로 처리되는데 입력된 값을 숫자로 연산해야 하는 경우 변환을 위한 메소드가 필요합니다. 문자열을 변환하지 않고 연산하는 경우 원하지 않는 결과가 나올 수 있습니다.

"3"+1; //"31"
parseInt("3")+1; // 4

14.6.3예제 구현 방법

1

화면 구성하기

Calendar, Edit, Button, Static 컴포넌트를 예제 화면과 같이 배치합니다. Calendar 컴포넌트는 계산된 값을 바로 확인할 수 있도록 type 속성값은 monthonly로 설정하고 usetrilingday 속성값은 true로 설정합니다.

2

Button 컴포넌트 이벤트 함수 작성하기

Button 컴포넌트를 선택한 후 onclick 이벤트 함수를 작성합니다. Button 컴포넌트 클릭 시 입력된 연도와 주를 계산해 결과값을 Calendar 컴포넌트에 표시합니다.

this.btnCal_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    var dDate = new Date(parseInt(this.editYear.value),0,1);
    var nDay = dDate.getDay();
    
    if(nDay != 0) {
        dDate.addDate(-nDay);
    }
    
    dDate.addDate(7 * (parseInt(this.editWeek.value)-1));
    
    this.calWeek.set_value(dDate.getFullYear()
        +(dDate.getMonth()+1).toString().padLeft(2, "0")
        +dDate.getDate().toString().padLeft(2, "0")
    );
}

3

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 연도와 주차를 입력하고 해당 날짜 구간을 확인합니다.

14.7공휴일 지정하기

달력에서 공휴일을 표시하는 기능은 자주 사용하면서도 논리적으로 구현하기는 어려운 부분입니다. 외부에서 제공하는 이벤트 일정 API를 사용하거나 개발자가 자체적으로 데이터를 만들어 제공하기도 합니다. Calendar 컴포넌트에서는 innerdataset 속성값을 지정해 공휴일 정보를 표시하는 방법을 사용합니다.

14.7.1예제

버튼 클릭 시 공휴일 정보를 적용해 Calendar 컴포넌트에 표시합니다. 현재 년도의 매달 1일을 지정했습니다. 해당 날짜 정보는 필요에 따라 변경할 수 있습니다.

sample_calendar_06.xfdl

14.7.2예제에서 사용한 핵심 기능

innerdataset

Calendar 컴포넌트에서 특정 날짜 표기를 처리하기 위해 해당 데이터를 담고 있는 Dataset을 지정할 수 있습니다. Dataset 컴포넌트를 추가해 지정할 수도 있으며 넥사크로 스튜디오에서 innerdataset 편집기를 사용해 데이터를 추가할 수 있습니다.

backgroundcolumn, textcolorcolumn, bordercolumn

Calendar 컴포넌트에서 해당 날짜에 해당하는 영역의 배경색, 텍스트색, 테두리 정보를 지정하는 속성입니다. bordercolumn 데이터는 DatePickerControl 컨트롤의 border 속성을 기준으로 작성되어야 합니다.

14.7.3예제 구현 방법

1

화면 구성하기

Calendar, Button 컴포넌트를 예제 화면과 같이 배치합니다. Calendar 컴포넌트는 계산된 값을 바로 확인할 수 있도록 type 속성값은 monthonly로 설정합니다.

2

Dataset 컴포넌트 설정하기

Dataset 컴포넌트를 추가하고 backgroundcolumn, bordercolumn, datecolumn, textcolorcolumn 4개 컬럼을 설정합니다. 그리고 속성창에서 Calendar 컴포넌트의 innerdataset 항목을 설정합니다. innerdataset 속성값을 설정하고 나면 나머지 항목도 목록에서 설정할 수 있습니다.

3

Button 컴포넌트 이벤트 함수 작성하기

Button 컴포넌트를 선택한 후 onclick 이벤트 함수를 작성합니다. Button 컴포넌트 클릭 시 Dataset의 데이터를 초기화하고 현재 년도의 매월 1일 날짜값을 Dataset에 추가합니다. 이때 backgroundcolumn, bordercolumn, textcolorcolumn 항목은 설정하지 않으면 테마에 지정된 값이 적용됩니다.

this.btnCal_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    this.dsHoliday.clearData();
    
    var colorBordercolumn = "1px solid green";
    var colorBackgroundcolumn = "yellow";
    var colorTextcolorcolumn = "red";
    
    var currDate = new Date();
    var year = currDate.getFullYear().toString().padLeft(4, "0");    
    
    for(var i=1;i<13;i++) {
        var rIdx = this.dsHoliday.addRow();
        this.dsHoliday.setColumn(rIdx, "backgroundcolumn", colorBackgroundcolumn);
        this.dsHoliday.setColumn(rIdx, "textcolorcolumn", colorTextcolorcolumn);
        this.dsHoliday.setColumn(rIdx, "bordercolumn", colorBordercolumn);
        this.dsHoliday.setColumn(rIdx, "datecolumn", (year+i.toString().padLeft(2, "0"))+"01");    
        
    }
}

1월부터 12월까지 매월 1일을 공휴일로 지정하기 위해 for 문을 사용했습니다. i라는 변수의 초기값을 1로 지정하고 13보다 작을 때까지 1씩 늘어나며 구문 내의 코드를 반복해서 실행합니다. Dataset에 새로운 값을 추가하기 때문에 addRow 메소드로 Row를 추가하고 setColumn 메소드를 사용해 지정된 컬럼에 데이터를 지정합니다. 넥사크로 스튜디오에서 아래 그림과 같이 Row를 추가하고 값을 설정하는 것과 같습니다.

사용자가 버튼을 클릭하거나 항목을 입력했을 때 이전에 추가된 Dataset의 값을 모두 삭제하고자 할 때는 clearData 메소드를 사용합니다. 이번 예제에서는 같은 데이터가 추가되기 때문에 초기화가 없다면 같은 데이터가 계속 쌓이게 됩니다.

backgroundcolumn, bordercolumn, textcolorcolumn 항목은 설정하지 않으면 테마에 지정된 값이 적용됩니다.

4

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 버튼을 클릭해 지정된 공휴일을 지정합니다.

14.8음력 날짜로 변환하기

양력 날짜를 음력으로 변환하는 것은 명확한 규칙을 가지고 있지는 않습니다. 그래서 대부분의 음력 날짜 변환하는 스크립트를 보면 어느 시점부터 어느 시점까지만 변환할 수 있는 제한을 둡니다. 그 기간동안의 기본 데이터를 스크립트 안에 지정해놓고 계산합니다. 이번 예제에서는 1900년부터 2040년까지 음력 날짜로 변환하는 기능을 살펴봅니다.

14.8.1예제

양력 날짜를 입력하면 음력 날짜를 표시합니다.

sample_calendar_07.xfdl

14.8.2예제에서 사용한 핵심 기능

concat

Calendar 컴포넌트에 value 값을 설정할때 "20181212"와 같은 식으로 값을 설정하는데, 년도, 월, 일로 나누어진 문자열을 하나로 합치기 위해 concat 메소드를 사용합니다.

14.8.3예제 구현 방법

1

Form 화면 구성하기

Calendar 컴포넌트를 2개 배치합니다. 첫번째 Calendar 컴포넌트는 양력 날짜를 입력받기 위한 용도입니다. 두번째 Calendar 컴포넌트는 음력 날짜를 출력하기 위한 용도입니다. enable 속성값을 false로 지정합니다. 그리고 CheckBox 컴포넌트를 하나 더 배치하는데 음력 날짜에는 윤달이라는 개념이 있어서, 윤달일 경우에 체크박스에 표시해줍니다.

2

Calendar 컴포넌트의 onchanged 이벤트 함수 작성하기

양력 날짜를 입력하면 바로 음력 날짜가 출력되도록 onchanged 이벤트 함수를 작성합니다. 입력받은 값으로 음력 날짜를 계산해서 Calendar 컴포넌트와 CheckBox 컴포넌트에 표시합니다.

this.Calendar00_onchanged = function(obj:nexacro.Calendar,e:nexacro.ChangeEventInfo)
{
    var c = new String(obj.value);
    var y = c.substr(0,4);
    var m = c.substr(4,2);
    var d = c.substr(6,2);
    var lunar = this.lunarCalc(y, m, d, 1);
    lunar.month = lunar.month < 10 ? "0"+lunar.month : lunar.month;
    lunar.day = lunar.day   < 10 ? "0"+lunar.day   : lunar.day;
    
    this.Calendar01.set_value(String().concat(lunar.year, lunar.month, lunar.day));
    this.CheckBox00.set_value(lunar.leapMonth);
};

3

음력 날짜 계산하기

onchanged 이벤트에서 호출되는 함수는 lunarCalc 입니다. 여기에서는 입력된 양력 날짜를 음력 날짜로 계산합니다. 정확하게는 계산이라기보다는 lunarMonthTable 라는 배열에서 해당하는 날짜 정보를 찾아서 반환하는 것입니다.

this.lunarCalc = function (year, month, day, type, leapmonth)
{
    var solYear, solMonth, solDay;
    var lunYear, lunMonth, lunDay;
    var lunLeapMonth, lunMonthDay;
    var i, lunIndex;
    
    var solMonthDay = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    
    /* range check */
    if (year < 1900 || year > 2040)
    {
        alert('This example supports solar to lunar from 1900 to 2040 only');
        return;
    }

전체 스크립트 코드는 소스를 참조해주세요.

4

QuickView로 확인하기

QuickView(Ctrl + F6)로 실행한 후 첫번째 Calendar에서 날짜를 선택하면 음력 날짜를 확인할 수 있습니다.

14.9입력한 날짜 보정하기

달력에서 직접 날짜를 선택하는 경우는 선택한 날짜값을 그대로 처리하지만, 직접 텍스트 편집 영역에 값을 입력하거나 스크립트에서 값을 설정하는 경우에는 날짜 범위를 벗어나거나 누락된 값이 들어올 수 있습니다. 이런 경우에는 내부적으로 날짜값을 규칙에 따라 보정하고 보정된 값으로 처리합니다.

14.9.1예제

Radio 컴포넌트에서 입력할 값을 선택하면 Calendar 컴포넌트에 보정된 값이 표시됩니다. 날짜 보정 규칙은 아래와 같습니다.

sample_calendar_08.xfdl

14.9.2예제에서 사용한 핵심 기능

value

Calendar 컴포넌트의 경우 사용자가 입력한 값과 실제 처리되는 value 속성값이 다를 수 있습니다. 예제에서 설명한 규칙 외에도 editformat 속성에 따라 입력한 값과 달라질 수 있습니다. 일반적인 경우에는 사용자가 입력할 수 있는 경로를 제한하기 때문에 예외적인 상황이 발생하지는 않지만, value 속성의 특징을 미리 알지 못하면 원하는 데이터가 들어오지 않았을 때 원인을 확인할 수 없습니다.

14.9.3예제 구현 방법

1

화면에 GroupBox 컴포넌트를 배치하고, Radio 컴포넌트를 그 안에 배치합니다.

예제에서는 규칙에 따라 Radio 컴포넌트를 구분해 표시하기 위해 GroupBox 컴포넌트를 사용했습니다. 동작에는 영향을 미치지 않습니다.

2

Radio 컴포넌트의 innerdataset 데이터를 예제와 같이 지정합니다.

3

Radio 컴포넌트 아래에 Calendar 컴포넌트를 배치합니다.

4

Radio 컴포넌트를 선택하고 속성창 컨텍스트 메뉴를 [Add User Property] 항목을 선택합니다.

5

[Add User Property] 입력창이 뜨면 Name 항목은 "calendarId", Value 항목은 "Calendar00"으로 입력합니다.

사용자 속성으로 추가한 calendarId 속성은 Radio 컴포넌트의 이벤트 처리 시 사용할 겁니다.

6

Radio 컴포넌트의 onitemchanged 이벤트 함수를 아래와 같이 추가합니다.

이벤트가 발생한 Radio 컴포넌트의 사용자 속성인 calendarId 속성값에 해당하는 Calendar 컴포넌트의 value 속성값을 선택한 아이템 값으로 설정합니다.

this.Radio_onitemchanged = function(obj:nexacro.Radio,e:nexacro.ItemChangeEventInfo)
{
    this[obj.calendarId].set_value(e.postvalue);
};

7

GroupBox, Radio, Calendar 컴포넌트를 모두 선택하고 복사한 후 붙여넣기를 하고 적절한 위치에 배치합니다.

예제에서는 3개의 컴포넌트의 배치가 3번 반복되는 구성이라 복사해 붙여넣기를 사용했습니다. 간단한 예제이니 1번부터 단계를 반복할 수도 있습니다.

8

GroupBox 컴포넌트의 text 속성값을 수정하고 Radio 컴포넌트의 innerdataset 속성 데이터를 설정합니다. 앞에서 만든 Radio 컴포넌트를 복사했다면 사용자 속성인 calendarId 속성값도 수정합니다.

9

QuickView(Ctrl + F6)로 실행한 후 선택한 값이 어떻게 보여지는지 확인합니다.

14.10DatePickerControl 스타일 지정하기

Calendar 컴포넌트에서 달력 형태로 날짜를 선택할 수 있는 영역은 DatePickerControl 입니다. Calendar 컴포넌트 뿐 아니라 Grid 컴포넌트 등에서도 사용할 수 있기 때문에 별도의 컨트롤로 분리되어 있습니다. Calendar 컴포넌트에서 DatePickerControl 영역의 스타일을 지정하는 방법을 살펴봅니다.

14.10.1예제

왼쪽은 기본 테마를 적용한 상태이며, 오른쪽은 일부 스타일 속성을 변경한 상태입니다.

sample_calendar_09.xfdl

14.10.2예제에서 사용한 핵심 기능

datepicker

Calendar 컴포넌트의 하위 컨트롤인 DatePickerControl에 접근하기 위한 속성입니다. 예제에서는 스타일 속성을 설정하기 위한 자식 선택자로 사용합니다.

14.10.3예제 구현 방법

1

화면에 Calendar 컴포넌트를 배치하고 locale 속성값은 "en_US", type 속성값은 "monthonly"로 지정합니다. width, height 속성값은 200으로 지정합니다.

2

xcss 파일을 열어서 아래와 같이 코드를 추가합니다.

DatePickerControl은 두 부분으로 나눌 수 있습니다. 년도와 월을 표시하며 버튼을 가지고 있는 head, 요일과 날짜를 표시하는 body. 그리고 body는 다시 요일을 표시하는 weekband와 각각의 dayitem으로 구성됩니다.아래 코드에서는 head, weekband 영역의 배경색을 바꾸었고 body 영역의 테두리선을 보이지 않게 했으며, 토요일과 일요일을 다른 날과 같은 색으로 표시하도록 했습니다.

.Calendar.sample_calendar_09 .datepicker .head
{
    background : orangered;
}
.Calendar.sample_calendar_09 .datepicker  .body .weekband
{
    background : orangered;
}
.Calendar.sample_calendar_09 .datepicker  .body
{
    -nexa-border : 1px none transparent;

}
.Calendar.sample_calendar_09 .datepicker .body .dayitem[userstatus=saturday]
{
    color : #333333;
}
.Calendar.sample_calendar_09 .datepicker .body .dayitem[userstatus=sunday]
{
    color : #333333;
}
.Calendar.sample_calendar_09 .datepicker .body .weekitem[userstatus=saturday]
{
    color : #ffffff;
}
.Calendar.sample_calendar_09 .datepicker .body .weekitem[userstatus=sunday]
{
    color : #ffffff;
}

3

오른쪽 Calendar 컴포넌트의 cssclass 속성값을 "sample_calendar_09"로 설정합니다.

4

QuickView(Ctrl + F6)로 실행한 후 두 개의 Calendar 컴포넌트에 적용된 스타일을 확인합니다.

14.11평일로 다음날 설정하기

Calendar 컴포넌트에서 선택한 날이 금요일인 경우 토요일이 아닌 다음 주 월요일을 설정합니다.

14.11.1예제

일요일에서 목요일 사이의 날짜를 선택하면 다음날을 두 번째 Calendar 컴포넌트에 표시하고 금요일, 토요일을 선택한 경우에는 월요일을 표시합니다.

sample_calendar_10.xfdl

14.11.2예제에서 사용한 핵심 기능

getDayOfWeek

선택한 날짜의 요일값을 반환합니다. 일요일은 0을 반환하고 토요일은 6을 반환합니다.

14.11.3예제 구현 방법

1

화면에 Calendar 컴포넌트를 배치하고 locale 속성값은 "en_US"로 설정합니다. 두 번째 Calendar 컴포넌트의 readonly 속성값은 false로 지정합니다.

2

첫 번째 Calendar 컴포넌트의 onchanged 이벤트 함수를 아래와 같이 작성합니다.

getDayOfWeek 메소드를 사용해 선택한 날짜의 요일값을 확인하고 금요일, 토요일의 경우 따로 처리합니다.

this.Calendar00_onchanged = function(obj:nexacro.Calendar,e:nexacro.ChangeEventInfo)
{
    var nWeek = obj.getDayOfWeek();
    if(nWeek == 5)
    {
        this.Calendar01.set_value (this.AddDateOffset(e.postvalue, 3));
    }
    else if(nWeek == 6)
    {
        this.Calendar01.set_value (this.AddDateOffset(e.postvalue, 2));
    }
    else 
    {
        this.Calendar01.set_value (this.AddDateOffset(e.postvalue, 1));
    }
    this.setFocus(true, false);
};

다음날 처리를 위해 지정한 날만큼 더한 값을 반환합니다.

this.AddDateOffset = function(sDate, nOffset)
{
    var nYear = parseInt(sDate.substr(0, 4));
    var nMonth = parseInt(sDate.substr(4, 2));
    var nDate = parseInt(sDate.substr(6, 2)) + nOffset;

    return this.MakeDate(nYear, nMonth, nDate);
}

this.MakeDate = function(nYear, nMonth, nDate)
{
    var objDate = new Date(nYear, nMonth-1, nDate);

    var sYear   = objDate.getFullYear().toString();
    var sMonth  = (objDate.getMonth() + 1).toString().padLeft(2, "0");
    var sDate   = (objDate.getDate()).toString().padLeft(2, "0");

    return sYear + sMonth + sDate;
}

3

QuickView(Ctrl + F6)로 실행한 후 첫 번째 Calendar 컴포넌트에서 원하는 날짜를 선택해봅니다.