onExcalendar (event)

외부 달력을 제어할 수 있는 시트 이벤트를 발생시키도록 합니다.
시트의 onScroll, onKeyDown, onAfterFilter, onClick 이벤트 발생 시점에 해당 이벤트가 발생됩니다.
onClickSide 이벤트에서 외부 달력을 시트 셀 영역에 표시하고, 해당 이벤트에서 외부 달력을 제거할 수 있습니다.

Syntax

    onExcalendar: function (paramObject) {

    }
or
    sheet.bind("onExcalendar" , function(paramObject) {});

Parameters

Name Type Description
sheet object 이벤트가 발생한 시트 객체
params object 전달되는 이벤트(onScroll, onKeyDown, onAfterFilter, onClick) 가 가지는 param 인자
evType string 전달되는 이벤트(onScroll, onKeyDown, onAfterFilter, onClick) Name
eventName string 해당 이벤트 Name(onExcalendar)

Return

boolean

Example

// Cols 옵션에서 셀 영역에 외부 달력을 표시하는 예시 (dateRangePicker)
"Cols": [
  {
    "Header": "날짜-daterangepicker","Type": "Date","Name": "DateData","Width": 200,"Align": "Center","CanEdit": 1,"Format": "yyyy-MM-dd","EmptyValue": "날짜를 입력해주세요","DataFormat":"yyyyMMdd",
    "Button": "https://www.ibsheet.com/demo/js/lib/sheet/Main/calendar.png",
    OnClickSide: function (evtParam) {
      var eRow = evtParam.row;
      var eCol = evtParam.col;
      var DateCol = "DateData";
      var cellPos = evtParam.sheet.getCell(eRow, eCol).getBoundingClientRect();
      sheetPopCalendar(evtParam, cellPos, DateCol,true); //단일 달력
    }
  },
  {
    "Header": "예약 날짜(From~To)-daterangepicker","Type": "Date",
    "Name": "FromToData","Width": 250,"Align": "Center","CanEdit": 1,"Format": "yyyy-MM-dd","EmptyValue": "날짜를 입력해주세요","DataFormat":"yyyyMMdd",
    "Button": "https://www.ibsheet.com/demo/js/lib/sheet/Main/calendar.png", 
    "Range": 1, /*날짜를 범위나 여러개 선택 가능하게 설정*/
    OnClickSide: function (evtParam) {
      var eRow = evtParam.row;
      var eCol = evtParam.col;
      var DateCol = "FromToData"; 
      var cellPos = evtParam.sheet.getCell(eRow, eCol).getBoundingClientRect();
      sheetPopCalendar(evtParam, cellPos, DateCol);
    }
  }
]

options.Events = {
  // 외부 달력 이벤트 닫기 (onScroll, onKeyDown, onAfterFilter, onClick)
  onExcalendar : function (evtParam) {

    var isCal = false;
    var evtName = evtParam.evType;

    if (document.getElementsByClassName('daterangepicker ltr show-calendar opensright')[0] && document.getElementsByClassName('daterangepicker ltr show-calendar opensright')[0].style.display != 'none') isCal = true;

    switch (evtName) {
      case "onScroll":
        if (isCal) $('#CalendarInput').data('daterangepicker').remove();
        break;
      case "onAfterFilter":
        // 필터행 초기화인 경우
        if (evtParam.sheet.FCol == "FromData" && evtParam.sheet.FRow[evtParam.sheet.FCol] == '') {
          evtParam.sheet.doFilter("ToData",'');
          if (isCal) $('#CalendarInput').data('daterangepicker').remove();
        }
        break;
      case "onKeyDown": //esc키를 누를
        if (evtParam.params.name == "Esc" && isCal) $('#CalendarInput').data('daterangepicker').remove();
        break;
      case "onClick":
        console.log('onClick');
        break;
    }
  }
}

