Integrasi FullCalendar di NuxtJS dan Laravel API (Part 2)
Setelah pada tutorial pertama kita sudah buat rest API untuk fullcalendar, sekarang kita akan menginstall nuxt dan mencoba untuk integrasi dengan fullcalendar.
sebelumnya pastikan anda sudah mempunyai project nuxt, atau jika belum ada anda bisa menginstall nuxt dengan perintah berikut:
Install NuxtJS
npm init nuxt-app <project-name>
Instal Dependencies
setelah anda berhasil menginstall nuxt, langkah selanjutnya adalah menginstall dependensi untuk fullcalendar, tambahkan baris berikut pada file package.json pada sub dependencies.
"jquery": "3.4.1",
"@fullcalendar/core": "^5.9.0",
"@fullcalendar/daygrid": "^5.9.0",
"@fullcalendar/interaction": "^5.9.0",
"@fullcalendar/timegrid": "^5.9.0",
"@fullcalendar/vue": "^5.9.0",
"@nuxtjs/moment": "^1.6.1"
jalankan perintah berikut untuk mendownload dependenciesnya.
npm install
Plugins
langkah selanjutnya adalah membuat plugins, buat folder baru pada root project kita dengan nama plugins
Jquery.js
kita buat file baru dengan nama jquery.js pada folder plugins yang telah kita buat tadi, kemudian tambahkan baris berikut.
import jquery from 'jquery'
import 'jquery-ui-bundle'
window.$ = window.jQuery = jquery
vue-fullcalendar.js
selanjutnya kita juga buat sebuah file baru dengan nama vue-fullcalendar.js pada folder plugins, kemudian tambahkan baris berikut.
import '@fullcalendar/core/vdom'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default {
components: {
FullCalendar
},
data() {
return {
calendarOptions: {
plugins: [ dayGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth'
}
}
}
}
Menambahkan plugin ke file nuxt.config.js
pada root folder nuxtjs kita, terdapat file dengan nama nuxt.config.js, buka file tersebut kemudian tambahkan baris kode berikut pada sub plugins.
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: '~/plugins/vue-fullcalendar', ssr: false },
{ src: '~/plugins/jquery', ssr: false },
],
Menampilkan Data Event
buka file index.php pada folder pages, kemudian edit menjadi seperti berikut.
<template>
<div>
<div class="container">
<FullCalendar :options="calendarOptions" ref="calendar" @rerender-events="generateEvent" @event-selected="eventSelected"/>
</div>
</div>
</template>
<script>
import '@fullcalendar/core/vdom'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import timeGridPlugin from '@fullcalendar/timegrid'
import moment from 'moment'
export default {
components: {
FullCalendar,
},
data(){
return {
api_url:'http://127.0.0.1:8000',
calendarOptions: {
plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin ],
initialView: 'timeGridWeek',
validRange: {
start: new Date()
},
slotLabelFormat: [
{
hour: '2-digit',
minute: '2-digit',
hour12:false
}
],
locale: 'en',
dateClick: this.dayClick,
selectable:true,
eventClick: this.eventSelected,
events: [],
},
events:[]
}
},
filters: {
moment: function (date) {
return moment(date).format('YYYY-MM-DD');
}
},
mounted(){
this.getData()
},
methods:{
generateEvent(){
},
eventSelected(e){
}
}
}
</script>
jalankan project nuxt dengan perintah berikut.
npm run dev
kemudian buka browser, jika sesuai maka akan muncul tampilan seperti berikut.
langkah selanjutkan kita akan mencoba mengambil data dari API yang telah kita buat pada tutorial sebelumnya dan menampilkannya pada list calendar. tambahkan fungsi berikut.
generateEvent(){
this.calendarOptions.events = []
this.$axios.get(this.api_url+'/api/event')
.then(resp => {
for(var a=0; a<resp.data.length; a++)
{
this.calendarOptions.events.push({
id: resp.data[a].id,
title: resp.data[a].title,
start: resp.data[a].start_date+'T'+resp.data[a].start_time.replace(/\s+/g, ' ').trim(),
end: resp.data[a].end_date+'T'+resp.data[a].end_time.replace(/\s+/g, ' ').trim(),
allDay:false,
})
}
})
},
kita akan menjalankan method diatas, saat aplikasi kita dibuka, maka tambahkan baris berikut.
mounted(){
this.generateEvent()
},
jika berhasil maka akan muncul hasil seperti berikut.
Menambah Data Event
sekarang kita akan menambahkan event baru, yang kemudian akan menyimpan data nya ke api.
kita tambahkan button add untuk menampilkan form input data event, buka file index.vue kemudian tambahkan baris berikut.
<template>
<div>
<div class="container">
<a href="#" class="btn btn-primary" @click.prevent="tampilFormEvent">
Buat Event Baru
</a>
<hr>
<b-modal id="bv-modal-event" hide-footer>
<template #modal-title>
{{title}}
</template>
<form @submit.prevent="simpanEvent">
<div class="form-group">
<label for="" class="control-label">Title</label>
<input type="text" v-model="form.title" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">Start Date</label>
<input type="date" v-model="form.start_date" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">End Date</label>
<input type="date" v-model="form.date_date" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">Start Time</label>
<input type="time" v-model="form.start_time" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">End Time</label>
<input type="time" v-model="form.date_time" class="form-control">
</div>
<div class="form-group">
<button class="btn btn-primary btn btn-block" type="submit">Simpan</button>
</div>
</form>
</b-modal>
<FullCalendar :options="calendarOptions" ref="calendar" @rerender-events="generateEvent" @event-selected="eventSelected"/>
</div>
</div>
</template>
<script>
import '@fullcalendar/core/vdom'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import timeGridPlugin from '@fullcalendar/timegrid'
import moment from 'moment'
export default {
components: {
FullCalendar,
},
data(){
return {
api_url:'http://127.0.0.1:8000',
calendarOptions: {
plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin ],
initialView: 'timeGridWeek',
validRange: {
start: new Date()
},
slotLabelFormat: [
{
hour: '2-digit',
minute: '2-digit',
hour12:false
}
],
locale: 'en',
dateClick: this.dayClick,
selectable:true,
eventClick: this.eventSelected,
events: [],
},
title:'',
form:{
type:'add',
id:'',
title:'',
start_date:'',
end_date:'',
start_time:'',
end_time:''
}
}
},
filters: {
moment: function (date) {
return moment(date).format('YYYY-MM-DD');
}
},
mounted(){
this.generateEvent()
},
methods:{
generateEvent(){
this.calendarOptions.events = []
this.$axios.get(this.api_url+'/api/event')
.then(resp => {
for(var a=0; a<resp.data.length; a++)
{
this.calendarOptions.events.push({
id: resp.data[a].id,
title: resp.data[a].title,
start: resp.data[a].start_date+'T'+resp.data[a].start_time.replace(/\s+/g, ' ').trim(),
end: resp.data[a].end_date+'T'+resp.data[a].end_time.replace(/\s+/g, ' ').trim(),
allDay:false,
})
}
})
},
tampilFormEvent(){
this.title = "Buat Event Baru"
this.form.form = {
type:'add',
id:'',
title:'',
start_date:'',
end_date:'',
start_time:'',
end_time:''
}
this.$bvModal.show('bv-modal-event')
},
simpanEvent(){
this.$axios.post(this.api_url+'/api/store-event', this.form)
.then(resp => {
this.$bvModal.hide('bv-modal-event')
this.generateEvent()
})
},
eventSelected(e){
}
}
}
</script>
Edit Data Event
langkah selanjutnya, kita akan mengedit data event yang sudah ada. buka kembali file index.vue kemudian update method eventSelected menjadi seperti berikut.
eventSelected(e){
this.title = "Edit Event"
this.form = {
id: e.event.id,
type:'edit',
title:e.event.title,
start_date:moment(e.event.start).format('YYYY-MM-DD'),
end_date:moment(e.event.end).format('YYYY-MM-DD'),
start_time:moment(e.event.start).format('hh:mm:ss'),
end_time:moment(e.event.end).format('hh:mm:ss')
}
this.$bvModal.show('bv-modal-event')
}
secara keseluruhan file index.vue akan menjadi seperti berikut.
<template>
<div>
<div class="container">
<a href="#" class="btn btn-primary" @click.prevent="tampilFormEvent">
Buat Event Baru
</a>
<hr>
<b-modal id="bv-modal-event" hide-footer>
<template #modal-title>
{{title}}
</template>
<form @submit.prevent="simpanEvent">
<div class="form-group">
<label for="" class="control-label">Title</label>
<input type="text" v-model="form.title" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">Start Date</label>
<input type="date" v-model="form.start_date" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">End Date</label>
<input type="date" v-model="form.end_date" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">Start Time</label>
<input type="time" v-model="form.start_time" class="form-control">
</div>
<div class="form-group">
<label for="" class="control-label">End Time</label>
<input type="time" v-model="form.end_time" class="form-control">
</div>
<div class="form-group">
<button class="btn btn-primary btn btn-block" type="submit">Simpan</button>
</div>
</form>
</b-modal>
<FullCalendar :options="calendarOptions" ref="calendar" @rerender-events="generateEvent" @event-selected="eventSelected"/>
</div>
</div>
</template>
<script>
import '@fullcalendar/core/vdom'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import timeGridPlugin from '@fullcalendar/timegrid'
import moment from 'moment'
export default {
components: {
FullCalendar,
},
data(){
return {
api_url:'http://127.0.0.1:8000',
calendarOptions: {
plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin ],
initialView: 'timeGridWeek',
validRange: {
start: new Date()
},
slotLabelFormat: [
{
hour: '2-digit',
minute: '2-digit',
hour12:false
}
],
locale: 'en',
dateClick: this.dayClick,
selectable:true,
eventClick: this.eventSelected,
events: [],
},
title:'',
form:{
type:'add',
id:'',
title:'',
start_date:'',
end_date:'',
start_time:'',
end_time:''
}
}
},
filters: {
moment: function (date) {
return moment(date).format('YYYY-MM-DD');
}
},
mounted(){
this.generateEvent()
},
methods:{
generateEvent(){
this.calendarOptions.events = []
this.$axios.get(this.api_url+'/api/event')
.then(resp => {
for(var a=0; a<resp.data.length; a++)
{
this.calendarOptions.events.push({
id: resp.data[a].id,
title: resp.data[a].title,
start: resp.data[a].start_date+'T'+resp.data[a].start_time.replace(/\s+/g, ' ').trim(),
end: resp.data[a].end_date+'T'+resp.data[a].end_time.replace(/\s+/g, ' ').trim(),
allDay:false,
})
}
})
},
tampilFormEvent(){
this.title = "Buat Event Baru"
this.form.form = {
type:'add',
id:'',
title:'',
start_date:'',
end_date:'',
start_time:'',
end_time:''
}
this.$bvModal.show('bv-modal-event')
},
simpanEvent(){
this.$axios.post(this.api_url+'/api/store-event', this.form)
.then(resp => {
this.$bvModal.hide('bv-modal-event')
this.generateEvent()
})
},
eventSelected(e){
this.title = "Edit Event"
this.form = {
id: e.event.id,
type:'edit',
title:e.event.title,
start_date:moment(e.event.start).format('YYYY-MM-DD'),
end_date:moment(e.event.end).format('YYYY-MM-DD'),
start_time:moment(e.event.start).format('hh:mm:ss'),
end_time:moment(e.event.end).format('hh:mm:ss')
}
this.$bvModal.show('bv-modal-event')
}
}
}
</script>
untuk full source code anda bisa download pada link dibawah.