MyTime - 크롬 익스텐션 만들기 - 6 (일정 추가)

남궁명, Nam-Goong Myoung·2020년 12월 9일
2

MyTime

목록 보기
7/12

일정 추가하기를 만들자. 설정 모달과 마찬가지로 모달 컴포넌트를 이용하여 일정 추가하기 모달을 만들자.


init

이전에 했던 설정 모달과 마찬가지로 헤더 텍스트, 버튼, 모달의 크기를 지정해준다.

const initTimeModal = (arr) => {
    const [timeModal, timeModalBody, timeModalButtons] = createModal('일정 추가', ['확인', '취소'], '500px', '400px');
    
    ...
    
    return timeModal;
}

확인 버튼을 누르게 되면 화면에 일정을 추가하여야 하므로 그에 맞게 로직을 짜서 이벤트 리스너로 등록 해주었다.

timeModalButtons[0].addEventListener('click', () => {
    const s = document.getElementById('start-time').value;
    const e = document.getElementById('end-time').value;
    const t = document.getElementById('type').value;

    if(s && e && t){
        let startTime = 0;
        for(let i = 0; i < parent.childNodes.length; i++){
            const data = parent.childNodes[i].getAttribute('data');

            if(i == document.getElementById('start-time').value){
                break;
            }

            startTime += Number(data);
        }

        const endTime = Number(document.getElementById('end-time').value);

        if(endTime && endTime > startTime && endTime <= 24){
            let index = 0;
            for(let i = 0, time = 0, end = 24; time < end; i++){
                const data = parent.childNodes[i].getAttribute('data');

                if(startTime <= time && time < endTime){
                    parent.removeChild(parent.childNodes[i]);
                    i--;
                    index = i;
                }

                time += Number(data);
            }

            const newTime = createElement('div', ['time', 'checked']);
            newTime.style.background = arr[document.getElementById('type').value][1];
            newTime.setAttribute('data', endTime - startTime);
            newTime.style.width = `${16*(endTime-startTime) + 6*(endTime-startTime-1)}px`;

            if(startTime === 0 && endTime === 24){
                parent.appendChild(newTime);
            }
            else if(startTime === 0){
                parent.insertAdjacentElement('afterbegin', newTime);
            }
            else if(endTime === 24){
                parent.insertAdjacentElement('beforeend', newTime);
            }
            else{
                parent.childNodes[index].insertAdjacentElement('afterend', newTime);
            }
        }

        document.getElementById('start-time').value = '';
        document.getElementById('end-time').value = '';
        document.getElementById('type').value = '';
        document.getElementById('contents').value = '';

        timeModal.classList.add('hide');
    }
});

일정을 등록할 때 마다 화면에 있는 box 요소를 지우고 그 자리에 새로 합쳐진 div를 넣게 된다. 그런데 어떤 경우에는 칸이 모자라게 되는 경우가 있다. 후에 로직을 다시 살펴봐야겠다.


selection

모달의 body에 시작 시간, 마친 시간, 분류, 그리고 일정에 대한 내용을 작성하면 된다. 그런데 화면 설계한 대로 분류 선택을 하려고 보니 html의 selection은 option에 text 밖에 인식을 하지 못했다. 그래서 text 이외의 요소를 넣기 위해서 selection을 직접 작성하여 사용하였다.

const createSelection = (arr, id) => {
    const container = createElement('div', 'container');

    const selectionDiv = createElement('div', 'selection');

    const selectionInput = createElement('input', 'selection-input');
    selectionInput.type = 'hidden';
    selectionInput.id = id;

    const selectedDiv = createElement('div', 'selected-div');

    const defaultDiv = createElement('div', 'default-div', '<span>분류를 선택해주세요.</span>');
    const selectionImg = createElement('img', 'selection-img');
    selectionImg.src = '../images/black-down-button.png'

    selectedDiv.addEventListener('click', (event) => {
        for(let i = 0; i < options.length; i++){
            options[i].classList.toggle('hide');
        }
    });

    document.getElementsByTagName('body')[0].addEventListener('click', (event) => {
        if(event.target != selectedDiv){
            for(let i = 0; i < options.length; i++){
                options[i].classList.add('hide');
            }   
        }
    });

    selectedDiv.appendChild(defaultDiv);
    selectedDiv.appendChild(selectionImg);

    const menuDiv = createElement('div', 'menu-div');
    const options = [];
    for(let i = 1; i < arr.length; i++){
        const option = createElement('div', 'option');
        options.push(option);
        option.classList.add('hide');

        const optionBox = createElement('div', 'option-box');
        optionBox.style.backgroundColor = arr[i][1];
        
        const optionSpanDiv = createElement('div', 'option-span-div');
        const optionSpan = createElement('span', 'option-span',arr[i][0]);

        optionSpanDiv.appendChild(optionSpan);

        option.appendChild(optionBox);
        option.appendChild(optionSpanDiv);

        option.addEventListener('click', (event) => {
            if(defaultDiv.innerHTML != option){
                defaultDiv.innerHTML = option.innerHTML;
                selectionInput.value = i;

                for(let i = 0; i < options.length; i++){
                    options[i].classList.remove('selected');
                }
                option.classList.add('selected');
            }
        })

        menuDiv.appendChild(option);
    }

    selectionDiv.appendChild(selectionInput);
    selectionDiv.appendChild(selectedDiv);

    selectionDiv.appendChild(menuDiv);

    container.appendChild(selectionDiv);

    return container;
}

결과

profile
아직 잘 모르겠다!

2개의 댓글

comment-user-thumbnail
2020년 12월 9일

일정 추가하기 모달달달 ... 잘봣읍니다~~~

1개의 답글

관련 채용 정보