라라리라

2023.10.25 / Step 7 [DOM_Diary] - 코딩 76 일차 본문

코딩/2023 JavaScript DOM

2023.10.25 / Step 7 [DOM_Diary] - 코딩 76 일차

헤실 2023. 10. 25. 23:29

index.html

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="main.js" type="module"></script>

</head>
<body>
    <div id="header"></div>
    <div id="content"></div>
</body>
</html>

 


 

main.js

 

import { ControllerMain } from "./controllerMain.js";
import { JsonDiary } from "./jsonDiary.js";

JsonDiary.getInstance().start();
ControllerMain.getInstance().start();

 


 

jsonDiary.js

 

export class JsonDiary {

    static intstance = new JsonDiary();
    static getInstance() { return this.intstance; }

    start() {
        this.diaryList = null;
        this.setSampleData();
    }

    setSampleData() {
        this.diaryList = [
            {
                "diaryNo"   : 1001,
                "title"     : "제목1",
                "content"   : "내용1",
                "regDate"   : "2023-01-19"      
            },
            {
                "diaryNo"   : 1002,
                "title"     : "제목2",
                "content"   : "내용2",
                "regDate"   : "2023-02-19"
            },
            {
                "diaryNo"   : 1003,
                "title"     : "제목3",
                "content"   : "내용3",
                "regDate"   : "2023-03-19"
            },
            {
                "diaryNo"   : 1004,
                "title"     : "제목4",
                "content"   : "내용4",
                "regDate"   : "2023-03-19"
            },
            {
                "diaryNo"   : 1005,
                "title"     : "제목5",
                "content"   : "내용5",
                "regDate"   : "2023-04-19"
            },
            {
                "diaryNo"   : 1006,
                "title"     : "제목6",
                "content"   : "내용6",
                "regDate"   : "2023-03-19"
            },
            {
                "diaryNo"   : 1007,
                "title"     : "제목777777777777",
                "content"   : "내용7",
                "regDate"   : "2023-03-19"
            },
        ];

    }

    getMaxNo() {
        let maxNo = 0;
        for(let i=0; i<this.diaryList.length; i++) {
            if(maxNo < this.diaryList[i].diaryNo) {
                maxNo = this.diaryList[i].diaryNo;
            }
        }
        return maxNo;
    }

    diaryWritePro(title, content, regDate) {
        let diary = {
            "diaryNo"   : this.getMaxNo() + 1,
            "title"     : title,
            "content"   : content,
            "regDate"   : regDate
        };

        this.diaryList.push(diary);

        console.log(this.diaryList);
    }

    getDiaryList(year, month) {
        let temp = [];

        for(let i=0; i<this.diaryList.length; i++) {
            let token = this.diaryList[i].regDate.split("-");
            let tokenYear = Number(token[0]);
            let tokenMonth = Number(token[1]);

            if(tokenYear == year && tokenMonth == month) {
                temp.push(this.diaryList[i]);
            }
        }

        return temp;
    }

    getDiaryInfo(diaryNo) {
        for(let i=0; i<this.diaryList.length; i++) {
            if(this.diaryList[i].diaryNo == diaryNo) {
                return this.diaryList[i];
            }
        }
    }

}

 


 

controllerMain.js

 

import { PageHeader } from "./pageHedaer.js";
import { PageContent } from "./pageContent.js";
import { PageWrite } from "./pageWrite.js";
import { PageInfo } from "./pageInfo.js"

export class ControllerMain {
   
    static instance = new ControllerMain();
    static getInstance() { return this.instance; }

    start() {
        this.dayList = ["", "", "", "", "", "", ""];

        this.pageList = {};
        this.setPageList();

        this.chagePage("page-header", null);
        this.chagePage("page-content", null);
    }

    setPageList() {
        this.pageList["page-header"] = new PageHeader();
        this.pageList["page-content"] = new PageContent();
        this.pageList["page-write"] = new PageWrite();
        this.pageList["page-info"] = new PageInfo();
    }

    chagePage(pageName, data) {
        this.pageList[pageName].execute(data);
    }

}

 


pageHedaer.js

 

import { ControllerMain } from "./controllerMain.js";

export class PageHeader {

    execute(data) {
        let $header = document.querySelector("#header");

        let tag = "";

        tag +=
        `
        <style>
            table, tr, td {
               
                border-collapse: collapse;
            }
            #header-table {
                margin: 0 auto;
                width: 1000px;
                border-bottom: 1px solid #333333;
            }
            #time {
                font-size: 50px;
                color: #333333;
                height: 100px;
                vertical-align: bottom;
            }
            #today {
                color: blue;
                height: 50px;
                vertical-align: top;
            }      
        </style>  
        `;

        tag +=
        `
        <table id="header-table">
            <tr>
                <td id="time"></td>
            </tr>
            <tr>
                <td id="today"></td>
            </tr>
        </table>
        `;

        $header.innerHTML = tag;

        setInterval(this.setTime, 1000);
        this.setToday();

    }

