본문 바로가기

프로젝트 개발기/Status 200 ( Team Project )

6. TEAM 프로젝트: 캘린더 기능 구현 - 레이아웃 기능


상세한 개발 내역을 작성할려고 했으나, 여러 번의 디버그가 있었고 개발 단계에서 변경되는 점 또한 많았다. 

때문에 완성된 캘린더를 기능 별로 정리하고, 개선점을 작성하려고 한다. 

(TimeLine에 작성해 봤으나 글이 한눈에 들어오지 않는다는 단점이 있어서 방법을 바꿨다.)

 


1. 레이아웃의 기능 정의 

해당 이미지 디자인은 기능 단위를 구현한 후 내가 직접 진행했다. 아이콘도 직접 만든 것이라서 추후에 배포할 생각이다.

 

캘린더의 레이아웃에는 위와 같은 헤더 외에 '스케줄', '그룹', '할일 목록'이 있다.

해당 레이아웃은 각 기능에 대한 포스트에 다루고, 우선 해당 포스트에서는 헤더에 대한 전반적인 기능을 정리한다. 

가장 좌측부터 명칭을 정하자면 다음과 같다. 

 

  • 메뉴: To Do List 및 Group 항목을 안보이도록 한다. 캘린더 영역의 넓이가 늘어난다는 장점이 있다. 
  • 오늘 날짜로 이동: 해당 아이콘을 누르면 오늘 날짜로 이동한다.
  • 이전 날짜로 이동: 해당 아이콘을 누르면 이전 날짜로 이동한다. (년간은 이전 년도, 월간은 이전 월) 
  • 다음 날짜로 이동: 해당 아이콘을 누르면 다음 날짜로 이동한다. (년간은 다음 년도, 월간은 다음 월)
  • 현재 캘린더의 날짜 표시: 현재 캘린더의 Date 정보를 표시한다. 연간은 년도만 표시된다. 
  • 검색 기능: 스케줄을 검색할 수 있다. (더불어 자동완성 또한 구현하였다. 다만 해당 기능에 대한 상세 원리는 그룹에서 구현한 그룹원 초대 기능과 같기 때문에 별도로 서술하지 않는다.)
  • 모양 선택 기능: 해당 Select 태그를 누르면 년간, 월간, 일간 모양을 선택하고 변경할 수 있다. 

 

2. 버튼의 동작을 정의

1) 메뉴 버튼

let calendarHeadMenu = document.getElementsByClassName("calendarHeadMenu")[0];
calendarHeadMenu.addEventListener("click", calendarHeadMenuClidked);

function calendarHeadMenuClidked(){
    let flag = document.getElementsByClassName("calendarHeadMenuFlag")[0];
    let leftBox = document.getElementsByClassName("leftBox")[0];
    let calendarBody = document.getElementsByClassName("calendarBody")[0];
    if(flag.value=="false"){
        flag.setAttribute("value", "true");
        leftBox.setAttribute("style", "display:none;");
        calendarBody.setAttribute("style", "padding-left: 10px; padding-right: 10px;");
    }
    else{
        flag.setAttribute("value", "false");
        leftBox.removeAttribute("style");
        calendarBody.removeAttribute("style");
    }
}

flag 데이터를 menu 생성시 생성한 hidden 타입의 인풋에서 가져온다.

Java Script의 전역 변수에 값을 할당하는 방법도 있지만, 전역 변수가 다수 생기면 개발하면서 이를 혼동할 우려가 있다고 생각했다.

유사한 flag 데이터들은 거의 input 데이터의 값을 가져오는 방식으로 진행했다. 

 

 

2)  오늘 날짜로 이동 

// 오늘로 이동 
function goCalendarToday(){
    select = document.getElementsByClassName("selectForm")[0].value;

    if(select=="Y"){
        let date = getToday();
        changeForm("Y", date);
    }
    else if(select=="M"){
        let date = getToday();
        changeForm("M", date);
    }
    else if(select=="W"){
        // 현재의 구간을 구하고, 해당 구간을 기준으로 더라기 빼기 
    }
    else if(select=="D"){
        let date = getToday();
        changeForm("D", date);
    }
}

 

