작성한 To Do에 더욱 상세한 설명을 추가하거나, 패턴 / 마감일등을 추가할 수 있는 기능이다.
해당 To Do 불러오기
우선 상세설정을 하기 위해서는 이전글에서 만들어둔 Detail 화면에서 상세설정이라는 버튼을 누르면 됩니다.
ToDoDetail.vue
<button type="button" class="btn btn-primary" @click="redirectToDateSet(toDo)">詳細設定</button>
위의 코드가 상세설정 부분의 코드인데, @Click 이벤트로 redirectToDataSet이라는 함수를 실행시킨다.
파라미터로 toDo 데이터를 같이 보내는 것을 확인 가능
redirectToDateSet(data) {
this.$emit('ShowSetDetail', data)
},
redirectToDataSet함수에서는 $emit을 통해서 ShowSetDetail이라는 함수이름으로 파라미터로 받아온 toDo데이터를 다시 파라미터로 부모 컴포넌트(ToDoList.vue)로 보내는 것을 확인 가능
ToDoList.vue
ShowSetDetail(data) {
this.ToDo = data;
this.showDetail = true;
}
$emit을 통해서 받아온 파라미터(toDo 데이터)를 ToDo라는 변수에 담고, showDetail이라는 변수를 true로 변경해줍니다.
showDetail함수는 SetDetail 컴포넌트를 보여주기 위해서 사용될 변수입니다.
<template v-if="ToDo === ''">
//
</template>
<template v-else-if="showDetail">
<SetDetail :to-do="ToDo" />
</template>
<!-- To Do Detail 화면 -->
<template v-else>
<ToDoDetail :to-do="ToDo" @show-set-detail="ShowSetDetail"/>
</template>
위를 보면, v-if, v-else-if, v-else를 이용해서 그때 그때 상황에 맞는 컴포넌트가 보이도록 했는데,
그중에서 v-else-if="showDetail"을 통해서 SetDetail 컴포넌트를 보여주는 것을 확인할 수 있다.
그래서 아까 위의 함수를 봤을 때, 상세설정 버튼이 클릭되면 함수가 실행되어 ShowDetail 변수를 true로 바꿔주기 때문에 해당 SetDetail 컴포넌트가 보여지게 되는 것 입니다.
그리고 파라미터로 받아온 ToDo 데이터를 SetDetail 컴포넌트에 보내주는 것을 확인 가능
SetDetail.vue
<script>
export default {
props: ['toDo'],
}
</script>
부모 컴포넌트로부터 받아온 toDo 데이터를 사용하기위해 선언을 해주고
<div class="mb-2 border border-2 border-blue-300">
<input type="text" class="w-full p-2 bg-gray-400" v-model="title">
</div>
<div class="mb-2 border border-2 border-blue-300">
<div>
<textarea rows="15" placeholder="詳しく書いてください。" v-model="description"
class="w-full bg-gray-400 p-2"></textarea>
</div>
</div>
위 코드는 title을 수정하는 부분의 text form과 상세내용을 수정할 textarea form에 대한 부분입니다.
두개 모두 v-model을 통해서 양방향 바인딩을 하고 있는 것을 볼 수 있습니다.
수정할 때에는 기존의 내용을 보여주기 위해서, 받아온 toDo 데이터를 변수에 초기화 해줄 필요가 있습니다
data() {
return {
title: this.toDo.title,
description: this.toDo.description,
deadline: this.toDo.deadline,
}
},
data부분에서 받아온 toDo 데이터로 초기화해주면 됩니다.
그러면 자동적으로 기존의 내용들이 화면에 불러와지게 되어 편하게 수정할 수 있게 됩니다.
스케줄 설정하기
스케줄 설정은 상세설정에 들어가면 Pattern으로 할지, 마감일로 할지 정할 수 있는 기능
Pattern은 매일 해야하는 To Do와 매주 해야하는 To Do로 나뉘어집니다.
마감일은 말그대로 언제까지 해야하는지 날짜를 정할 수 있습니다.
그렇기 때문에 radio 메뉴로 무엇을 선택하느냐에 따라서 다른 Form이 나오게 합니다.
<div class="grid grid-cols-2 border border-2 border-blue-300 mb-2 p-2">
<div>
<span class="mr-2">Set Schedule</span>
<span class="mr-4">
<input type="radio" name="schedule" value="pattern" v-model="schedule">
<label for="huey">Pattern</label>
</span>
<span>
<input type="radio" name="schedule" value="deadline" v-model="schedule">
<label for="huey">Deadline</label>
</span>
</div>
<div v-if="schedule === 'pattern'">
<span class="mr-2">Set Pattern</span>
<span class="mr-4">
<input type="radio" name="pattern" value="daily" v-model="pattern">
<label for="huey">毎日</label>
</span>
<span>
<input type="radio" name="pattern" value="weekly" v-model="pattern">
<label for="huey">毎週</label>
</span>
<div v-if="pattern === 'weekly'">
<span class="mr-2">Set Day</span>
<select class="bg-gray-400 text-white" v-model="day">
<template v-for="(day, i) in week" :key="i">
<option :value="day">{{ day }}</option>
</template>
</select>
</div>
</div>
<div v-if="schedule === 'deadline'">
<label for="date" class="text-sm">Set Deadline</label>
<input type="date" id="date" v-model="deadline" class="border border-1 border-dark ml-2 bg-gray-400">
</div>
</div>
그것을 코드로는 v-if문을 사용하면 쉽게 설정을 할 수 있습니다.
radio form에는 schedule 변수를 바인딩하여, 선택값에 따라서 deadline이냐 pattern이냐 바뀌도록 합니다.
그럼, 마감일을 정하는 data form은 v-if="schedule === 'deadline'"을 해주면, deadline이 선택됐을 떼 달력 data form이 나오게 됩니다.
상세설정 DB에 저장
설정이라는 버튼을 누르게되면 작성한 내용이 DB에 저장이 되게 됩니다.
<button type="button" class="btn btn-warning" @click="submit(toDo.id)">設定</button>
위의 코드가 설정버튼의 코드이고 @Click 이벤트로 submit함수를 실행시킵니다.
submit(id) {
if(this.description || this.deadline || this.pattern) {
if(this.deadline) {
const deadline = this.deadline.split('-').map(str => Number(str));
const deadlineSec = new Date(deadline[0], deadline[1], deadline[2]).getTime();
const elapsedMSec = deadlineSec - this.today;
this.elapsedDay = elapsedMSec / 1000 / 60 / 60 / 24;
if(this.elapsedDay < 0) {
this.errorMessage = "DeadLineは、過去に設定できません";
return;
}
}
if(this.pattern) {
if(this.pattern === 'weekly') {
this.setPattern = this.day;
} else {
this.setPattern = "매일";
}
}
axios.post('api/todo/updateDetail', {
description: this.description,
deadline: this.deadline,
id: id,
pattern: this.setPattern
}).then(res => {
console.log(res);
});
window.location.href = '/';
} else {
this.errorMessage = "詳細内容 or DeadLineを作成してください。"
}
},
submit함수가 긴데, 그 이유가 deadline 설정할 때 현재보다 과거를 설정할 수 없으니까 그것을 검사하는 코드가 추가되서 그렇습니다.
그것을 계산하는 방법은 이전 글에서 적은 D-Day 기능에서 썻던 원리와 같습니다.
실질적으로 DB에 저장시키는 코드는
axios.post('api/todo/updateDetail', {
title: this.title,
description: this.description,
deadline: this.deadline,
id: id,
pattern: this.setPattern
}).then(res => {
console.log(res);
});
window.location.href = '/';
값을 수정 또는 저징하기 때문에 axios.post로 api통신을 하게 됩니다.
파라미터로
제목 title
상세내용 description
마감일 deadline
id 값
패턴 정보 pattern
를 같이 보냅니다.
api.php
Route::post('/todo/updateDetail', [ToDoListController::class, 'updateDetail']);
ToDoListController.php
public function updateDetail() {
$ToDoList = ToDoList::find(request('id'));
$ToDoList->title = request('title');
$ToDoList->description = request('description');
$ToDoList->deadline = request('deadline');
$ToDoList->pattern = request('pattern');
$ToDoList->save();
$todo_detail = ToDoList::where('id', request('id'))->first();
return view('welcome');
}
파라미터로 받은 id값으로 해당 ToDo 데이터를 DB에서 가져오고
받아온 나머지 정보로 하나씩 수정하여, save합니다.
window.location.href = '/';
그리고 통신이 완료되면, 메인화면으로 redirect를 시켜줍니다.
예외처리 (에러메세지)
상황에 맞는 예외처리가 발생하면 해당 에러메세지를 화면에 보여줍니다.
submit함수에는 if문으로 예외처리를 해주었는데
if(this.description || this.deadline || this.pattern) {
if(this.deadline) {
//
if(this.elapsedDay < 0) {
this.errorMessage = "DeadLineは、過去に設定できません";
return;
}
}
//
} else {
this.errorMessage = "詳細内容 or DeadLineを作成してください。"
}
아무런 내용 변화가 없이 저장을 했을 경우에는 errorMessage에 내용을 적어달라는 메세지를 추가하고
마감일을 설정할 때, 현재 날짜보다 과거를 설정하게 되면, 과거는 설정할 수 없다고 에러메세지를 추가 하게 됩니다.
<div class="text-gray-500 font-black">
{{ errorMessage }}
</div>
data() {
return {
errorMessage: '',
}
},
에러메세지는 data부분에 ''로 초기화 상태이기 때문에, 예외가 생기기 전까지는 아무런 표시도 하지 않습니다.
'IT 공부 > Laravel' 카테고리의 다른 글
[ Laravel + Vue.js ] 나만의 To Do List 만들기 - Modal창 (0) | 2021.08.31 |
---|---|
[ Laravel + Vue.js ] 나만의 To Do List 만들기 - Navbar 구현 (0) | 2021.08.31 |
[ Laravel + Vue.js ] 나만의 To Do List 만들기 - Detail 화면 (0) | 2021.08.30 |
[ Laravel + Vue.js ] 나만의 To Do List 만들기 - D-Day계산 / 중요 관리 (0) | 2021.08.30 |
[ Laravel + Vue.js ] 나만의 To Do List 만들기 - DB에서 data 받아오기 (0) | 2021.08.29 |