    setTime = (event) => {
        let today = new Date();
        document.querySelector("#time").innerText = today.toLocaleTimeString();
    }

    setToday = (event) => {
        let today = new Date();

        let dayList = ControllerMain.getInstance().dayList;
        let thisYear = today.getFullYear();
        let thisMonth = today.getMonth();
        let thisDate = today.getDate();
        let thisDay = today.getDay();

        document.querySelector("#today").innerText = `${thisYear}${thisMonth + 1}${thisDate}${dayList[thisDay]}요일`;
    }

}

 


pageContent.js

 

import { ControllerMain } from "./controllerMain.js";
import { JsonDiary } from "./jsonDiary.js";

export class PageContent {

    $content = null;

    execute(data) {
        this.$content = document.querySelector("#content");

        let tag = "";
        tag +=
        `
        <style>
            .diary-title {
                margin: 5px;
                border: 1px solid lightgray;
                border-radius: 3px;
                box-shadow: 2px 2px 2px lightgray;
                cursor: pointer;
            }
            .aInfo {
                text-decoration: none;
                color: black;
            }
            #content {
                margin: 0 auto;
                width: 1000px;
            }
            .dayOfWeek {
                text-align: center;
                font-size: 18px;
                font-weight: bold;
                color: #333333;
                width: 140px;
                height: 50px;
                border-bottom: 1px solid #333333;
            }
            .day {
                vertical-align: top;
                height: 70px;
                padding: 10px;
                border-bottom: 1px solid #333333;
            }
            .dayOfWeek:not(:last-child),
            .day:not(:last-child) {
                border-right: 1px solid #333333;
            }  
           
            #nav {
                margin: 0 auto;
                width: 1000px;
                height: 80px;
                border-bottom: 1px solid #333333;
            }
            #navEmpty {
                width: 500px;
            }
            .navBtn {
                background-color: white;
                border-style: none;
                cursor: pointer;
                font-size: 20px;
               
            }          
        </style>
        `;

        tag +=
        `
        <table id="nav">
            <tr>
                <td>
                    <span id="year"></span>년 <span id="month"></span>월
                </td>
                <td id="navEmpty">
                </td>
                <td><button class="navBtn">△</button></td>
                <td><button class="navBtn">▽</button></td>
            </tr>
        </table>

        <table id="content">
            <tr>
                <td id="contentTd"></td>
            </tr>
        </table>
        `;

        this.$content.innerHTML = tag;

        let today = new Date();
        let year = today.getFullYear();
        let month = today.getMonth() + 1;
        document.querySelector("#year").innerText = year;
        document.querySelector("#month").innerText = month;

        let navBtnList = document.querySelectorAll(".navBtn");
        navBtnList[0].addEventListener("click", this.beforeMonth);
        navBtnList[1].addEventListener("click", this.afterMonth);

        this.setCalendar();
    }

   

    beforeMonth = (event) => {
        let $thisYear = document.querySelector("#year");
        let $thisMonth = document.querySelector("#month");

        let year = Number($thisYear.innerText);
        let month = Number($thisMonth.innerText) - 1;
       
        if(month < 1) {
            year -= 1;
            month = 12;
        }
       
        $thisYear.innerText = year;
        $thisMonth.innerText = month;

        this.setCalendar();
    }
   
    afterMonth = (event) => {
        let $thisYear = document.querySelector("#year");
        let $thisMonth = document.querySelector("#month");
       
        let year = Number($thisYear.innerText);
        let month = Number($thisMonth.innerText) + 1;
       
        if(month > 12) {
            year += 1;
            month = 1;
        }
       
        $thisYear.innerText = year;
        $thisMonth.innerText = month;

        this.setCalendar();

       
    }

    getTable = (event) => {
        let $table = document.createElement("table");
        $table.id = "calendar";
        for(let i=0; i<7; i++) {
            let $tr = document.createElement("tr");
            for(let j=0; j<7; j++) {
                let $td = document.createElement("td");

                $tr.append($td);

                if(i == 0) {
                    $td.classList = "dayOfWeek";
                   
                } else {
                    $td.classList = "day";
                }

                if(j == 0) {
                    $td.style.color = "red";
                } else if(j == 6) {
                    $td.style.color = "blue";
                }
            }
            $table.append($tr);
        }
        return $table;
    }