3) 이전 날짜로 이동

// 이전으로 이동 
function goCalendarPrevious(){
    select = document.getElementsByClassName("selectForm")[0].value;

    // 년도의 경우 -1을 년에 월은 월에 해줌 
    if(select=="Y"){
        let input = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let inputYear = parseInt(input.value.substring(0,4));
        let inputMonth = parseInt(input.value.substring(4,6));
        let inputDay = parseInt(input.value.substring(6,8));

        let changeYear = inputYear-1;
        let changeMonth = inputMonth;
        let changeDay = inputDay;

        let date = getThisDay(changeYear, changeMonth, changeDay, 0, 0);
        changeForm("Y", date);
    }
    else if(select=="M"){
        let input = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let inputYear = parseInt(input.value.substring(0,4));
        let inputMonth = parseInt(input.value.substring(4,6));
        let inputDay = parseInt(input.value.substring(6,8));

        let changeYear = inputYear;
        let changeMonth = inputMonth-1;
        let changeDay = 10;

        if(changeMonth<1){
            changeMonth=12;
            changeYear=changeYear-1;
        }

        let date = getThisDay(changeYear, changeMonth, changeDay, 0, 0);
        changeForm("M", date);
    }
    else if(select=="W"){
       
    }
    else if(select=="D"){
       
    }
}

 

4) 다음 날짜로 이동

// 이전으로 이동 
function goCalendarPrevious(){
    select = document.getElementsByClassName("selectForm")[0].value;

    // 년도의 경우 -1을 년에 월은 월에 해줌 
    if(select=="Y"){
        let input = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let inputYear = parseInt(input.value.substring(0,4));
        let inputMonth = parseInt(input.value.substring(4,6));
        let inputDay = parseInt(input.value.substring(6,8));

        let changeYear = inputYear-1;
        let changeMonth = inputMonth;
        let changeDay = inputDay;

        let date = getThisDay(changeYear, changeMonth, changeDay, 0, 0);

        changeForm("Y", date);
    }
    else if(select=="M"){
        let input = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let inputYear = parseInt(input.value.substring(0,4));
        let inputMonth = parseInt(input.value.substring(4,6));
        let inputDay = parseInt(input.value.substring(6,8));

        let changeYear = inputYear;
        let changeMonth = inputMonth-1;
        let changeDay = 10;

        if(changeMonth<1){
            changeMonth=12;
            changeYear=changeYear-1;
        }

        let date = getThisDay(changeYear, changeMonth, changeDay, 0, 0);

        changeForm("M", date);
    }
    else if(select=="D"){
        
    }
}

 

5) 현재 캘린더의 날짜 표시

// 캘린더 현재 월이나 년수 표현
// 해당 데이터를 기점으로 캘린더 이동이 진행됨 
function whatIsDateInfo(form, date){
    let v = document.getElementsByClassName("calendarHeadDate")[0];

    while(v.hasChildNodes()){
        v.removeChild(v.firstChild);
    }

    if(form=="Y"){
        v.innerHTML += date.year+"년";
        let info = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let month = date.month;
        let day = date.day;

        if(date.month<10){
            month = "0"+date.month;
        }
        if(date.day<10){
            day = "0"+date.day;
        }

        info.value = date.year+""+month+""+day;
    }
    else if(form="M"){
        v.innerHTML += date.year+"년 "+date.month+"월";
        let info = document.getElementsByClassName("calendarHeadDateInfo")[0];
        let month = date.month;
        let day = date.day;

        if(date.month<10){
            month = "0"+date.month;
        }
        if(date.day<10){
            day = "0"+date.day;
        }

        info.value = date.year+""+month+""+day;
    }
    else if(form="D"){

    }
}

 

6) 검색 기능 

// 서치 버튼에 기능 부여
let calendarHeadSearch = document.getElementsByClassName("calendarHeadSearch")[0];
calendarHeadSearch.addEventListener("click", function(){
    let calendarSearch = document.getElementsByClassName("calendarSearch")[0];
    let calendarHeadBar = document.getElementsByClassName("calendarHeadBar")[0];
    let calendarHeadSearchFlag = document.getElementsByClassName("calendarHeadSearchFlag")[0];

    if(calendarHeadSearchFlag.value=="false"){
        calendarHeadSearchFlag.setAttribute("value", "true");
        calendarHeadBar.setAttribute("style", "display:none");
        calendarSearch.setAttribute("style", "display:block");
    }
});

