diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..fd5106ff2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_STORE diff --git a/README.md b/README.md index e97a1d649..0cbdb1158 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,94 @@ -# ๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜ - -## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ - -### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ์—ญ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹จ, ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์€ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค) -- ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. -- ์ง€ํ•˜์ฒ  ์—ญ์€ 2๊ธ€์ž ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค. -- ์ง€ํ•˜์ฒ  ์—ญ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. - -### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. -- ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ๋…ธ์„  ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. -- ๋…ธ์„  ๋“ฑ๋ก ์‹œ ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. - -### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๊ตฌ๊ฐ„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋…ธ์„ ์— ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค. - - ์—ญ๊ณผ ์—ญ์‚ฌ์ด๋ฅผ ๊ตฌ๊ฐ„์ด๋ผ ํ•˜๊ณ  ์ด ๊ตฌ๊ฐ„๋“ค์˜ ๋ชจ์Œ์ด ๋…ธ์„ ์ด๋‹ค. -- ํ•˜๋‚˜์˜ ์—ญ์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋…ธ์„ ์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋‹ค. -- ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ์—ญ์ด ์ถ”๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. -- ๋…ธ์„ ์—์„œ ๊ฐˆ๋ž˜๊ธธ์€ ์ƒ๊ธธ ์ˆ˜ ์—†๋‹ค. - - - -### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์‚ญ์ œ ๊ธฐ๋Šฅ -- ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค. -- ์ข…์ ์„ ์ œ๊ฑฐํ•  ๊ฒฝ์šฐ ๋‹ค์Œ ์—ญ์ด ์ข…์ ์ด ๋œ๋‹ค. -- ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์ด ๋‘๊ฐœ ์ดํ•˜์ผ ๋•Œ๋Š” ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†๋‹ค. - - - -### ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ ์กฐํšŒ ๊ธฐ๋Šฅ -- ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ๋ถ€ํ„ฐ ํ•˜ํ–‰ ์ข…์ ๊นŒ์ง€ ์—ฐ๊ฒฐ๋œ ์ˆœ์„œ๋Œ€๋กœ ์—ญ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. - -
- -## ๐Ÿ’ป ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ - -### ์—ญ๊ด€๋ฆฌ - - -### ๋…ธ์„ ๊ด€๋ฆฌ - - -### ๊ตฌ๊ฐ„๊ด€๋ฆฌ - - -### ๋…ธ์„ ๋„ ์ถœ๋ ฅ - - - -## โœ… ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ - -### ๋ฉ”๋‰ด ๋ฒ„ํŠผ -- ์—ญ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#station-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ๋…ธ์„  ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#line-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#section-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#map-print-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - -### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ์—ญ์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#station-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” button ํƒœ๊ทธ๋Š” `#station-add-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ์—ญ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.station-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - -### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#line-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-start-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ํ•˜ํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-end-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์ถ”๊ฐ€ํ•˜๋Š” button ํƒœ๊ทธ๋Š” `#line-add-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.line-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - -### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์„ ํƒํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-line-menu-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์„ค์ •ํ•  ์—ญ select ํƒœ๊ทธ๋Š” `#section-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#section-order-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ๋“ฑ๋กํ•˜๋Š” button ํƒœ๊ทธ๋Š” `#section-add-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. -- ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์ œ๊ฑฐํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - -### ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ธฐ๋Šฅ -- ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด `
` ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํƒœ๊ทธ ๋‚ด๋ถ€์— ๋…ธ์„ ๋„๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. - -### ๊ธฐ์กด ์š”๊ตฌ์‚ฌํ•ญ - -- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ์ž…๋ ฅ ๊ฐ’์„ ์ž‘์„ฑํ•œ ๊ฒฝ์šฐ `alert`์„ ์ด์šฉํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์žฌ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. -- ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(jQuery, Lodash ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ˆœ์ˆ˜ Vanilla JS๋กœ๋งŒ ๊ตฌํ˜„ํ•œ๋‹ค. -- **์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์ง€ํ‚ค๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ** ํ•œ๋‹ค - - [https://google.github.io/styleguide/jsguide.html](https://google.github.io/styleguide/jsguide.html) - - [https://ui.toast.com/fe-guide/ko_CODING-CONVENSION/](https://ui.toast.com/fe-guide/ko_CODING-CONVENTION) -- **indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ 3์ด ๋„˜์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 2๊นŒ์ง€๋งŒ ํ—ˆ์šฉ**ํ•œ๋‹ค. - - ์˜ˆ๋ฅผ ๋“ค์–ด while๋ฌธ ์•ˆ์— if๋ฌธ์ด ์žˆ์œผ๋ฉด ๋“ค์—ฌ์“ฐ๊ธฐ๋Š” 2์ด๋‹ค. - - ํžŒํŠธ: indent(์ธ๋ดํŠธ, ๋“ค์—ฌ์“ฐ๊ธฐ) depth๋ฅผ ์ค„์ด๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋œ๋‹ค. -- **ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)์˜ ๊ธธ์ด๊ฐ€ 15๋ผ์ธ์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค.** - - ํ•จ์ˆ˜(๋˜๋Š” ๋ฉ”์†Œ๋“œ)๊ฐ€ ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ์ž˜ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. -- ๋ณ€์ˆ˜ ์„ ์–ธ์‹œ `var` ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. `const` ์™€ `let` ์„ ์‚ฌ์šฉํ•œ๋‹ค. - - [const](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) - - [let](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) -- `import` ๋ฌธ์„ ์ด์šฉํ•ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ชจ๋“ˆํ™”ํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค. - - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) -- `template literal`์„ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ์™€ html string์„ ๊ฐ€๋…์„ฑ ์ข‹๊ฒŒ ํ‘œํ˜„ํ•œ๋‹ค. - - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals) - -### ์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ -- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ html ํƒœ๊ทธ์— ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์˜ ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. -- [localStorage](https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage)๋ฅผ ์ด์šฉํ•˜์—ฌ, ์ƒˆ๋กœ๊ณ ์นจํ•˜๋”๋ผ๋„ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ž‘์—…ํ•œ ์ •๋ณด๋“ค์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. - -
- -## ๐Ÿ“ ๋ฏธ์…˜ ์ €์žฅ์†Œ ๋ฐ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ - -- ๋ฏธ์…˜์€ [https://github.com/woowacourse/javascript-subway-map-precours](https://github.com/woowacourse/javascript-subway-map-precourse) ์ €์žฅ์†Œ๋ฅผ fork/cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. -- **๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— javascript-subway-precourse/docs/README.md ํŒŒ์ผ์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก**์„ ์ •๋ฆฌํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. -- **git์˜ commit ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ README.md ํŒŒ์ผ์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„๋กœ ์ถ”๊ฐ€**ํ•œ๋‹ค. -- [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ๋ฌธ์„œ ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ ๋ฏธ์…˜์„ ์ œ์ถœํ•œ๋‹ค. +### 0. ๋ฉ”๋‰ด +- ์—ญ ๊ด€๋ฆฌ, ๋…ธ์„  ๊ด€๋ฆฌ, ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ, ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ ์ƒ์„ฑ +- ๊ฐ ๋ฒ„ํŠผ์— ํ•ด๋‹น๋˜๋Š” ํŽ˜์ด์ง€ ์ƒ์„ฑํ•ด์„œ ์ˆจ๊ธฐ๊ธฐ (์ฒ˜์Œ ๋กœ๋“œ ์‹œ ํŽ˜์ด์ง€๋Š” ๋ณด์ด๋ฉด ์•ˆ๋จ) +- ๊ฐ ๋ฒ„ํŠผ์€ ๊ด€๋ จ ํŽ˜์ด์ง€๋งŒ ๋ณด์ด๊ณ  ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋Š” ์ˆจ๊ธฐ๊ธฐ + +### 1. ์—ญ ๊ด€๋ฆฌ +- ์ฒ˜์Œ ์‹œ์ž‘์‹œ localStorage๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํŽ˜์ด์ง€ ๊ตฌ์„ฑ ์š”์†Œ ์ƒ์„ฑ +- ์—ญ ๊ด€๋ฆฌ ๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค ์—ญ ๋ชฉ๋ก ํ…Œ์ด๋ธ” ์ƒˆ๋กœ๊ณ ์นจ + +- ์—ญ ๋“ฑ๋ก ์˜ˆ์™ธ์‚ฌํ•ญ + - ์—ญ ์ด๋ฆ„์ด ํ•œ๊ธ€์ž ์ดํ•˜์ธ ๊ฒฝ์šฐ + - ์—ญ ์ด๋ฆ„์ด ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ +- ์—ญ ์ด๋ฆ„์˜ ๊ณต๋ฐฑ ๋ชจ๋‘ ์ œ๊ฑฐ +- ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก ๋์— ์ถ”๊ฐ€ +- localStorage์— ์—ญ ๋ชฉ๋ก ์ƒˆ๋กœ ์ €์žฅ +- ์—ญ ๋ชฉ๋ก ํ…Œ์ด๋ธ” ํ•˜๋‹จ์— row ์ถ”๊ฐ€ + +- ์—ญ ์‚ญ์ œ ์˜ˆ์™ธ์‚ฌํ•ญ + - ๋…ธ์„ ์— ๋“ฑ๋ก๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ +- ์‚ญ์ œ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ํ™•์ธ์ฐฝ ๋„์šฐ๊ธฐ +- localStorage์— ์—ญ ๋ชฉ๋ก ์ƒˆ๋กœ ์ €์žฅ +- ์‚ญ์ œ๋œ ์—ญ row๋ฅผ ํ…Œ์ด๋ธ”์—์„œ ์ œ๊ฑฐ + - ์‚ญ์ œ ๋ฒ„ํŠผ์˜ dataset์œผ๋กœ row ์ฐพ๊ธฐ + +
+ +### 2. ๋…ธ์„  ๊ด€๋ฆฌ +- ์ฒ˜์Œ ์‹œ์ž‘์‹œ localStorage๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํŽ˜์ด์ง€ ๊ตฌ์„ฑ ์š”์†Œ ์ƒ์„ฑ + +- ๋…ธ์„  ๊ด€๋ฆฌ ๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค + - ์ƒํ–‰ ํ•˜ํ–‰ selector ๋ชฉ๋ก ์ƒˆ๋กœ๊ณ ์นจ + - ๋…ธ์„  ๋ชฉ๋ก ํ…Œ์ด๋ธ” ์ƒˆ๋กœ๊ณ ์นจ + +- ๋…ธ์„  ๋“ฑ๋ก ์˜ˆ์™ธ์‚ฌํ•ญ + - ๋…ธ์„  ์ด๋ฆ„์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ + - ๋…ธ์„  ์ด๋ฆ„์ด ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ + - ์ƒํ–‰ ์ข…์ ๊ณผ ํ•˜ํ–‰ ์ข…์ ์ด ๊ฐ™์€ ๊ฒฝ์šฐ +- ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ ์„ ํƒ + - ์ƒํ–‰๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ selector์˜ ๊ธฐ๋ณธ์€ ์ฒซ ์—ญ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ + - ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์€ ์—ญ ๋ชฉ๋ก ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ +- ๋…ธ์„  ์ด๋ฆ„์˜ ๊ณต๋ฐฑ ๋ชจ๋‘ ์ œ๊ฑฐ +- ๋…ธ์„  ๋ชฉ๋ก ๋์— ์ถ”๊ฐ€ +- ์—ญ ๋ชฉ๋ก์— ํ•ด๋‹น ์—ญ์˜ ๋…ธ์„  ์ •๋ณด ์ถ”๊ฐ€ +- ๋…ธ์„  ๋ชฉ๋ก๊ณผ ์—ญ ๋ชฉ๋ก localStorage์— ์ƒˆ๋กœ ์ €์žฅ +- ๋…ธ์„  ๋ชฉ๋ก ํ…Œ์ด๋ธ” ํ•˜๋‹จ์— row ์ถ”๊ฐ€ + +- ์ง€ํ•˜์ฒ  ๋…ธ์„  ์‚ญ์ œ +- ์‚ญ์ œ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ํ™•์ธ์ฐฝ ๋„์šฐ๊ธฐ +- ์—ญ ๋ชฉ๋ก์—์„œ ํ•ด๋‹น ์—ญ์˜ ๋…ธ์„  ์ •๋ณด ์ œ๊ฑฐ +- ๋…ธ์„  ๋ชฉ๋ก๊ณผ ์—ญ ๋ชฉ๋ก localStorage์— ์ƒˆ๋กœ ์ €์žฅ +- ๋…ธ์„  ๋ชฉ๋ก ํ…Œ์ด๋ธ”์—์„œ ํ•ด๋‹น row๋ฅผ ์ œ๊ฑฐ + - ์‚ญ์ œ ๋ฒ„ํŠผ์˜ dataset์œผ๋กœ row ์ฐพ๊ธฐ + +
+ +### 3. ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ +- ์ฒ˜์Œ ์‹œ์ž‘์‹œ localStorage๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํŽ˜์ด์ง€ ๊ตฌ์„ฑ ์š”์†Œ ์ƒ์„ฑ + +- ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ ๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค + - ๊ฐ ๋…ธ์„ ๋ณ„๋กœ ๋ฒ„ํŠผ ์ƒˆ๋กœ ์ƒ์„ฑ + - selector ๋ชฉ๋ก ์ƒˆ๋กœ๊ณ ์นจ + +- ๋…ธ์„  ๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค + - ๋…ธ์„  ๊ตฌ๊ฐ„ ํ…Œ์ด๋ธ” ์ƒˆ๋กœ๊ณ ์นจ + +- ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ์˜ˆ์™ธ์‚ฌํ•ญ + - ์ˆœ์„œ๊ฐ€ ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ + - ์ˆœ์„œ๊ฐ€ ์Œ์ˆ˜์ธ ๊ฒฝ์šฐ + - ์ˆœ์„œ๊ฐ€ ์ข…์ ์—ญ ์ˆœ์„œ๋ณด๋‹ค 1๋„˜๊ฒŒ ํฐ ๊ฒฝ์šฐ (์—ฐ์†์ ์ด์ง€ ์•Š์€ ์ˆœ์„œ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒฝ์šฐ) + - ์ด๋ฏธ ๋“ฑ๋ก๋œ ์—ญ์ธ ๊ฒฝ์šฐ +- ์ž…๋ ฅํ•œ ์ˆœ์„œ ์ดํ›„์˜ ์ˆœ์„œ๋Š” ๋ฐ€๋ฆผ (์ˆœ์„œ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š์Œ) +- ๋…ธ์„  ๋ชฉ๋ก์—์„œ, ํ•ด๋‹น๋˜๋Š” ๋…ธ์„ ์˜ ์—ญ ๋ฆฌ์ŠคํŠธ์—, ํ•ด๋‹น๋˜๋Š” ์ˆœ์„œ๋กœ ์—ญ ๋“ฑ๋ก +- ์—ญ ๋ชฉ๋ก์— ํ•ด๋‹น ์—ญ์˜ ๋…ธ์„  ์ •๋ณด ์ถ”๊ฐ€ +- ๋…ธ์„  ๋ชฉ๋ก๊ณผ ์—ญ ๋ชฉ๋ก localStorage์— ์ƒˆ๋กœ ์ €์žฅ +- ํ˜ธ์„ ๋ณ„ ์—ญ ๋ชฉ๋ก ํ…Œ์ด๋ธ”์— ํ•ด๋‹น๋˜๋Š” ์ˆœ์„œ row ์ถ”๊ฐ€ + +- ๊ตฌ๊ฐ„ ์ œ๊ฑฐ ์˜ˆ์™ธ์‚ฌํ•ญ + - ํ•ด๋‹น ํ˜ธ์„ ์˜ ์—ญ์ด ๋‘๊ฐœ ์ดํ•˜์ธ ๊ฒฝ์šฐ๋Š” ๋…ธ์„ ์—์„œ ์—ญ ์ œ๊ฑฐ ๋ถˆ๊ฐ€ +- ๋…ธ์„  ๋ชฉ๋ก์—์„œ ํ•ด๋‹น ํ˜ธ์„ ์˜ ํ•ด๋‹น ์—ญ ์ œ๊ฑฐ +- ์—ญ ๋ชฉ๋ก์—์„œ ํ•ด๋‹น ์—ญ์˜ ๋…ธ์„  ์ •๋ณด ์ œ๊ฑฐ +- ๋…ธ์„  ๋ชฉ๋ก๊ณผ ์—ญ ๋ชฉ๋ก localStorage์— ์ƒˆ๋กœ ์ €์žฅ +- ํ˜ธ์„ ๋ณ„ ์—ญ ๋ชฉ๋ก ํ…Œ์ด๋ธ”์—์„œ ํ•ด๋‹น๋˜๋Š” ์ˆœ์„œ row ์ œ๊ฑฐ + +### 4. ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ +- ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค + - ํ˜ธ์„ ๊ณผ ํ•ด๋‹น๋˜๋Š” ์—ญ์„ ์ˆœ์„œ๋Œ€๋กœ ํ™”๋ฉด์— ์ƒˆ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ + +### 5. LocalStorage +- stationList ๊ฐ์ฒด + - key: ์—ญ์ด๋ฆ„ + - value: ์—ญ์ด ๋“ฑ๋ก๋œ ๋…ธ์„  ๋ฐฐ์—ด +- lineList ๊ฐ์ฒด + - key: ๋…ธ์„ ์ด๋ฆ„ + - value: ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ ๋ฐฐ์—ด \ No newline at end of file diff --git a/src/common_utils.js b/src/common_utils.js new file mode 100644 index 000000000..7742c14ed --- /dev/null +++ b/src/common_utils.js @@ -0,0 +1,82 @@ +import DomUtils from './dom_utils.js'; + +export default class CommonUtils { + constructor() { + this._privateDomUtils = new DomUtils(); + } + + alertError(errorMessage) { + alert(errorMessage); + } + + createDiv(toIdName, idName) { + const div = document.createElement('div'); + + this._privateDomUtils.setAttribute('id', div, idName); + this._privateDomUtils.appendToIdName(toIdName, div); + } + + createTitle(titleTag, titleContent, toIdName) { + const title = document.createElement(titleTag); + + title.innerHTML = titleContent; + this._privateDomUtils.appendToIdName(toIdName, title); + } + + createUnorderedList(stationList, toIdName) { + const list = document.createElement('ul'); + + this._privateDomUtils.appendToIdName(toIdName, list); + + for (const station of stationList) { + this.createListElement(list, station); + } + } + + createListElement(list, station) { + const element = document.createElement('li') + + element.innerHTML = station; + this._privateDomUtils.appendToVarName(list, element); + } + + insertEmptyline(toIdName) { + const newline = document.createElement('br'); + + this._privateDomUtils.appendToIdName(toIdName, newline); + } + + getLocalStorageStation() { + const stationList = JSON.parse(localStorage.getItem('stationList')); + + if (!stationList) { + return {}; + } + + return stationList; + } + + getLocalStorageLine() { + const lineList = JSON.parse(localStorage.getItem('lineList')); + + if (!lineList) { + return {}; + } + + return lineList; + } + + saveToLocalStorage(datasetName, data) { + localStorage.setItem(datasetName, JSON.stringify(data)); + } + + renewSelect(idName) { + const select = document.getElementById(idName); + + select.value = select.firstChild.value; + } + + emptyInput(input) { + input.value = ''; + } +} \ No newline at end of file diff --git a/src/dom_utils.js b/src/dom_utils.js new file mode 100644 index 000000000..075c2332d --- /dev/null +++ b/src/dom_utils.js @@ -0,0 +1,74 @@ +export default class DomUtils { + constructor() { + this.DO_NOT_APPEND = false; + this.ID_ATTRIBUTE = 'id'; + } + + createButton(idName, buttonText) { + const button = document.createElement('button'); + + this.setAttribute(this.ID_ATTRIBUTE, button, idName); + this.setInnerHtml(button, buttonText); + + return button; + } + + createArticle(toIdName, idName) { + const article = document.createElement('ARTICLE'); + + this.setAttribute(this.ID_ATTRIBUTE, article, idName); + this.appendToIdName(toIdName, article); + + return article + } + + setAttribute(attribute, varName, attributeName) { + varName.setAttribute(attribute, attributeName); + } + + setInnerHtml(varName, buttonText) { + varName.innerHTML = buttonText; + } + + appendToIdName(toIdName, varName) { + document.getElementById(toIdName).appendChild(varName); + } + + appendToVarName(toVarName, varName) { + toVarName.appendChild(varName); + } + + appendBefore(toIdName, varName, before) { + const toVarName = document.getElementById(toIdName); + + toVarName.insertBefore(varName, before); + } + + displayNone(varName) { + varName.style.display = "none"; + } + + createInput(inputObject) { + const input = document.createElement('input'); + + this.setAttribute(inputObject['attribute'], input, inputObject['idName']); + this.setInputType(input, inputObject['type']); + this.setPlaceholder(input, inputObject['placeholder']); + this.appendToIdName(inputObject['toIdName'], input) + input.style.margin = '0 2px 0 2px'; + + return input; + } + + setInputType(input, type) { + input.setAttribute('type', type); + } + + setPlaceholder(input, placeholder) { + input.placeholder = placeholder; + } + + addDataAttribute(tag, trackingData) { + tag.setAttribute('data-tracking', trackingData); + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index e69de29bb..43a7bc448 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,22 @@ +import ManageStation from './manage_station.js'; +import Menu from './menu.js'; +import ManageLine from './manage_line.js'; +import ManageSection from './manage_section.js'; + +export default class SubwayMap { + constructor() { + document.body.style.fontFamily = 'Arial'; + + const menu = new Menu(); + const manageStation = new ManageStation(); + const manageLine = new ManageLine(); + const manageSection = new ManageSection(); + + menu.createMenu(); + manageLine.initPage(); + manageStation.initPage(); + manageSection.initPage(); + } +} + +new SubwayMap(); \ No newline at end of file diff --git a/src/manage_line.js b/src/manage_line.js new file mode 100644 index 000000000..2b69f4f14 --- /dev/null +++ b/src/manage_line.js @@ -0,0 +1,219 @@ +import CommonUtils from "./common_utils.js"; +import DomUtils from "./dom_utils.js"; +import TableUtils from "./table_utils.js"; +import SelectUtils from "./select_utils.js"; +import StringUtils from "./string_utils.js"; + +export default class ManageLine { + setPrivateVariables() { + this._privateCommonUtils = new CommonUtils(); + this._privateDomUtils = new DomUtils(); + this._privateTableUtils = new TableUtils(); + this._privateSelectUtils = new SelectUtils(); + this._privateStringUtils = new StringUtils(); + } + + setConst() { + this.ARTICLE_NAME = 'lineArticle'; + + this.LINE_INPUT_ID = 'line-name-input'; + this.LINE_INPUT_TITLE_TAG = 'div'; + this.LINE_INPUT_TITLE_TEXT = '๋…ธ์„  ์ด๋ฆ„'; + this.LINE_INPUT_PLACEHOLDER = '๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'; + this.LINE_INPUT_TYPE = 'String'; + + this.ADD_BUTTON_ID = 'line-add-button'; + this.ADD_BUTTON_TEXT = '๋…ธ์„  ์ถ”๊ฐ€'; + + this.LINE_LIST_TITLE_TAG = 'h2'; + this.LINE_LIST_TITLE_TEXT = '๐Ÿš‰ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก'; + + this.IS_VALID = 1; + this.IS_NOT_VALID = 0; + + this.DELETE_BUTTON_TEXT = '์‚ญ์ œ'; + this.IS_NOT_VALID = false; + this.IS_VALID = true; + + this.EMPTY_ERROR_MESSAGE = '๋…ธ์„  ์ด๋ฆ„์„ ํ•œ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'; + this.OVERLAP_ERROR_MESSAGE = '์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋…ธ์„  ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.' + this.SAME_START_END_ERROR_MESSAGE = '์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์ด ๊ฐ™์Šต๋‹ˆ๋‹ค.' + } + + initPage() { + this.setConst(); + this.setPrivateVariables(); + this.initLists(); + + this.createLineAddSection(); + this.createTableSection(); + } + + initLists() { + this._lineList = this._privateCommonUtils.getLocalStorageLine(); + this._stationList = this._privateCommonUtils.getLocalStorageStation(); + this._privateCommonUtils.insertEmptyline(this.ARTICLE_NAME); + } + + /* + * this.createLineAddSection() + */ + + createLineAddSection() { + this.createInputSection(); + this._privateSelectUtils.createSelectSection(this.ARTICLE_NAME); + this._privateCommonUtils.insertEmptyline(this.ARTICLE_NAME); + this.createLineAddButton(); + } + + createInputSection() { + this._privateCommonUtils.createTitle('div', this.LINE_INPUT_TITLE_TEXT, this.ARTICLE_NAME); + this.createLineInput(); + this._privateCommonUtils.insertEmptyline(this.ARTICLE_NAME); + } + + createLineInput() { + const inputObject = this.lineInputObject(); + + this._lineInput = this._privateDomUtils.createInput(inputObject); + } + + lineInputObject() { + const inputObject = { + 'attribute': 'id', + 'toIdName': this.ARTICLE_NAME, + 'idName': this.LINE_INPUT_ID, + 'placeholder': this.LINE_INPUT_PLACEHOLDER, + 'type': this.LINE_INPUT_TYPE, + } + + return inputObject; + } + + /* + * this.createLineAddButton() + */ + + createLineAddButton() { + this._lineAddButton = this._privateDomUtils.createButton(this.ADD_BUTTON_ID, this.ADD_BUTTON_TEXT); + this._privateDomUtils.appendToIdName(this.ARTICLE_NAME, this._lineAddButton); + this.addEventToButton(); + } + + addEventToButton() { + this._lineAddButton.addEventListener('click', () => { + this.createNewLine(); + }) + this._lineInput.addEventListener('keypress', e => { + if (e.keyCode === 13) { + this.createNewLine(); + } + }) + } + + createNewLine() { + this._lineInputValue = this._privateStringUtils.removeSpace(this._lineInput.value); + + if (this.checkLineValidity() === this.IS_VALID) { + this.updateAddToLocalStorage(); + this.addLine(); + this.renewLineUserInteractions(); + } + else { + this.alertCorrespondingError(); + } + } + + checkLineValidity() { + if (this.isEmpty() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + + if (this.overlap() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + + if (this.sameStartEnd() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + isEmpty() { + if (this._lineInputValue.length === 0) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + overlap() { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + if (this._lineInputValue in lineList) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + sameStartEnd() { + this.getSelect(); + if (this._startSelect.value === this._endSelect.value) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + alertCorrespondingError() { + if (this.isEmpty() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.EMPTY_ERROR_MESSAGE); + } + else if (this.overlap() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.OVERLAP_ERROR_MESSAGE); + } + else if (this.sameStartEnd() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.SAME_START_END_ERROR_MESSAGE); + } + + return this.IS_VALID; + } + + getSelect() { + this._startSelect = document.getElementById('line-start-station-selector'); + this._endSelect = document.getElementById('line-end-station-selector'); + } + + updateAddToLocalStorage() { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + const stationList = this._privateCommonUtils.getLocalStorageStation(); + lineList[this._lineInputValue] = [this._startSelect.value, this._endSelect.value]; + stationList[this._startSelect.value].push(this._lineInputValue); + stationList[this._endSelect.value].push(this._lineInputValue); + + this._privateCommonUtils.saveToLocalStorage('lineList', lineList); + this._privateCommonUtils.saveToLocalStorage('stationList', stationList); + } + + addLine() { + const rowArray = [this._lineInputValue, this._startSelect.value, this._endSelect.value, this.DELETE_BUTTON_TEXT]; + + this._privateTableUtils.addRow(rowArray, this.ARTICLE_NAME); + } + + renewLineUserInteractions() { + this._privateCommonUtils.emptyInput(this._lineInput); + this._privateCommonUtils.renewSelect('line-start-station-selector'); + this._privateCommonUtils.renewSelect('line-end-station-selector'); + } + + /* + * this.createTableSection() + */ + + createTableSection() { + this._privateCommonUtils.createTitle(this.LINE_LIST_TITLE_TAG, this.LINE_LIST_TITLE_TEXT, this.ARTICLE_NAME); + this._privateTableUtils.initTable(this.ARTICLE_NAME); + } +} \ No newline at end of file diff --git a/src/manage_map_print.js b/src/manage_map_print.js new file mode 100644 index 000000000..d69d53b90 --- /dev/null +++ b/src/manage_map_print.js @@ -0,0 +1,30 @@ +import DomUtils from './dom_utils.js'; + +export default class ManageMapPrint { + emptyArticle(articleName) { + const mapArticle = document.getElementById(articleName); + + mapArticle.innerHTML = ''; + } + + displayMapPrint(articleName, commonUtils) { + const mapClass = this.createMapDiv(articleName); + const lineList = commonUtils.getLocalStorageLine(); + + for (const line in lineList) { + commonUtils.createTitle('h3', line, mapClass); + commonUtils.createUnorderedList(lineList[line], mapClass); + } + } + + createMapDiv(articleName) { + const domUtils = new DomUtils(); + const mapDiv = document.createElement('div'); + + domUtils.setAttribute('class', mapDiv, 'map'); + domUtils.setAttribute('id', mapDiv, 'map'); + domUtils.appendToIdName(articleName, mapDiv); + + return 'map'; + } +} \ No newline at end of file diff --git a/src/manage_section.js b/src/manage_section.js new file mode 100644 index 000000000..cfc22c4d1 --- /dev/null +++ b/src/manage_section.js @@ -0,0 +1,301 @@ +import TableUtils from './table_utils.js'; +import DomUtils from './dom_utils.js'; +import CommonUtils from './common_utils.js'; +import SelectUtils from './select_utils.js'; +import StringUtils from './string_utils.js'; + +export default class ManageSection { + setPrivateVariables() { + this._privateTableUtils = new TableUtils(); + this._privateDomUtils = new DomUtils(); + this._privateCommonUtils = new CommonUtils(); + this._privateSelectUtils = new SelectUtils(); + this._privateStringUtils = new StringUtils(); + } + + setConst() { + this.IS_VALID = 1; + this.IS_NOT_VALID = 0; + + this.ARTICLE_NAME = 'sectionArticle'; + this.SELECT_LINE_SECTION = 'selectLineSection'; + this.MANAGE_LINE_SECTION = 'manageLineSection'; + this.LINE_TABLE_SECTION = 'sectionManageArea'; + + this.SELECT_LINE_TITLE_TAG = 'h3'; + this.SELECT_LINE_TITLE = '๊ตฌ๊ฐ„์„ ์ˆ˜์ •ํ•  ๋…ธ์„ ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”'; + + this.MANAGE_LINE_TITLE_TAG = 'h3'; + this.MANAGE_LINE_TITLE = ' ๊ด€๋ฆฌ'; + + this.ADD_SECTION_TITLE_TAG = 'h4'; + this.ADD_SECTION_TITLE = '๊ตฌ๊ฐ„ ๋“ฑ๋ก'; + + this.SECTION_ORDER_INPUT_PLACEHOLDER = '์ˆœ์„œ'; + this.SECTION_DELETE_TEXT = '๋…ธ์„ ์—์„œ ์ œ๊ฑฐ'; + + this.LINE_BUTTONS_CLASS = 'line-button'; + this.SELECT_LINE_BUTTON_CLASS = 'section-line-menu-button'; + this.DELETE_BUTTON_CLASS = 'section-delete-button'; + + this.SECTION_STATION_SELECTOR = 'section-station-selector'; + this.SECTION_ORDER_INPUT = 'section-order-input'; + this.ADD_BUTTON = 'section-add-button'; + this.ADD_BUTTON_TEXT = '๋“ฑ๋ก'; + + this.IS_EMPTY_ERROR_MESSAGE = '์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'; + this.IS_NEGATIVE_ERROR_MESSAGE = '์Œ์ˆ˜๊ฐ€ ์•„๋‹Œ ์ •์ˆ˜ ์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'; + this.IS_NOT_CONSECUTIVE_ERROR_MESSAGE = '๊ธฐ์กด ์ˆœ์„œ๋“ค๊ณผ ์—ฐ์†๋˜๋Š” ์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'; + this.IS_ALREADY_REGISTERED_ERROR_MESSAGE = '์ด๋ฏธ ๋“ฑ๋ก๋˜์–ด์žˆ๋Š” ์—ญ์ž…๋‹ˆ๋‹ค.'; + } + + getLocalStorage() { + this._lineList = this._privateCommonUtils.getLocalStorageLine(); + this._stationList = this._privateCommonUtils.getLocalStorageStation(); + } + + initPage() { + this.setPrivateVariables(); + this.setConst(); + this.getLocalStorage(); + + this.createSelectLineSection(); + this.createManageLineSection(); + this.createManageLineSectionTable(); + } + + /* + * createSelectLineSection() + */ + + createSelectLineSection() { + this._privateCommonUtils.createDiv(this.ARTICLE_NAME, this.SELECT_LINE_SECTION); + this._privateCommonUtils.createTitle(this.SELECT_LINE_TITLE_TAG, this.SELECT_LINE_TITLE, this.SELECT_LINE_SECTION); + this.createLineButtons(); + } + + createLineButtons() { + this.setPrivateVariables(); + this.setConst(); + const lineList = this._privateCommonUtils.getLocalStorageLine(); + + for (const line in lineList) { + const button = this._privateDomUtils.createButton(`${line}Button`, line); + + this._privateDomUtils.appendToIdName(this.SELECT_LINE_SECTION, button); + button.style.margin = "2px"; + this._privateDomUtils.setAttribute('class', button, this.LINE_BUTTONS_CLASS); + this.addEventToLineSelectButton(button, line); + } + } + + addEventToLineSelectButton(button, line) { + button.addEventListener('click', () => { + this.showManageLineSection(); + this.changeManageLineSection(line); + }) + } + + showManageLineSection() { + const manageLineSection = document.getElementById(this.MANAGE_LINE_SECTION); + + manageLineSection.style.display = 'block'; + } + + changeManageLineSection(line) { + this.changeManageLineSectionTitle(line); + this.changeManageLineSectionTable(line); + } + + changeManageLineSectionTitle(line) { + const manageLineTitle = document.querySelector("#manageLineSection h3"); + + manageLineTitle.innerHTML = line + this.MANAGE_LINE_TITLE; + } + + changeManageLineSectionTable(line) { + this._privateTableUtils.refreshTableData(this.LINE_TABLE_SECTION, line); + } + + /* + * createManageLineSection() + */ + + createManageLineSection() { + this._privateCommonUtils.createDiv(this.ARTICLE_NAME, this.MANAGE_LINE_SECTION); + this._privateCommonUtils.createTitle(this.MANAGE_LINE_TITLE_TAG, this.MANAGE_LINE_TITLE, this.MANAGE_LINE_SECTION); + this.createSectionAddArea(); + this.hideManageLineSection(); + } + + hideManageLineSection() { + const manageLineSection = document.getElementById(this.MANAGE_LINE_SECTION); + + manageLineSection.style.display = 'none'; + } + + createSectionAddArea() { + this._privateCommonUtils.createTitle(this.ADD_SECTION_TITLE_TAG, this.ADD_SECTION_TITLE, this.MANAGE_LINE_SECTION); + this._privateSelectUtils.createSelect(this.MANAGE_LINE_SECTION, this.SECTION_STATION_SELECTOR, this._privateCommonUtils, this._privateDomUtils); + this.createSectionOrderInput(); + this.createSectionAddButton(); + } + + createSectionOrderInput() { + const inputObject = this.createInputObject(); + this._orderInput = this._privateDomUtils.createInput(inputObject); + } + + createInputObject() { + const inputObject = { + 'attribute': 'id', + 'toIdName': this.MANAGE_LINE_SECTION, + 'idName': this.SECTION_ORDER_INPUT, + 'placeholder': this.SECTION_ORDER_INPUT_PLACEHOLDER, + 'type': 'number', + } + + return inputObject; + } + + createSectionAddButton() { + const button = this._privateDomUtils.createButton(this.ADD_BUTTON, this.ADD_BUTTON_TEXT); + + this._privateDomUtils.appendToIdName(this.MANAGE_LINE_SECTION, button); + this.addEventToAddButton(button); + } + + addEventToAddButton(button) { + button.addEventListener('click', () => { + this.createNewSection(); + }) + this._orderInput.addEventListener('keypress', (e) => { + if (e.keyCode === 13) { + this.createNewSection(); + } + }) + } + + createNewSection() { + if (this.checkSectionValidity() === this.IS_VALID) { + const line = this.getCurrentLineFromTitle(); + + this.updateAddToLocalStorage(); + this._privateTableUtils.refreshTableData(this.LINE_TABLE_SECTION, line); + this.renewSectionUserInteractions(); + } + else { + this.alertCorrespondingError(); + } + } + + renewSectionUserInteractions() { + this._privateCommonUtils.renewSelect('section-station-selector'); + this._privateCommonUtils.emptyInput(this._orderInput); + } + + checkSectionValidity() { + if (this.isAlreadyRegistered() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID + } + if (this.isEmpty() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + if (this.isNegative() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + if (this.isNotConsecutive() === this.IS_NOT_VALID) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + isAlreadyRegistered() { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + const line = this.getCurrentLineFromTitle(); + const station = this.getSelectedStation(); + + if (lineList[line].includes(station)) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + isEmpty() { + if (!this._orderInput.value) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + isNegative() { + if (this._orderInput.value < 0) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + isNotConsecutive() { + const tbody = document.querySelector(`#${this.LINE_TABLE_SECTION}Table tbody`); + const rowCount = tbody.childElementCount; + + if (this._orderInput.value >= rowCount) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + alertCorrespondingError() { + if (this.isEmpty() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.IS_EMPTY_ERROR_MESSAGE); + } + else if (this.isNegative() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.IS_NEGATIVE_ERROR_MESSAGE); + } + else if (this.isNotConsecutive() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.IS_NOT_CONSECUTIVE_ERROR_MESSAGE); + } + else if (this.isAlreadyRegistered() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.IS_ALREADY_REGISTERED_ERROR_MESSAGE); + } + } + + updateAddToLocalStorage() { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + const stationList = this._privateCommonUtils.getLocalStorageStation(); + const line = this.getCurrentLineFromTitle(); + const station = this.getSelectedStation(); + + lineList[line].splice(this._orderInput.value, 0, station); + stationList[station].push(line); + + this._privateCommonUtils.saveToLocalStorage('lineList', lineList); + this._privateCommonUtils.saveToLocalStorage('stationList', stationList); + } + + getCurrentLineFromTitle() { + const title = document.querySelector("#manageLineSection h3"); + + return title.innerHTML.split(' ')[0]; + } + + getSelectedStation() { + return document.getElementById('section-station-selector').value; + } + + /* + * createManageLineSectionTable + */ + + createManageLineSectionTable() { + this._privateCommonUtils.createDiv(this.MANAGE_LINE_SECTION, this.LINE_TABLE_SECTION); + this._privateCommonUtils.insertEmptyline(this.LINE_TABLE_SECTION); + this._privateCommonUtils.insertEmptyline(this.LINE_TABLE_SECTION); + this._privateTableUtils.initTable(this.LINE_TABLE_SECTION); + } +} \ No newline at end of file diff --git a/src/manage_station.js b/src/manage_station.js new file mode 100644 index 000000000..fb6e152b7 --- /dev/null +++ b/src/manage_station.js @@ -0,0 +1,150 @@ +import DomUtils from './dom_utils.js'; +import TableUtils from './table_utils.js'; +import CommonUtils from './common_utils.js'; +import StringUtils from './string_utils.js'; + +export default class ManageStation { + setPrivateVariable() { + this._privateStringUtils = new StringUtils(); + this._privateDomUtils = new DomUtils(); + this._privateCommonUtils = new CommonUtils(); + this._privateTableUtils = new TableUtils(); + } + + setConst() { + this.ARTICLE_NAME = 'stationArticle'; + + this.MENU_TYPE = 'station', + this.ADD_TYPE = 'Add', + this.DELETE_TYPE = 'Delete', + + this.STATION_INPUT_TITLE_TAG = 'div'; + this.STATION_INPUT_TITLE_TEXT = '์—ญ ์ด๋ฆ„'; + this.STATION_LIST_TITLE_TAG = 'h2'; + this.STATION_LIST_TITLE_TEXT = '๐Ÿš‰ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก'; + + this.STATION_INPUT_ID = 'station-name-input'; + this.ADD_BUTTON_ID = 'station-add-button'; + + this.STATION_INPUT_PLACEHOLDER = '์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'; + this.STATION_INPUT_TYPE = 'String'; + this.MINLENGTH_ERROR_MESSAGE = '์—ญ ์ด๋ฆ„์„ ๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'; + this.OVERLAP_ERROR_MESSAGE = '์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์—ญ์ž…๋‹ˆ๋‹ค.' + + this.ADD_BUTTON_TEXT = '์—ญ ์ถ”๊ฐ€'; + this.DELETE_BUTTON_TEXT = '์‚ญ์ œ'; + + this.IS_VALID = true; + this.IS_NOT_VALID = false; + } + + initPage() { + this.setPrivateVariable(); + this._stationList = {}; + this.setConst(); + + this.createInputSection(); + this.createTableSection(); + } + + createInputSection() { + this._privateCommonUtils.insertEmptyline(this.ARTICLE_NAME); + this._privateCommonUtils.createTitle(this.STATION_INPUT_TITLE_TAG, this.STATION_INPUT_TITLE_TEXT, this.ARTICLE_NAME); + this.createStationInput(); + this._stationAddButton = this._privateDomUtils.createButton(this.ADD_BUTTON_ID, this.ADD_BUTTON_TEXT); + this._privateDomUtils.appendToIdName(this.ARTICLE_NAME, this._stationAddButton); + this.addEventToButton(this.ADD_TYPE, this.MENU_TYPE); + } + + createTableSection() { + this._privateCommonUtils.createTitle(this.STATION_LIST_TITLE_TAG, this.STATION_LIST_TITLE_TEXT, this.ARTICLE_NAME); + this._privateTableUtils.initTable(this.ARTICLE_NAME); + } + + createStationInput() { + const inputObject = this.stationInputObject(); + + this._stationInput = this._privateDomUtils.createInput(inputObject); + } + + stationInputObject() { + const inputObject = { + 'attribute': 'id', + 'toIdName': this.ARTICLE_NAME, + 'idName': this.STATION_INPUT_ID, + 'placeholder': this.STATION_INPUT_PLACEHOLDER, + 'type': this.STATION_INPUT_TYPE, + } + + return inputObject; + } + + addEventToButton(buttonType, menuType) { + this[`_station${buttonType}Button`].addEventListener('click', () => { + this.addStation(); + }) + this[`_${menuType}Input`].addEventListener('keypress', e => { + if (e.keyCode === 13) { + this.addStation(); + } + }) + } + + addStation() { + this._inputValue = this._privateStringUtils.removeSpace(this._stationInput.value); + console.log(this._inputValue); + + if (this.checkStationValidity() === this.IS_VALID) { + const rowArray = [this._inputValue, this.DELETE_BUTTON_TEXT]; + + this.addToStationList(this._inputValue); + this._privateCommonUtils.saveToLocalStorage('stationList', this._stationList); + this._privateTableUtils.addRow(rowArray, this.ARTICLE_NAME); + this._stationInput.value = ''; + } + } + + checkStationValidity() { + if (this.minLength() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(this.MINLENGTH_ERROR_MESSAGE); + + return this.IS_NOT_VALID; + } + + if (this.overlap() === this.IS_NOT_VALID) { + this._privateCommonUtils.alertError(`"${this._inputValue}"์€/๋Š” ` + this.OVERLAP_ERROR_MESSAGE) + + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + minLength() { + if (this._inputValue.length <= 1) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + overlap() { + const stationList = this._privateCommonUtils.getLocalStorageStation(); + + if (this._inputValue in stationList) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + addToStationList(stationName) { + this._stationList = this._privateCommonUtils.getLocalStorageStation(); + + if (!this._stationList) { + this._stationList = {}; + } + + this._stationList[stationName] = []; + } +} \ No newline at end of file diff --git a/src/menu.js b/src/menu.js new file mode 100644 index 000000000..f3cf8366e --- /dev/null +++ b/src/menu.js @@ -0,0 +1,182 @@ +import DomUtils from './dom_utils.js'; +import StringUtils from './string_utils.js'; +import TableUtils from './table_utils.js'; +import CommonUtils from './common_utils.js'; +import ManageLine from './manage_line.js'; +import SelectUtils from './select_utils.js'; +import ManageMapPrint from './manage_map_print.js'; +import ManageSection from './manage_section.js'; + +export default class Menu { + setPrivateVariables() { + this._privateDomUtils = new DomUtils(); + this._privateStringUtils = new StringUtils(); + this._privateTableUtils = new TableUtils(); + this._privateCommonUtils = new CommonUtils(); + this._privateSelectUtils = new SelectUtils(); + } + + setIdName() { + this.APP = 'app'; + this.ARTICLE_AREA = 'articleArea'; + this.DO_NOT_APPEND = false; + + this.STATION_ARTICLE = 'stationArticle'; + this.LINE_ARTICLE = 'lineArticle'; + this.SECTION_ARTICLE = 'sectionArticle'; + this.MAP_PRINT_ARTICLE = 'mapArticle'; + + this.LINE_BUTTON_CLASS = 'line-button' + } + + managerButton() { + this._managerButton = { + 'station-manager-button': '1. ์—ญ ๊ด€๋ฆฌ', + 'line-manager-button': '2. ๋…ธ์„  ๊ด€๋ฆฌ', + 'section-manager-button': '3. ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ', + 'map-print-manager-button': '4. ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ', + } + } + + createMenu() { + this.setIdName(); + this.managerButton(); + this.setPrivateVariables(); + + this.createArticleArea(); + for (const idName in this._managerButton) { + const varName = this.createMenuButton(idName); + const articleName = this.createMenuArticle(idName); + this.addEventToButton(varName, articleName); + } + } + + createArticleArea() { + this._articleArea = this._privateDomUtils.createArticle(this.APP, this.ARTICLE_AREA); + } + + createMenuButton(idName) { + const varName = this._privateStringUtils.getVarName(idName); + + this[`_${varName}`] = this._privateDomUtils.createButton(idName, this._managerButton[idName]); + this._privateDomUtils.appendBefore(this.APP, this[`_${varName}`], this._articleArea); + + return varName; + } + + createMenuArticle(idName) { + const articleName = this._privateStringUtils.getArticleName(idName); + + this[`_${articleName}`] = this._privateDomUtils.createArticle(this.ARTICLE_AREA, articleName); + this._privateDomUtils.displayNone(this[`_${articleName}`]); + + return articleName; + } + + addEventToButton(varName, articleName) { + this[`_${varName}`].addEventListener('click', () => { + this.showArticle(articleName); + this.refreshArticle(articleName); + }); + } + + showArticle(articleName) { + this.hideAllArticle(); + this.showCorrespondingArticle(articleName); + } + + hideAllArticle() { + for (let i = 0; i < 4; i++) { + this._articleArea.children[i].style.display = 'none' + } + } + + showCorrespondingArticle(articleName) { + this[`_${articleName}`].style.display = 'block'; + } + + refreshArticle(articleName) { + if (articleName === this.STATION_ARTICLE) { + this.refreshStationArticle(articleName); + } + else if (articleName === this.LINE_ARTICLE) { + this.refreshLineArticle(articleName); + } + else if (articleName === this.SECTION_ARTICLE) { + this.refreshSectionArticle(); + } + else if (articleName === this.MAP_PRINT_ARTICLE) { + this.refreshMapPrint(articleName); + } + } + + refreshStationArticle(articleName) { + this.findInputAndEmpty('station-name-input'); + this._privateTableUtils.emptyTableData(articleName); + this._privateTableUtils.initStationTableData(articleName); + } + + refreshLineArticle(articleName) { + this.findInputAndEmpty('line-name-input') + this.refreshLineSelect(); + this._privateTableUtils.refreshTableData(articleName); + } + + refreshLineSelect() { + const startSelect = document.getElementById('line-start-station-selector'); + const endSelect = document.getElementById('line-end-station-selector'); + + startSelect.innerHTML = ''; + endSelect.innerHTML = ''; + + this._privateSelectUtils.addStationsToSelect(startSelect, this._privateCommonUtils, this._privateDomUtils); + this._privateSelectUtils.addStationsToSelect(endSelect, this._privateCommonUtils, this._privateDomUtils); + } + + refreshSectionArticle() { + this.findInputAndEmpty('section-order-input'); + this.refreshSectionLineButtons(); + this.refreshStationsSelector(); + } + + findInputAndEmpty(idName) { + const input = document.getElementById(idName) + this._privateCommonUtils.emptyInput(input); + } + + refreshSectionLineButtons() { + this.removeButtons(); + + const manageSection = new ManageSection(); + + manageSection.createLineButtons(); + manageSection.hideManageLineSection(); + } + + refreshStationsSelector() { + const select = document.getElementById('section-station-selector'); + + select.innerHTML = ''; + + this._privateSelectUtils.addStationsToSelect(select, this._privateCommonUtils, this._privateDomUtils); + } + + removeButtons() { + const buttonArray = document.querySelectorAll(`.${this.LINE_BUTTON_CLASS}`); + const len = buttonArray.length + + for (let i = 0; i < len; i++) { + document.querySelector(`.${this.LINE_BUTTON_CLASS}`).remove(); + } + } + + refreshMapPrint(articleName) { + const manageMapPrint = new ManageMapPrint(); + + manageMapPrint.emptyArticle(articleName); + manageMapPrint.displayMapPrint(articleName, this._privateCommonUtils); + } + + + +} \ No newline at end of file diff --git a/src/select_utils.js b/src/select_utils.js new file mode 100644 index 000000000..7b5b0c89a --- /dev/null +++ b/src/select_utils.js @@ -0,0 +1,65 @@ +import CommonUtils from './common_utils.js'; +import DomUtils from './dom_utils.js'; + +export default class SelectUtils { + setPrivateVariables() { + this._privateCommonUtils = new CommonUtils(); + this._privateDomUtils = new DomUtils(); + } + + initLists() { + this._lineList = this._privateCommonUtils.getLocalStorageLine(); + this._stationList = this._privateCommonUtils.getLocalStorageStation(); + } + + setConst() { + this.LINE_START_SELECT_ID = 'line-start-station-selector'; + this.LINE_END_SELECT_ID = 'line-end-station-selector'; + this.LINE_START_SELECT_TEXT = '์ƒํ–‰ ์ข…์  '; + this.LINE_END_SELECT_TEXT = 'ํ•˜ํ–‰ ์ข…์  ' + } + + createSelectSection(articleName) { + this.setPrivateVariables(); + this.setConst(); + + this._privateCommonUtils.insertEmptyline(articleName); + this.createSelectStation('start', articleName); + this._privateCommonUtils.insertEmptyline(articleName); + this.createSelectStation('end', articleName); + this._privateCommonUtils.insertEmptyline(articleName); + } + + createSelectStation(position, articleName) { + const positionUpper = position.toUpperCase(); + + this._privateCommonUtils.createTitle('span', this[`LINE_${positionUpper}_SELECT_TEXT`], articleName); + this[`_${position}Select`] = this.createSelect(articleName, this[`LINE_${positionUpper}_SELECT_ID`], this._privateCommonUtils, this._privateDomUtils); + } + + createSelect(toIdName, idName, commonUtils, domUtils) { + const select = document.createElement('SELECT'); + + domUtils.setAttribute('id', select, idName); + domUtils.appendToIdName(toIdName, select); + this.addStationsToSelect(select, commonUtils, domUtils); + + return select; + } + + addStationsToSelect(select, commonUtils, domUtils) { + const stationList = commonUtils.getLocalStorageStation(); + + for (const station in stationList) { + this.createSelectOption(select, station, domUtils); + } + } + + createSelectOption(select, station, domUtils) { + const option = document.createElement('option'); + + domUtils.addDataAttribute(option, station) + option.innerHTML = station; + select.add(option); + } +} \ No newline at end of file diff --git a/src/string_utils.js b/src/string_utils.js new file mode 100644 index 000000000..b1365ec67 --- /dev/null +++ b/src/string_utils.js @@ -0,0 +1,40 @@ +export default class StringUtils { + removeSpace(inputValue) { + return inputValue.split(' ').join(''); + } + + getVarName(tagName) { + let tagParts = this.splitTagName(tagName); + let varNameParts = this.intoCamelCase(tagParts); + + return varNameParts.join(''); + } + + splitTagName(tagName) { + return tagName.split('-'); + } + + intoCamelCase(tagParts) { + let varNameParts = []; + + tagParts.forEach((part) => { + varNameParts.push(this.capitalizeFirstChar(part, tagParts)); + }) + + return varNameParts; + } + + capitalizeFirstChar(string, tagParts) { + if (tagParts.indexOf(string) >= 1) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + + return string + } + + getArticleName(tagName) { + const tagParts = this.splitTagName(tagName); + + return `${tagParts[0]}Article`; + } +} \ No newline at end of file diff --git a/src/table_utils.js b/src/table_utils.js new file mode 100644 index 000000000..4d082da69 --- /dev/null +++ b/src/table_utils.js @@ -0,0 +1,397 @@ +import DomUtils from './dom_utils.js'; +import CommonUtils from './common_utils.js'; +import ManageSection from './manage_section.js'; + +export default class TableUtils { + constructor() { + this.setPrivateVariable(); + this.setTableType(); + this.setConst(); + } + + setPrivateVariable() { + this._privateDomUtils = new DomUtils(); + this._privateCommonUtils = new CommonUtils(); + } + + setTableType() { + this._tableType = { + stationArticle: ['์—ญ ์ด๋ฆ„', '์„ค์ •'], + lineArticle: ['๋…ธ์„  ์ด๋ฆ„', '์ƒํ–‰ ์ข…์ ์—ญ', 'ํ•˜ํ–‰ ์ข…์ ์—ญ', '์„ค์ •'], + sectionManageArea: ['์ˆœ์„œ', '์ด๋ฆ„', '์„ค์ •'], + } + } + + setConst() { + this.STATION_DELETE_BUTTON_TEXT = '์‚ญ์ œ'; + this.LINE_DELETE_BUTTON_TEXT = '์‚ญ์ œ'; + this.SECTION_DELETE_BUTTON_TEXT = '๋…ธ์„ ์—์„œ ์ œ๊ฑฐ'; + + this.ID_ATTRIBUTE = 'id'; + this.IS_VALID = 1; + this.IS_NOT_VALID = 0; + + this.STATION_DELETE_ERROR_MESSAGE = '๋…ธ์„ ์— ๋“ฑ๋ก๋˜์–ด ์žˆ๋Š” ์—ญ์€ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.'; + this.SECTION_DELETE_ERROR_MESSAGE = '๋” ์ด์ƒ ์ด ๋…ธ์„ ์—์„œ ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์ด ๋‘๊ฐœ ์ดํ•˜์ผ ๋•Œ๋Š” ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.' + + this.STATION_TABLE_NAME = 'stationArticleTable'; + this.LINE_TABLE_NAME = 'lineArticleTable'; + this.SECTION_TABLE_NAME = 'sectionManageAreaTable'; + } + + initTable(toIdName) { + const table = document.createElement('table'); + + this._privateDomUtils.setAttribute(this.ID_ATTRIBUTE, table, `${toIdName}Table`); + this.addTableStyle(table); + this.createTitleRow(table, toIdName); + this._privateDomUtils.appendToIdName(toIdName, table); + this.initTableData(toIdName); + } + + initTableData(toIdName) { + if (toIdName === 'stationArticle') { + this.initStationTableData(toIdName); + } + else if (toIdName === 'lineArticle') { + this.initLineTableData(toIdName); + } + } + + initStationTableData(articleName) { + const stationList = this._privateCommonUtils.getLocalStorageStation(); + + for (const station in stationList) { + const rowArray = [station, this.STATION_DELETE_BUTTON_TEXT]; + this.addRow(rowArray, articleName); + } + } + + initLineTableData(articleName) { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + + for (const line in lineList) { + const lineLen = lineList[line].length; + const rowArray = [line, lineList[line][0], lineList[line][lineLen - 1], this.LINE_DELETE_BUTTON_TEXT]; + this.addRow(rowArray, articleName); + } + } + + refreshTableData(toIdName, line) { + this.emptyTableData(toIdName); + if (toIdName === 'lineArticle') { + this.initLineTableData(toIdName); + } + else if (toIdName === 'sectionManageArea') { + this.initSectionTable(toIdName, line); + } + } + + emptyTableData(toIdName) { + const tbody = document.querySelector(`#${toIdName}Table tbody`); + const rowCount = tbody.childElementCount; + + if (rowCount > 1) { + this.deleteRows(tbody.parentNode, rowCount); + } + } + + deleteRows(table, rowCount) { + for (let i = rowCount - 1; i > 0; i--) { + table.deleteRow(i); + } + } + + initSectionTable(toIdName, line) { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + const stationList = this._privateCommonUtils.getLocalStorageStation(); + + for (const index in lineList[line]) { + const rowArray = [index, lineList[line][index], this.SECTION_DELETE_BUTTON_TEXT, line]; + this.addRow(rowArray, toIdName); + } + } + + addTableStyle(table) { + table.style.border = '1px solid black'; + } + + createTitleRow(table, tableType) { + const titleRow = table.insertRow(0); + + this._tableType[tableType].forEach((text, i) => { + const cell = this.addCell(titleRow, i); + this.addTitleCellStyle(cell, text); + }) + } + + addCell(titleRow, i) { + return titleRow.insertCell(i); + } + + addTitleCellStyle(cell, text) { + cell.innerHTML = text; + cell.style.border = '1px solid black'; + cell.style.fontWeight = 'bold'; + cell.style.textAlign = 'center'; + } + + addRow(rowArray, tableType) { + const table = document.getElementById(`${tableType}Table`); + const row = table.insertRow(); + + this._privateDomUtils.addDataAttribute(row, rowArray); + this.addCellsAndButton(tableType, row, rowArray); + } + + addRowAtIndex(rowArray, line, tableType) { + const table = document.getElementById('sectionManageAreaTable'); + const index = rowArray[0]; + const row = table.insertRow(index); + + this._privateDomUtils.addDataAttribute(row, rowArray); + this.addCellsAndButton(tableType, row, rowArray); + } + + addCellText(cell, text) { + cell.innerHTML = text; + } + + addCellBorder(cell) { + cell.style.border = '1px solid black'; + } + + addCellsAndButton(tableType, row, rowArray) { + this._tableType[tableType].forEach((v, i) => { + const typeUpper = this.getType(tableType).toUpperCase(); + + if (i !== 3 || rowArray[i] === this.LINE_DELETE_BUTTON_TEXT) { + const cell = row.insertCell(i); + + this.addCellBorder(cell); + this.checkButtonOrText(rowArray, i, typeUpper, cell); + } + }) + } + + checkButtonOrText(rowArray, i, typeUpper, cell) { + if (rowArray[i] === this[`${typeUpper}_DELETE_BUTTON_TEXT`]) { + this.addDeleteButton(cell, rowArray, typeUpper); + } + else { + this.addCellText(cell, rowArray[i]); + } + } + + addDeleteButton(cell, rowArray, typeUpper) { + const deleteButton = document.createElement('button'); + const type = typeUpper.toLowerCase(); + + this._privateDomUtils.addDataAttribute(deleteButton, rowArray); + this._privateDomUtils.setAttribute('class', deleteButton, `${type}-delete-button`) + this._privateDomUtils.setInnerHtml(deleteButton, this[`${typeUpper}_DELETE_BUTTON_TEXT`]); + this._privateDomUtils.appendToVarName(cell, deleteButton); + this.addEventToDeleteButton(deleteButton, type); + } + + getType(tableType) { + let type = ''; + + for (let i = 0; i < tableType.length; i++) { + if (tableType[i] >= 'A' && tableType[i] <= 'Z') { + return type + } + type += tableType[i]; + } + + return type; + } + + addEventToDeleteButton(deleteButton, type) { + if (type === 'station') { + this.addEventToStationDeleteButton(deleteButton); + } + else if (type === 'line') { + this.addEventToLineDeleteButton(deleteButton); + } + else if (type === 'section') { + this.addEventToSectionDeleteButton(deleteButton); + } + } + + addEventToStationDeleteButton(button) { + button.addEventListener('click', () => { + if (this.ifOkay() === this.IS_VALID) { + this.checkStationDeleteValidity(button); + } + }); + } + + addEventToLineDeleteButton(button) { + button.addEventListener('click', () => { + if (this.ifOkay() === this.IS_VALID) { + this.deleteRowAndData(button); + } + }) + } + + addEventToSectionDeleteButton(button) { + button.addEventListener('click', () => { + if (this.ifOkay() === this.IS_VALID) { + this.checkSectionDeleteValidity(button); + } + }) + } + + ifOkay() { + if (confirm('์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) { + return this.IS_VALID; + } + else { + return this.IS_NOT_VALID; + } + } + + checkStationDeleteValidity(button) { + if (this.checkIfRegisteredToLine(button) === this.IS_VALID) { + this.deleteRowAndData(button); + } + else { + this._privateCommonUtils.alertError(this.STATION_DELETE_ERROR_MESSAGE); + } + } + + checkSectionDeleteValidity(button) { + if (this.checkIfContainsOverTwoStations(button) === this.IS_VALID) { + this.deleteRowAndData(button); + this.refreshSectionTable(button); + } + else { + this._privateCommonUtils.alertError(this.SECTION_DELETE_ERROR_MESSAGE); + } + } + + checkIfRegisteredToLine(button) { + const stationList = this._privateCommonUtils.getLocalStorageStation(); + const dataset = this.getDataAttribute(button); + const station = dataset.split(',')[0]; + + if (stationList[station][0]) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + checkIfContainsOverTwoStations(button) { + const lineList = this._privateCommonUtils.getLocalStorageLine(); + const dataset = this.getDataAttribute(button); + const line = dataset.split(',')[3]; + + if (lineList[line].length <= 2) { + return this.IS_NOT_VALID; + } + + return this.IS_VALID; + } + + deleteRowAndData(button) { + const dataset = this.getDataAttribute(button); + const datasetArray = this.getDataSetArray(button); + const row = document.querySelector(`[data-tracking="${dataset}"]`); + + this.updateDeleteToLocalStorage(button, datasetArray); + this.deleteTableRow(row); + } + + getDataSetArray(button) { + const dataset = this.getDataAttribute(button); + const datasetArray = dataset.split(','); + + return datasetArray; + } + + getDataAttribute(button) { + return button.dataset.tracking; + } + + refreshSectionTable(button) { + const datasetArray = this.getDataSetArray(button); + const line = datasetArray[3]; + + this.refreshTableData('sectionManageArea', line); + } + + updateDeleteToLocalStorage(button, datasetArray) { + const stationList = this._privateCommonUtils.getLocalStorageStation(); + const lineList = this._privateCommonUtils.getLocalStorageLine(); + + if (this.checkTableId(button) === this.STATION_TABLE_NAME) { + this.updateStationDelete(stationList, datasetArray); + } + else if (this.checkTableId(button) === this.LINE_TABLE_NAME) { + this.updateLineDelete(stationList, lineList, datasetArray); + } + else if (this.checkTableId(button) === this.SECTION_TABLE_NAME) { + this.updateSectionDelete(stationList, lineList, datasetArray); + } + } + + updateStationDelete(stationList, datasetArray) { + const station = datasetArray[0]; + + this.removeFromObject(stationList, station); + this._privateCommonUtils.saveToLocalStorage('stationList', stationList); + } + + updateLineDelete(stationList, lineList, datasetArray) { + const line = datasetArray[0]; + + this.removeStationFromLine(line, lineList, stationList); + this.removeFromObject(lineList, line); + this._privateCommonUtils.saveToLocalStorage('stationList', stationList); + this._privateCommonUtils.saveToLocalStorage('lineList', lineList); + } + + updateSectionDelete(stationList, lineList, datasetArray) { + const index = datasetArray[0]; + const line = datasetArray[3]; + const station = lineList[line][index]; + const lineIndex = stationList[station].indexOf(line); + const stationIndex = lineList[line].indexOf(station); + + stationList[station].splice(lineIndex, 1); + lineList[line].splice(stationIndex, 1); + + this._privateCommonUtils.saveToLocalStorage('lineList', lineList); + this._privateCommonUtils.saveToLocalStorage('stationList', stationList); + } + + checkTableId(button) { + return button.parentNode.parentNode.parentNode.parentNode.id; + } + + removeStationFromLine(line, lineList, stationList) { + for (const station of lineList[line]) { + this.removeFromArray(stationList[station], line); + } + } + + removeFromObject(object, name) { + delete object[name]; + + return object; + } + + removeFromArray(array, name) { + const index = array.indexOf(name); + + array.splice(index, 1); + + return array; + } + + deleteTableRow(row) { + row.remove(); + } +} \ No newline at end of file