I am using python with bottle framework and JavaScript, and I want to display fetched MySQL dates into FullCalender. I am successfully fetching the data from MySQL, as shown below, but the problem is when I pass the value "dates" to the "start" key, my expectation was to see all the dates in the Callendar, but instead, I am only getting the last date.
Here is my JavaScript code:
<script>
let calendarElement = document.querySelector("#calendar");
fetch('/api-fetch-booking_data')
.then(res => res.json())
.then(data => {
data.booking_dates.forEach(element => {
let dates = element.avalable_dates
console.log(dates);
let calendar = new FullCalendar.Calendar(calendarElement, {
events: [
{
start: dates,
}
]
});
calendar.render();
})
})
</script>
These are the dates fetched from MySQL:
This is the UI, as you can see I am only getting the "2022-06-30" date:
I have seen that you could do a for loop like this using flask:
but I really don't know how and even if it is bossible to do it with bottle. Hope someone will help me up with this. Thanks in advance.
If you read full documentation for bottle then you should find information how to use for
-loops in template in bottle
.
But you send data to JavaScript library FullCalendar
and you have to do all in JavaScript.
You may have to create
events: [{start: dates[0]}, {start: dates[1]}, ... ]
and this need only JavaScript code, not Python.
EDIT:
See documentation for events https://fullcalendar.io/docs/events-array
var calendar = new Calendar(calendarEl, {
events: [
{
title : 'event1',
start : '2010-01-01'
},
{
title : 'event2',
start : '2010-01-05',
end : '2010-01-07'
},
{
title : 'event3',
start : '2010-01-09T12:30:00',
allDay : false // will make the time show
}
]
});
But it seems it can get also JSON
data which you can format in Python before sending to browser. https://fullcalendar.io/docs/events-json-feed
var calendar = new Calendar(calendarEl, {
events: '/link/to/bottle/function'
});
and this function would have to return JSON with
[
{
title : 'event1',
start : '2010-01-01'
},
{
title : 'event2',
start : '2010-01-05',
end : '2010-01-07'
},
{
title : 'event3',
start : '2010-01-09T12:30:00',
allDay : false // will make the time show
}
]
It seems you already send JSON but you would have to set it as
events: dates
and in dates you would have to send data formatted as
[
{
title : 'event1',
start : '2010-01-01'
},
{
title : 'event2',
start : '2010-01-05',
end : '2010-01-07'
},
{
title : 'event3',
start : '2010-01-09T12:30:00',
allDay : false // will make the time show
}
]
EDIT:
Minimal working code.
It uses only one FullCalendar
in JavaScript
and it puts all dates from bottle in this FullCalendar
.
Your code uses forEach
so it creates many FullCalendar
- and it puts every date in separated FullCalendar
. But all FullCalendar
use the same <div id='calendar'>
so finally you see only last FullCalendar
with last date.
from bottle import route, run
@route('/')
def hello():
return '''<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<link href='https://cdn.jsdelivr.net/npm/[email protected]/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/[email protected]/main.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
let calendarElement = document.querySelector("#calendar");
fetch('/api-fetch-booking_data')
.then(res => res.json())
.then(data => {
console.log(data);
let calendar = new FullCalendar.Calendar(calendarElement, {
events: data
});
calendar.render();
});
});
</script>
</head>
<body>
<div id='calendar'></div>
</body>
</html>
'''
@route('/api-fetch-booking_data')
def data():
import json
return json.dumps([
{
"start": "2022-05-01",
"title": "Previous month"
},
{
"start": "2022-06-01",
"title": "Current month"
},
{
"start": "2022-06-20",
"title": "Today"
}
])
run(host='localhost', port=8080, debug=True)
And the same with events: url
instead of fetch()
EDIT: I added button Refetch Events
which reads new data from bottle. In bottle I use random to create random day to see difference.
When FullCalendar
fetch data from bottle then it automatically adds dates start
, end
to url /api-fetch-booking_data
so bottle
could send only events in this range. FullCalendar
automatically fetch new events when you change month.
from bottle import route, request, run
@route('/')
def hello():
return '''<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<link href='https://cdn.jsdelivr.net/npm/[email protected]/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/[email protected]/main.min.js'></script>
<script>
var calendar = "";
document.addEventListener('DOMContentLoaded', function() {
let calendarElement = document.querySelector("#calendar");
calendar = new FullCalendar.Calendar(calendarElement, {
events: '/api-fetch-booking_data'
});
calendar.render();
});
</script>
</head>
<body>
<button onclick="calendar.refetchEvents()">Refetch Events</button><br>
<div id='calendar'></div>
</body>
</html>
'''
@route('/api-fetch-booking_data')
def data():
import json
import random
print('start:', request.query.get('start'))
print('end :', request.query.get('end'))
return json.dumps([
{
"start": "2022-05-01",
"title": "Previous month"
},
{
"start": "2022-06-01",
"title": "Current month"
},
{
"start": f"2022-06-{random.randint(1,30):02}",
"title": "Random day"
},
{
"start": "2022-06-20",
"title": "Today"
}
])
run(host='localhost', port=8080, debug=True)