-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[holee] javascript-subway-map-precourse #1
Changes from all commits
47099c5
31bcdf8
830106e
79f2f58
5e55efe
42ba961
7d45183
7ac3e6d
9cd8222
044d5ad
8980a62
79904a5
6eb9db6
5a307a8
0393c38
efc602e
5cd878c
ce33ab5
b9650dc
4b91ba1
82beaea
a2f75b3
82bf2c3
8ae7e2f
1a86244
f64f518
3f8abab
dd4bc39
8cca7da
446335f
b7de03c
53bce3f
fac8afb
9c1754b
4eeab69
98752f6
92e2160
cfd3faf
4efa6fb
672d5b6
0a5b254
b470d57
a1d346b
cc14079
27ea9ec
f5b5188
e5d6b93
98cea3f
60644a6
7a3c1c8
8df6da6
f126979
3473cba
b8a0831
8b050f2
54eaf93
74a7658
34c5afe
6e534e2
ee8a457
21d4a28
6af1d3a
4f42e2f
1405112
5c52d77
c4829f2
be6b826
bd5454e
b65ff02
c1949de
44836c2
91870f7
d4b27a7
2cd1360
7425e93
3573332
b52fb8a
94e13e6
404cfb5
901c82f
580f08a
2ceffe4
da35e6e
90d76c2
40e00aa
a19da2d
5440c25
692243d
8839288
a07e6af
2c13a56
cfece75
797ee2d
ec6e3da
62f0f0a
3961555
2158321
a54fe7d
d0d9fec
328c8a4
095dc4b
62fe2c6
1a447b3
41c0f1a
c4fe9e5
275a728
503ca20
84e4029
f8247d4
6d88798
114e705
3937cc0
f7d30e1
d1f782a
2ce680c
ccf281a
c8e2682
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.eslintrc.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module.exports = { | ||
env: { | ||
browser: true, | ||
es2021: true, | ||
}, | ||
extends: ['airbnb-base', 'plugin:prettier/recommended'], | ||
parserOptions: { | ||
ecmaVersion: 12, | ||
sourceType: 'module', | ||
}, | ||
rules: { | ||
'no-new': 'off', | ||
'no-console': 'off', | ||
'no-alert': 'off', | ||
'no-plusplus': 'error', | ||
'no-param-reassign': 'error', | ||
'no-underscore-dangle': 'off', | ||
'no-return-assign': 'error', | ||
'max-depth': ['error', 2], | ||
'max-lines-per-function': ['error', 15], | ||
'import/extensions': ['off'], | ||
'import/prefer-default-export': 'off', | ||
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"] | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
node_modules/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
## 📝 구현할 기능 목록 | ||
|
||
### 🗂 공통 메뉴 | ||
|
||
- [x] 역 관리 button 태그는 `#station-manager-button` id값을 가진다. | ||
- [x] 노선 관리 button 태그는 `#line-manager-button` id값을 가진다. | ||
- [x] 구간 관리 button 태그는 `#section-manager-button` id값을 가진다. | ||
- [x] 지하철 노선도 출력 관리 button 태그는 `#map-print-manager-button` id값을 가진다. | ||
|
||
### 🚋 지하철 역 관리 | ||
|
||
- [x] 지하철 역을 입력하는 input 태그는 `#station-name-input` id값을 가진다. | ||
- [x] 지하철 역을 추가하는 button 태그는 `#station-add-button` id값을 가진다. | ||
- [x] 지하철 역을 삭제하는 button 태그는 `.station-delete-button` class값을 가진다. | ||
|
||
- [x] 지하철 역을 등록하고 삭제할 수 있다. (단, 노선에 등록된 역은 삭제할 수 없다) | ||
- [x] localStorage에 등록 | ||
- [x] 중복된 지하철 역 이름이 등록될 수 없다. | ||
- [x] 지하철 역은 2글자 이상이어야 한다. | ||
- [x] 지하철 역의 목록을 조회할 수 있다. | ||
|
||
### 🛤 지하철 노선 관리 | ||
|
||
- [x] 지하철 노선의 이름을 입력하는 input 태그는 `#line-name-input` id값을 가진다. | ||
- [x] 지하철 노선의 상행 종점을 선택하는 select 태그는 `#line-start-station-selector` id값을 가진다. | ||
- [x] 지하철 노선의 하행 종점을 선택하는 select 태그는 `#line-end-station-selector` id값을 가진다. | ||
- [x] 지하철 노선을 추가하는 button 태그는 `#line-add-button` id값을 가진다. | ||
- [x] 지하철 노선을 삭제하는 button 태그는 `.line-delete-button` class값을 가진다. | ||
|
||
- [x] 지하철 노선을 등록하고 삭제할 수 있다. | ||
- [x] 중복된 지하철 노선 이름이 등록될 수 없다. | ||
- [x] 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다. | ||
- [x] 지하철 노선의 목록을 조회할 수 있다. | ||
|
||
### 🚉 지하철 구간 관리 | ||
|
||
#### 삭제 | ||
|
||
- [x] 지하철 노선에 구간을 추가하는 기능은 노선에 역을 추가하는 기능이라고도 할 수 있다. | ||
- [x] 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다. | ||
- [x] 하나의 역은 여러개의 노선에 추가될 수 있다. | ||
- [x] 역과 역 사이에 새로운 역이 추가 될 수 있다. | ||
- [x] 노선에서 갈래길은 생길 수 없다. | ||
|
||
#### 추가 | ||
|
||
- [x] 지하철 노선을 선택하는 button 태그는 `.section-line-menu-button` class값을 가진다. | ||
- [x] 지하철 구간을 설정할 역 select 태그는 `#section-station-selector` id값을 가진다. | ||
- [x] 지하철 구간의 순서를 입력하는 input 태그는 `#section-order-input` id값을 가진다. | ||
- [x] 지하철 구간을 등록하는 button 태그는 `#section-add-button` id값을 가진다. | ||
- [x] 지하철 구간을 제거하는 button 태그는 `.section-delete-button` class값을 가진다. | ||
|
||
- [x] 노선에 등록된 역을 제거할 수 있다. | ||
- [x] 노선에 역을 중복해서 추가할 수 없다. | ||
- [x] 종점을 제거할 경우 다음 역이 종점이 된다. | ||
- [x] 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다. | ||
|
||
|
||
### 🗺 지하철 노선도 출력 | ||
|
||
- [x] 지하철 노선도 출력 버튼을 누르면 `<div class="map"></div>` 태그를 만들고 해당 태그 내부에 노선도를 출력한다. | ||
|
||
- [x] 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회할 수 있다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "javascript-subway-map-precourse", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"repository": "https://github.com/transcendence42/javascript-subway-map-precourse.git", | ||
"author": "hochan Lee <hochan049@gmail.com>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"eslint": "^7.27.0", | ||
"eslint-config-airbnb-base": "^14.2.1", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-import": "^2.23.3", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"prettier": "^2.3.0" | ||
}, | ||
"scripts": { | ||
"lint": "eslint ." | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export const errorMessage = { | ||
stationDuplicate: '❗역이 중복되었습니다. ❗', | ||
stationLength: '❗두글자 미만으로는 설정 할 수 없습니다.❗', | ||
lineDuplicate: '❗중복된 노선입니다. ❗', | ||
lineStationForbidden: '❗노선에 등록된 역은 삭제할 수 없습니다.❗', | ||
sectionInvalidRangeInput: '❗범위에 맞지 않은 입력입니다. 재입력 해주세요!❗', | ||
sectionInvalidOption: '❗노선에 이미 등록된 역입니다. 재선택 해주세요!❗', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { controlStationManagement } from './station-management/index.js'; | ||
import { controlLineManagement } from './line-management/index.js'; | ||
import { controlSectionManagement } from './section-management/index.js'; | ||
import { controlSubwayRouteMap } from './subway-route-map/index.js'; | ||
|
||
export const controller = () => { | ||
controlStationManagement(); | ||
controlLineManagement(); | ||
controlSectionManagement(); | ||
controlSubwayRouteMap(); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { rerenderSectionButtons } from '../section-management/index.js'; | ||
import { addLineLocalStorage, addLineList } from './model.js'; | ||
import { checkValidLineSelector } from './check.js'; | ||
import { deleteLine } from './delete-line.js'; | ||
import { storage } from '../../model/index.js'; | ||
import { addButtonEvent } from '../utils.js'; | ||
import { elementIds } from '../../utils.js'; | ||
import { initLineInput } from './init.js'; | ||
import { renderLine } from './view.js'; | ||
|
||
const addLineButtonEvent = (lineName) => { | ||
for (const item of document.querySelectorAll( | ||
`table[id=line-table] tbody tr td button`, | ||
)) { | ||
if (item.dataset.line === `${lineName}-button`) { | ||
addButtonEvent(item, deleteLine); | ||
} | ||
} | ||
}; | ||
|
||
export const addLine = () => { | ||
const lineName = elementIds.lineNameInput.value; | ||
const lineStartStationSelectorValue = | ||
elementIds.lineStartStationSelector.value; | ||
const lineEndStationSelectorValue = elementIds.lineEndStationSelector.value; | ||
if ( | ||
!checkValidLineSelector( | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
) | ||
) { | ||
return; | ||
} | ||
if ( | ||
!addLineLocalStorage( | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
) | ||
) { | ||
return; | ||
} | ||
renderLine({ | ||
lineName, | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
}); | ||
initLineInput(); | ||
addLineList(lineStartStationSelectorValue, lineEndStationSelectorValue); | ||
addLineButtonEvent(lineName); | ||
rerenderSectionButtons(); | ||
console.log(storage.getLocalStorageMap('subway-line')); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { errorMessage } from '../error-message.js'; | ||
|
||
export const checkValidLineSelector = ( | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
) => { | ||
if (lineStartStationSelectorValue === lineEndStationSelectorValue) { | ||
alert(errorMessage.stationDuplicate); | ||
return false; | ||
} | ||
return true; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { rerenderSectionButtons } from '../section-management/index.js'; | ||
import { storage } from '../../model/index.js'; | ||
|
||
export const deleteLine = (e) => { | ||
const dataLine = e.currentTarget.dataset.line.slice(0, -7); | ||
for (const item of document.querySelectorAll( | ||
`table[id=line-table] tbody tr`, | ||
)) { | ||
if (item.dataset.line === dataLine) { | ||
storage.removeLocalStorage('subway-line', item.dataset.line); | ||
item.remove(); | ||
} | ||
} | ||
window.removeEventListener(e.currentTarget, deleteLine); | ||
rerenderSectionButtons(); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { toggleDisplay } from './toggle-display.js'; | ||
import { deleteLine } from './delete-line.js'; | ||
import { addButtonEvent } from '../utils.js'; | ||
import { elementIds } from '../../utils.js'; | ||
import { addLine } from './add-line.js'; | ||
|
||
export const controlLineManagement = () => { | ||
addButtonEvent(elementIds.lineManagerButton, toggleDisplay); | ||
addButtonEvent(elementIds.lineAddButton, addLine); | ||
for (const item of document.querySelectorAll( | ||
`table[id=line-table] tbody tr button`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 querySelectorAll 표현도 다음에 활용해봐야겠어요 👍 |
||
)) { | ||
addButtonEvent(item, deleteLine); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { elementIds } from '../../utils.js'; | ||
|
||
export const initLineInput = () => { | ||
elementIds.lineNameInput.value = ''; | ||
elementIds.lineNameInput.focus(); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { errorMessage } from '../error-message.js'; | ||
import { storage } from '../../model/index.js'; | ||
import { elementIds } from '../../utils.js'; | ||
|
||
const addLineList = ( | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
) => { | ||
if (!storage.getLocalStorage('subway-line-list')) { | ||
storage.setLocalStorageArray('subway-line-list', []); | ||
} | ||
const lineList = storage.getLocalStorageArray('subway-line-list'); | ||
lineList.push(lineStartStationSelectorValue, lineEndStationSelectorValue); | ||
storage.setLocalStorageArray('subway-line-list', lineList); | ||
}; | ||
|
||
const addLineLocalStorage = ( | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
) => { | ||
if (!storage.getLocalStorage('subway-line')) { | ||
storage.setLocalStorageMap('subway-line', new Map()); | ||
} | ||
const subwayLine = storage.getLocalStorageMap('subway-line'); | ||
if (subwayLine.get(elementIds.lineNameInput.value)) { | ||
alert(errorMessage.lineDuplicate); | ||
return false; | ||
} | ||
subwayLine.set(elementIds.lineNameInput.value, [ | ||
lineStartStationSelectorValue, | ||
lineEndStationSelectorValue, | ||
]); | ||
storage.setLocalStorageMap('subway-line', subwayLine); | ||
return true; | ||
}; | ||
|
||
export { addLineList, addLineLocalStorage }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { initSubwayRouteMap } from '../subway-route-map/init.js'; | ||
import { elementIds } from '../../utils.js'; | ||
|
||
export const toggleDisplay = () => { | ||
elementIds.stationManagement.hidden = true; | ||
elementIds.lineManagement.hidden = !elementIds.lineManagement.hidden; | ||
elementIds.sectionManagement.hidden = true; | ||
if (elementIds.mapPrintManagement) { | ||
elementIds.mapPrintManagement.hidden = true; | ||
} | ||
initSubwayRouteMap(); | ||
}; | ||
Comment on lines
+4
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 이 코드를 참고해서 같은 구조로 구현했습니다만, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맨처음에 작성한뒤 나중에 보았을때 저는 굉장히 안좋은 패턴이라고 결론 내렸습니다. 저에게 만약에 다실 짤 기회가 주어진다면 https://github.com/transcendence42/javascript-subway-map-precourse/blob/jwon/src/view/01-station/template.js 다음과 같이 작성한 후 메뉴 버튼을 클릭할 때마다 한 페이지를 통으로 생성하고 삭제를 해주는 로직으로 다실 짤 것같습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
querySelectorAll 인자 사용 예시 배워갑니다!