    setCalendar = (event) => {
        let $content = document.querySelector("#contentTd");
        if($content.hasChildNodes()) {
            $content.removeChild($content.firstChild);
        }

        let dayList = ControllerMain.getInstance().dayList;
        let thisYear = document.querySelector("#year").innerText;
        let thisMonth = document.querySelector("#month").innerText - 1;

        // 달력을 표시하기 위한 테이블 생성
        let $table = this.getTable();
        this.$content = document.querySelector("#contentTd");
        this.$content.append($table);

        // 작년도까지 day 구하기
        let lastYear = thisYear - 1;
        let total = lastYear * 365;

        // 작년도까지 윤년 추가하기
        total += parseInt(lastYear / 400);
        total -= parseInt(lastYear / 100);
        total += parseInt(lastYear / 4);

        // 올해 지난달(2월)까지의 day 구하기
        // 올해가 윤년인지 확인해 윤년이면 2월달을 29일로 변경하기
        let monthList = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

        if(thisYear % 400 == 0) {
            monthList = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        } else if(thisYear % 100 != 0 && thisYear % 4 == 0) {
            monthList = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        }
        for(let i=0; i<thisMonth; i++) {
            total += monthList[i];
        }

        // 이번달을 표시하기 위해 1을 더한다.
        total += 1;

        // 이번달의 시작 요일 구하기
        let dayIndex = total % 7;

        // 요일 화면에 표시하기
        for(let i=0; i<dayList.length; i++) {
            $table.children[0].children[i].innerText = dayList[i];
        }

        let row = 1;
        for(let i=0; i<monthList[thisMonth]; i++) {
            let index = (i + dayIndex) % 7;
            $table.children[row].children[index].innerHTML = "<div><a href='#' class='aWrite'>" + (i + 1) + "</a></div>";
            if(index == 6) {
                row += 1;
            }
        }

        let $aWirteList = document.querySelectorAll(".aWrite");
        console.log($aWirteList);
        for(let i=0; i<$aWirteList.length; i++) {
            $aWirteList[i].addEventListener("click", this.clickWritePage);
        }

        this.setDiaryList(thisYear, thisMonth + 1);

    }

    clickWritePage = (event) => {

        let year = document.querySelector("#year").innerText;
        let month = document.querySelector("#month").innerText;
        if(Number(month) < 10) {
            month = "0" + month;
        }
        let day = event.target.innerText;
        if(Number(day) < 10) {
            day = "0" + day;
        }
        let data = year + "-" + month + "-" + day;

        ControllerMain.getInstance().chagePage("page-write", data);
    }

    setDiaryList(year, month) {
        let list = JsonDiary.getInstance().getDiaryList(year, month);
        console.log(list);

        let $dayList = document.querySelectorAll(".day");

        for(let i=0; i<list.length; i++) {

            let title = list[i].title;
            let day = Number(list[i].regDate.split("-")[2]);
            // console.log(day);
           
            for(let j=0; j<$dayList.length; j++) {
                // 빈칸을 제외하고
                if($dayList[j].children[0] != null) {
                    // 첫번째 children => 날짜(숫자)
                    if($dayList[j].children[0].innerText == day) {

                        let $div = document.createElement("div");

                        // 게시글 번호 저장하기
                        $div.id = list[i].diaryNo;

                        $div.classList = "diary-title";
                        $div.style.color = "black";
                        $div.style.width = "100px";
                        $div.height = "20px";

                        $div.style.display = "block";
                        $div.style.overflow = "hidden";             // 텍스트가 너비를 넘어서면 글자 숨기기
                        $div.style.whiteSpace = "nowrap";           // 줄바꿈 방지
                        $div.style.textOverflow = "ellipsis";       // 줄말임(...) 표시

                        $div.append(title);

                        $dayList[j].append($div);
                    }
                }
            }

            let $titleList = document.querySelectorAll(".diary-title");
            for(let i=0; i<$titleList.length; i++) {
                $titleList[i].addEventListener("click", this.clickInfoPage);
            }

        }
    }

    clickInfoPage = (event) => {

        let diaryNo = event.target.id;

        ControllerMain.getInstance().chagePage("page-info", diaryNo);
    }

}

 


pageWrite.js

 

import { ControllerMain } from "./controllerMain.js";
import { JsonDiary } from "./jsonDiary.js";

export class PageWrite {

    date = null;