// 스케줄 서치 기능
function searchSchedule(){
    let v = document.getElementsByClassName("calendarSearchBar")[0];
    let word = v.innerHTML;
    let rs = document.getElementsByClassName("calendarSearchResult")[0];

    if(word==""||word=="null"||word==null){
        while(rs.hasChildNodes()){
            rs.removeChild(rs.firstChild);
        }
        rs.removeAttribute("style");
        return;
    }

    rs.setAttribute("style", "display: block");
    createXHRCalendar();

    XHRCalendar.onreadystatechange=function(){
        if(XHRCalendar.readyState==4){
            if(XHRCalendar.status==200){
                let jsons = JSON.parse(XHRCalendar.responseText, "text/json");
                searchScheduleCreateBox(jsons);
            }
        }
    };
    XHRCalendar.open("POST", "scheduleSearch", true);
    XHRCalendar.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    XHRCalendar.send("userKey="+userKey+"&word="+word);
}

// 스케줄을 검색할 경우 해당 데이터를 자동 완성하여 보여줌 
// 보여지는 요소를 선택하면 해당 데이터를 반영하여 이동 
// 별도 페이지를 만들지 폼을 수정하도록 구현할지 추후 결정
function searchScheduleCreateBox(jsons){
    let v = document.getElementsByClassName("calendarSearchResult")[0];
    let c;
    let cc;
    let ccc;

    while(v.hasChildNodes()){
        v.removeChild(v.firstChild);
    }

    for(let i = 0; i < Object.keys(jsons).length; i++){

        c = document.createElement("div");
        c.classList.add("scheduleSearchLists");
        c.innerHTML = "제목: "+jsons[i].title;
        c.addEventListener("click", goToSearchResult);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsNum")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].num);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsTitle")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].title);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsContent")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].content);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsStart")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].start);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsEnd")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].end);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsColor")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].color);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsGroupnum")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].groupnum);
        c.appendChild(cc);

        cc = document.createElement("input");
        cc.classList.add("scheduleSearchListsGroupname")
        cc.setAttribute("type", "hidden");
        cc.setAttribute("value", jsons[i].groupname);
        c.appendChild(cc);

        v.appendChild(c);
    }
}

// 검색한 스케줄 데이터로 이동함 
function goToSearchResult(){
    let target = event.target;
    let num = target.getElementsByClassName("scheduleSearchListsNum")[0].value;
    let title = target.getElementsByClassName("scheduleSearchListsTitle")[0].value;
    let content = target.getElementsByClassName("scheduleSearchListsContent")[0].value;
    let start = target.getElementsByClassName("scheduleSearchListsStart")[0].value;
    let end = target.getElementsByClassName("scheduleSearchListsEnd")[0].value;
    let color = target.getElementsByClassName("scheduleSearchListsColor")[0].value;
    let groupnum = target.getElementsByClassName("scheduleSearchListsGroupnum")[0].value;
    let groupname = target.getElementsByClassName("scheduleSearchListsGroupname")[0].value;

    let data = {
        num: num,
        title: title,
        content: content,
        start: start,
        end: end,
        color: color,
        groupnum: groupnum,
        groupname: groupname
    }
    tempData = data;

    let bar = document.getElementsByClassName("calendarSearchBar")[0];
    bar.innerHTML = "";
    searchSchedule();
    viewScheduleDetail(data);
    quitScheduleDetail();

}

// 스케줄 Box 영역 초기화
// 스케줄을 모두 지워줌
function clearMonthBoxBody(){
    let v = document.getElementsByClassName("monthBoxBody");

    for(let i = 0; i < v.length; i++){
        while(v[i].hasChildNodes()){
            v[i].removeChild(v[i].firstChild);
        }
    }
}

 

7) 셀렉트 폼 변경 

let selectForm = document.getElementsByClassName("selectForm")[0];
selectForm.addEventListener("change", function(){
    changeForm(selectForm.value);
});