// onClickSide 이벤트에서 외부 달력을 표시하는 함수
function sheetPopCalendar (par, pos, DateCol, singleDatePicker, calHeight) {

  if (!par || !pos) return;

  // 달력이 표시될 시트 객체
  const sheet = par.sheet;
  
  //달력을 띄우기 위해서 input 객체를 하나 삽입
  if( $("#CalendarInput").length == 0 ) {
	
    // 속성 설정
    const inputElement = document.createElement("input");

    inputElement.setAttribute("type", "text");
    inputElement.setAttribute("id", "CalendarInput");
    inputElement.setAttribute("tabindex", "-1"); //tab키를 눌러서 focus 이동시 숨겨진 달력 input에는 focus를 주지 않도록 설정정
    inputElement.setAttribute("style", "opacity: 0; position: absolute;");
    //inputElement.setAttribute("readonly", "true");

    //body에 달력을 띄우기 위한 input 추가
	  document.body.appendChild(inputElement);
  }

  const datepicker = $('#CalendarInput'); 
  
  const sheetDate = sheet.getValue(par.row, DateCol); //시트의 셀에 표시된 날짜값
  
  //시트 셀의 데이터를 달력 input에 설정
  datepicker.val(sheetDate); 
  
  //dom의 높이 및 공간 계산 후 달력 위치 결정
  const datepickerHeight = calHeight || 290;
  const datepickersingleDate = singleDatePicker || false;  // 달력의 높이(크기)
  const windowHeight = $(document).height();  // document의 height
  const spaceBelow = windowHeight - pos.bottom;

  const dropDirection = (spaceBelow > datepickerHeight) ? 'down' : 'up'; // 달력이 위로 펼쳐질지 아래로 펼쳐질지 계싼

  datepicker.daterangepicker({
    locale: {
      format: 'YYYY-MM-DD', // 날짜 형식
      separator: '~',      // 구분자를 ' ~ '로 설정 (From - To 사이)
      applyLabel: '적용', 
      cancelLabel: '취소', 
      fromLabel: '시작일', 
      toLabel: '종료일', 
      daysOfWeek: ['일', '월', '화', '수', '목', '금', '토'],
      monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']
    },
    drops: dropDirection,
    singleDatePicker: datepickersingleDate, // 범위선택용 달력, 싱글 달력
    showDropdowns: true,     // 드롭다운 선택 가능
    autoUpdateInput: false,  // 자동 업데이트 방지 (사용자가 선택한 날짜만 표시)

  });

  //인풋의 위치를 시트의 row, col로 이동하고 input에 focus를 줘서 달력을 열리게 한다.
  let leftX = pos.x;
  if (par.row.Kind == "Filter"){ //필터행일경우 인풋의 위치를 좌측으로 이동, 필터연산자(같음, 같지않음등) 선택하기 위해서
    leftX += 30;
  }

  datepicker.css({
    position: 'absolute',
    top: `${pos.y+window.scrollY}px`,
    left: `${leftX}px`,
	  height:`${par.event.Height}px`,
	  borderTopStyle : "none",
	  borderBottomStyle : "none",
    width: '30px' 		// 너비를 적당히 설정
  }).show().focus(); 	

  // 날짜 범위 선택 후 적용 시 호출되는 콜백
  datepicker.on('apply.daterangepicker', function(ev, picker) {
    //시트에 값을 넣을때는 포멧 구분자를 제거 하고 넣는다.
    const startDate = picker.startDate.format('YYYYMMDD');
    const endDate = picker.endDate.format('YYYYMMDD');
    const dateRangeText = `${startDate} ~ ${endDate}`;
    const displayValue = picker.singleDatePicker ? startDate : dateRangeText

    // 인풋박스에 날짜 표시
    $(this).val(displayValue);
    
    // 필터행이면 필터 처리
    if (par.row.Kind === "Filter") {
      function filterOptions(data, excludeKey) {
        if (!Array.isArray(data) || data.length === 0) {
          return ["", "", ""];
        }
      
        const filtered = data.filter(item => item[0] !== excludeKey);
        const colNames = filtered.map(item => item[0]).join('|');
        const colValues = filtered.map(item => item[1]).join('|');
        const colTypes = filtered.map(item => item[2]).join('|');

        return [`|${colNames}|`, `|${colValues}|`, `|${colTypes}|`];

      }
      
      //날짜 컬럼 말고도 필터를 했다면 이어서 필터를 적용해야 한다.
      const [cols, values, operators]  = filterOptions(sheet.getFilter(0),DateCol);

      sheet.doFilter(
        `|${DateCol}${cols}`, 
        `|${displayValue}${values}`, 
        `|1${operators}`
      );
    }else{
      sheet.setValue(par.row, DateCol, displayValue);
    }  
  });

  //외부 달력을 닫기위해 필요한 이벤트(onScroll, onKeyDown, onAfterFilter, onClick)
  sheet.bind("onExcalendar" , function(evtParam) {
    let isCal = false;
    const evtName = evtParam.evType;
    const picker = $('#CalendarInput').data('daterangepicker');

    if (picker && picker.isShowing) { //달력이 떠 있는지 체크
      isCal = true;
    } 

    switch (evtName) {
      case "onScroll": //시트에서 스크롤시 달력을 닫는다.
        if (isCal) $('#CalendarInput').data('daterangepicker').remove();
        break;
      case "onKeyDown": //esc키를 누를때 달력을 닫는다.
        if (evtParam.params.name == "Esc" && isCal) $('#CalendarInput').data('daterangepicker').remove();
        break;
      case "onClick":
        // 시트 특정 영역 클릭시 달력을 닫고 싶을 때 로직 추가
        break;
    }
  });
}

Read More

Since

product version desc
core 8.3.0.5 기능 추가