CSS&JS/⚡Thinkers

[vanilla JS] json 값으로 html fetch이후 table 만들어서 뿌리기

arancia_ 2021. 9. 29. 10:43

깃허브 주소 : https://github.com/OhIkmyeong/tableJson

 

GitHub - OhIkmyeong/tableJson: json으로 테이블 만들기

json으로 테이블 만들기. Contribute to OhIkmyeong/tableJson development by creating an account on GitHub.

github.com

 

버튼을 누르면 html을 include하고, 그 이후 해당 html안의 table의 dataset값에 맞게, json 파일의 내용으로 테이블에 들어갈 내용물을 그려서 해당 테이블에 넣어준다.

 

폴더 구조 :

 

 

HTML

별거 없다. 버튼 누르면 wrapper에 include_wrapper.html을 불러와 넣어줄거다. 굳이 이렇게 하는 이유는 현재 하는 프로젝트가 fetch이후에 그 테이블에 값을 그려서 넣어줄거기 땜시롱..ㅡㅡ..

그렇지 않다면 그냥 바로 json만 fetch해서 그려주고 wrapper 때려박는게 사실 더 현명하긴 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<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>table JSON</title>
<link rel="stylesheet" type="text/css" href="./css/reset.css"/>
<link rel="stylesheet" type="text/css" href="./css/table.css"/>
<script src="./js/main.js" type="module"></script>
</head>
<body>
    
<button id="btn" data-url="include_wrapper" data-tbl="tbl_1"><span>어디 한번 그려봐라 json으로 만든 table을...</span></button>
 
<div id="wrapper">
    
</div><!-- wrapper -->
</body>
</html>
cs



CSS는 생략



main.js

1
2
3
4
5
6
7
8
9
import { display_wrapper } from "./fetch.js";
 
const btn = document.getElementById('btn');
 
btn.addEventListener('click',(e)=>{
    e = e || window.event;
    const target = e.target;
    display_wrapper(target);
});
cs



fetch.js

include_wrapper.html을 fetch해온다
include_wrapper.html의 내용은 좃도 아무것도 없고 그냥

<!-- 목록 테이블 -->
<table class="tbl list" data-tbl_name='listTable'>
</table>

<!-- 상세보기 테이블 -->
<table class="tbl crud" data-tbl_name='viewTable'>
</table>

이게 리얼 끝이다. data-tbl_name 값에 맞게 json을 뿌려줄거라 부모만 쳐넣은거다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { display_table } from "./table.js";
 
export async function display_wrapper(target){
    const wrapper = document.getElementById('wrapper');
    
    const data = await fetch_wrapper(target);
    wrapper.innerHTML = data;
    
    const myJson = await fetch_json(target);
    display_table(myJson);
}//display_wrapper
 
function fetch_wrapper(target){
    const URL = target.dataset.url;
    const full_url = `./include/${URL}.html`;
 
    const data = fetch(full_url).then(res=>res.text());
    return data;
}//fetch_wrapper
 
function fetch_json(target){
    const URL = target.dataset.tbl;
    const full_url = `./data/${URL}.json`;
 
    const data = fetch(full_url).then(res => res.json());
    return data;
}//fetch_json
cs

 

 

table.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
let this_tr;
 
export function display_table(myJson){
    for(let key in myJson){
        make_table(key,myJson);
    }//for
}//display_table
 