    execute(data) {

        this.date = data;

        let $content = document.querySelector("#content");

        let tag = "";
        tag +=
        `
        <style>
            #nav {
                margin: 0 auto;
                width: 1000px;
                height: 80px;
                border-bottom: 1px solid #333333;
            }

            #content {
                margin: 0 auto;
                width: 1000px;
                height: 450px;
            }
            #content td {
                border-bottom: 1px solid #333333;
            }
            #content td:nth-child(1) {
                height: 70px;
                width: 50px;
            }
            #content td:nth-child(2) {
                padding-left: 10px;
            }
            .content-title {
                text-align: center;
                font-weight: bold;
            }
            #input-title {
               
                width: 600px;
                height: 30px;
            }

            .content-btn {
                text-align: center;
            }
            .btn {
                width: 60px;
                height: 30px;
                display: inline-block;
            }
        </style>
        `;

        tag +=
        `
        <table id="nav">
            <tr>
                <td>
                    <span id="year"></span>년
                    <span id="month"></span>월
                    <span id="day"></span>일 다이어리 작성
                </td>
            </tr>
        </table>

        <table id="content">
            <tr>
                <td class="content-title">제목</td>
                <td>
                    <input id="input-title" type="text">
                </td>
            </tr>
            <tr>
                <td class="content-title">내용</td>
                <td class="content-td">
                    <textarea id="textarea-content" rows="20" cols="100"></textarea>
                </td>
            </tr>
            <tr>
                <td class="content-btn" colspan="2">
                    <button class="btn save">저장</button>
                    <button class="btn cancel">취소</button>
                </td>
            </tr>
        </table>
        `;

        $content.innerHTML = tag;

        console.log(data);
        let temp = data.split("-");
        let year = temp[0];
        let month = temp[1];
        let day = temp[2];

        document.querySelector("#year").innerText = year;
        document.querySelector("#month").innerText = month;
        document.querySelector("#day").innerText = day;


        document.querySelector(".btn.save").addEventListener("click", this.writePro);
        document.querySelector(".btn.cancel").addEventListener("click", this.cancel);

    }

    writePro = (event) => {
        let title = document.querySelector("#input-title").value;
        let content = document.querySelector("#textarea-content").value;
        let regDate = this.date;

        JsonDiary.getInstance().diaryWritePro(title, content, regDate);
        ControllerMain.getInstance().chagePage("page-content", null);
    }

    cancel = (event) => {
        ControllerMain.getInstance().chagePage("page-content", null);
    }

 
}

 


pageInfo.js

 

import { ControllerMain } from "./controllerMain.js";
import { JsonDiary } from "./jsonDiary.js";

export class PageInfo {
    execute(data) {

        let $content = document.querySelector("#content");

        let tag = "";
        tag +=
        `
        <style>
            #nav {
                margin: 0 auto;
                width: 1000px;
                height: 80px;
                border-bottom: 1px solid #333333;
            }

            #content {
                margin: 0 auto;
                width: 1000px;
                height: 450px;
            }
            #content td {
                border-bottom: 1px solid #333333;
            }
            #content td:nth-child(1) {
                height: 70px;
                width: 50px;
            }
            #content td:nth-child(2) {
                padding-left: 10px;
            }
            .content-title {
                text-align: center;
                font-weight: bold;
            }
            #input-title {
               
                width: 600px;
                height: 30px;
            }

            .content-btn {
                text-align: center;
            }
            .btn {
                width: 100px;
                height: 30px;
                display: inline-block;
            }
        </style>
        `;

        tag +=
        `
        <table id="nav">
            <tr>
                <td>
                    <span id="year"></span>년
                    <span id="month"></span>월
                    <span id="day"></span>일 다이어리 작성
                </td>
            </tr>
        </table>

        <table id="content">
            <tr>
                <td class="content-title">제목</td>
                <td>
                    <input id="input-title" type="text">
                </td>
            </tr>
            <tr>
                <td class="content-title">내용</td>
                <td class="content-td">
                    <textarea id="textarea-content" rows="20" cols="100"></textarea>
                </td>
            </tr>
            <tr>
                <td class="content-btn" colspan="2">
                    <button class="btn cancel">뒤로가기</button>
                </td>
            </tr>
        </table>
        `;

        $content.innerHTML = tag;

        let diaryNo = Number(data);
        let diaryInfo = JsonDiary.getInstance().getDiaryInfo(diaryNo);
        console.log(diaryInfo);

        let temp = diaryInfo.regDate.split("-");
        let year = temp[0];
        let month = temp[1];
        let day = temp[2];
        document.querySelector("#year").innerText = year;
        document.querySelector("#month").innerText = month;
        document.querySelector("#day").innerText = day;

        document.querySelector("#input-title").value = diaryInfo.title;
        document.querySelector("#textarea-content").value = diaryInfo.content;

        document.querySelector(".btn.cancel").addEventListener("click", this.cancel);
    }

    cancel = (event) => {
        ControllerMain.getInstance().chagePage("page-content", null);
    }

}