function make_table(key,myJson){
    const what_tbl = document.querySelector(`[data-tbl_name="${key}"]`);
    const {info, content= {...myJson[key]};
 
    //colgroup 넣기
    add_colgroup(info,what_tbl);
 
    //caption,thead,tbody,tfoot
    add_table_content(content,what_tbl);
}//make_table
 
function add_colgroup(info,what_tbl){
    const col_group = document.createElement('COLGROUP');
    for(let styl of info.styles){
        const col = document.createElement('COL');
        if(styl){col.style.width = styl;}
        col_group.appendChild(col);
    }//for
    what_tbl.appendChild(col_group);
}//add_colgroup
 
function add_table_content(content,what_tbl){
    for(let obj of content){
        switch(obj.EL){
            case "CAPTION" :
                add_caption(obj,what_tbl);
                break;
            default:
                add_thead_to_tfoot(obj,what_tbl);
                break;
        }//switch
    }//for
}//add_table_content
 
function add_caption(obj,what_tbl){
    const caption = document.createElement('CAPTION');
    caption.innerText = obj.ctnt;
    what_tbl.appendChild(caption);
}//add_caption
 
function add_thead_to_tfoot(obj,what_tbl){
    const el_type = document.createElement(`${String(obj.EL)}`);
    add_th_td(obj.ctnt,el_type);
    what_tbl.appendChild(el_type);
}//add_thead_to_tfoot;
 
function add_th_td(content,el_type){
    for(let ctn of content){
        //시작 TD/TH면 TR 만들고
        if(ctn.row_START){this_tr = document.createElement('TR');}
        
        //TD 생성하고 내용 채워넣고
        const this_el = document.createElement(`${ctn.EL}`);
        this_el.innerHTML = ctn.ctnt;
        
        //colspan이나 rowspan 있음 적용하고
        if(ctn["isSpan"]){
            const span_type = ctn["isSpan"]; 
            const span_num = String(ctn["spanNum"]);
            this_el.setAttribute(span_type,span_num);
        }//if
 
        //텍스트 정렬 스타일 있으면 적용하고
        if(ctn["textAlign"]){this_el.style.textAlign = "left";}
 
        //TR에 TD/TH append
        this_tr.appendChild(this_el);
 
        //마지막 TD/TH면 TR을 부모에 append
        if(ctn.row_END){
            el_type.appendChild(this_tr);}
    }//for
}//add_th_td
 
cs

 

마지막으로 table의 데이터를 담고있는 json구조는 대략 이러하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
{
    "listTable" : {
        "info" : {
            "colNum" : 6
            ,"styles" : ["80px","100px",null,"100px","120px","100px"]
        },
        "content" : [
            {
                "EL" : "CAPTION"
                ,"ctnt" : "이것은 목록 테이블입니다."
            },
            {
                "EL" : "THEAD"
                ,"ctnt" : [
                    {"row_START" : true,"EL" : "TH""ctnt" : "번호"}
                    ,{"EL" : "TH""ctnt" : "카테고리"}
                    ,{"EL" : "TH""ctnt" : "제목"}
                    ,{"EL" : "TH""ctnt" : "작성자"}
                    ,{"EL" : "TH""ctnt" : "작성일"}
                    ,{"row_END" : true,"EL" : "TH""ctnt" : "조회수"}
                ]
            },
            {
                "EL" : "TBODY"
                ,"ctnt" : [
                    {"row_START" : true,"EL" : "TD""ctnt" : 111}
                    ,{"EL" : "TD""ctnt" : "카테고리_1"}
                    ,{"EL" : "TD""ctnt" : "이곳에 제목을 출력 001","textAlign":"left"}
                    ,{"EL" : "TD""ctnt" : "홍길동"}
                    ,{"EL" : "TD""ctnt" : "2021-09-28"}
                    ,{"row_END" : true"EL" : "TD""ctnt" : "1111"}
 
 
 
                    ,{"row_START" : true,"EL" : "TD""ctnt" : 222}
                    ,{"EL" : "TD""ctnt" : "카테고리_2"}
                    ,{"EL" : "TD""ctnt" : "이곳에 제목을 출력 001","textAlign":"left"}
                    ,{"EL" : "TD""ctnt" : "홍길동"}
                    ,{"EL" : "TD""ctnt" : "2021-09-28"}
                    ,{"row_END" : true"EL" : "TD""ctnt" : "2222"}
 
 
                    
                    ,{"row_START" : true,"EL" : "TD""ctnt" : 333}
                    ,{"EL" : "TD""ctnt" : "카테고리_3"}
                    ,{"EL" : "TD""ctnt" : "이곳에 제목을 출력 001","textAlign":"left"}
                    ,{"EL" : "TD""ctnt" : "홍길동"}
                    ,{"EL" : "TD""ctnt" : "2021-09-28"}
                    ,{"row_END" : true"EL" : "TD""ctnt" : "3333"}
                ]
            }
        ]
    },
 
    "viewTable" : {
        "info" : {
            "colNum" : 5
            ,"styles" : ["20%"null"20%"null , null]
        },
        "content" : [
            {"EL" : "CAPTION""ctnt" : "내용 테이블"},
            {"EL" : "TBODY",
             "ctnt" : [
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
                
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "colSpan 예제"},
                {"row_END" : true"EL" : "TD""ctnt" : "colSpan...!""isSpan" : "colSpan""spanNum" : 4},
 
                {"row_START" : true"EL" : "TH""ctnt" : "colSpan 예제"},
                {"EL" : "TD""ctnt" : "colSpan...!""isSpan" : "colSpan""spanNum" : 3},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
                {"row_START" : true"EL" : "TH""ctnt" : "colSpan 예제"},
                {"row_END" : true"EL" : "TD""ctnt" : "colSpan...!""isSpan" : "colSpan""spanNum" : 4},
 
                
                
                {"row_START" : true"EL" : "TH""ctnt" : "rowSpan 예제""isSpan" : "rowSpan""spanNum" : 4},
                {"EL" : "TD""ctnt" : "평범한 TD_1"},
                {"EL" : "TH""ctnt" : "평범한 TD_1"},
                {"EL" : "TD""ctnt" : "평범한 TD_1"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_1"},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_2"},
                {"EL" : "TH""ctnt" : "평범한 TD_2"},
                {"EL" : "TD""ctnt" : "평범한 TD_2"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_2"},
                
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_3"},
                {"EL" : "TH""ctnt" : "평범한 TD_3"},
                {"EL" : "TD""ctnt" : "평범한 TD_3"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_3"},
                
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_4"},
                {"EL" : "TH""ctnt" : "평범한 TD_4"},
                {"EL" : "TD""ctnt" : "평범한 TD_4"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_4"},
 
                
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD""isSpan" : "colSpan""spanNum" : 2},
 
 
 
                {"row_START" : true"row_END" : true"EL" : "TH""ctnt" : "평범한 TH""isSpan" : "colSpan""spanNum" : 5},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
                
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "rowSpan 예제""isSpan" : "rowSpan""spanNum" : 3},
                {"row_END" : true"EL" : "TD""ctnt" : "colSpan...!""isSpan" : "colSpan""spanNum" : 4},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
                
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "rowSpan 예제""isSpan" : "rowSpan""spanNum" : 3},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "rowSpan 예제""isSpan" : "rowSpan""spanNum" : 4},
                {"row_END" : true"EL" : "TD""ctnt" : "colSpan...!""isSpan" : "colSpan""spanNum" : 4},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_2"},
                {"EL" : "TH""ctnt" : "평범한 TH_2""isSpan" : "rowSpan""spanNum" : 3},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_2""isSpan" : "colSpan""spanNum" : 2},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_3"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_3""isSpan" : "colSpan""spanNum" : 2},
 
                {"row_START" : true"EL" : "TD""ctnt" : "평범한 TD_4"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD_4""isSpan" : "colSpan""spanNum" : 2},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"},
 
 
 
                {"row_START" : true"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"EL" : "TH""ctnt" : "평범한 TH"},
                {"EL" : "TD""ctnt" : "평범한 TD"},
                {"row_END" : true"EL" : "TD""ctnt" : "평범한 TD"}
 
            ]}
        ]
    }
}
cs

 

row_START값이 오면 tr을 만들고, row_END값이 오면 부모에 tr을 appendChild한다.
어제는 하루종일 그냥 spanNum값으로 info의 colNUM값에 따라 자동으로 tr을 만들고 append하고 골머리 썩었는디
이게.. 수포자의 한계인지 colspan같은 경우엔 문제가 없었지만 rowspan일 때 하나 성공하면 다음 변수에서 지ㅡ랄 나고.. 두개 성공하면 세번쨰에서 쌈바를 추고... 그래서 걍 무식한 해결방법을 택함.

이렇게 하면 json짤 때 인간이 짜증은 나지만 온갖 변수에 완벽하게 대응된다(고 생각함)

참 별거없다.