Bootstrap Calendar Events Demo using Python Flask MySQL

Introduction

We will create bootstrap calendar events demo using Python Flask MySQL. We had created similar example using Codeigniter (PHP framework) and MySQL. We will use the same version of bootsrap library 2.3.2 because using bootstrap version 4.3.1 the layout becomes a little messy.

It helps users to track easily what all upcoming events are or past events were there by navigating through the calendar dates.

Bootstrap Calendar is a reusable jQuery plugin that makes it easier to create an AJAX-enabled, template-based, full-view event calendar for your web applications.

Prerequisites

Python 3.7.4, Flask 1.1.1, MySQL 8.0.17

Creating MySQL table

Create a table called event in the MySQL database using the following structure.

The following table has id, title, url, class, start_date and end_date dates.

When you store event information you must store all fields values. For end_date field you must have non-zero value.

CREATE TABLE `event` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `class` varchar(255) NOT NULL,
  `start_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `end_date` timestamp NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Storing Sample Events

To make the example Bootstrap Calendar Events Demo using Python Flask MySQL workable, we have added few rows into table:

insert  into `event`(`id`,`title`,`url`,`class`,`start_date`,`end_date`) values 
(1,'Example','http://www.example.com','event-sucess','2019-09-10 20:00:00','2019-09-10 20:01:02'),
(2,'Roy Tutorials','https://roytuts.com','event-important','2019-09-15 19:00:00','2019-09-15 19:42:45'),
(3,'Roy Tutorial','https://roytuts.com','event-info','2019-09-23 20:03:05','2019-09-24 08:45:53'),
(4,'Roy Tutorial','https://roytuts.com','event-error','2019-09-24 20:03:05','2019-09-25 08:45:53');

Creating Project Directory

Create a project root directory called python_flask_mysql_bootstrap_calendar_events as per your chosen location.

We may not mention the project’s root directory name in the subsequent sections but we will assume that we are creating files with respect to the project’s root directory.

Related Posts:

Configuring Application

We will configure application through flask framework.

Create a file called app.py with the below code.

from flask import Flask

app = Flask(__name__)

Database Configuration

We create the below db_config.py Python script to setup the MySQL database configurations for connecting to database.

We need to configure database connection with flask module and that’s why we have imported app module and setup the MySQL configuration with flask module.

from app import app
from flaskext.mysql import MySQL

mysql = MySQL()
 
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'root'
app.config['MYSQL_DATABASE_DB'] = 'roytuts'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

Creating Template View

We will render a template when application’s context root is hit on the browser.

This template file in turn calls the REST endpoint to display events on calendar.

The template file calendar_events.html is put under templates directory with below source code.

Notice how we are including static resources on template file in flask web application.

We have used latest versions of jQuery and Underscore from CDN. The older jQuery and Underscore libraries have been commented out but if you want to use older version of these libraries you can always find in the source code.

We are using older version bootstrap because the newer version 4.3.1 of bootstrap makes the layout a little messy.

<!DOCTYPE html>
<html>
<head>
	<title>Python Flask MySQL Bootstrap Calendar Events</title>
	<meta charset="UTF-8">
	<link type="text/css"  rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.css') }}"/>
	<link type="text/css"  rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap-responsive.css') }}"/>
	<link type="text/css"  rel="stylesheet" href="{{ url_for('static', filename='css/calendar.min.css') }}"/>
</head>
<body>
	<div class="container">
		<div>
			<h4>Bootstrap Calendar Events Demo using Python Flask MySQL</h4>
		</div>

		<div class="page-header">

			<div class="pull-right form-inline">
				<div class="btn-group">
					<button class="btn btn-primary" data-calendar-nav="prev"><< Prev</button>
					<button class="btn" data-calendar-nav="today">Today</button>
					<button class="btn btn-primary" data-calendar-nav="next">Next >></button>
				</div>
				<div class="btn-group">
					<button class="btn btn-warning" data-calendar-view="year">Year</button>
					<button class="btn btn-warning active" data-calendar-view="month">Month</button>
					<button class="btn btn-warning" data-calendar-view="week">Week</button>
					<button class="btn btn-warning" data-calendar-view="day">Day</button>
				</div>
			</div>

			<h3></h3>
		</div>

		<div class="row">
			<div class="span9">
				<div id="calendar"></div>
			</div>
			<div class="span3">
				<div class="row-fluid">
					<select id="first_day" class="span12">
						<option value="" selected="selected">First day of week is Sunday</option>
						<option value="1">First day of week is Monday</option>
					</select>
					<label class="checkbox">
						<input type="checkbox" value="#events-modal" id="events-in-modal"> Open events in modal window
					</label>
					<label class="checkbox">
						<input type="checkbox" id="format-12-hours"> 12 Hour format
					</label>
					<label class="checkbox">
						<input type="checkbox" id="show_wb" checked> Show week box
					</label>
					<label class="checkbox">
						<input type="checkbox" id="show_wbn" checked> Show week box number
					</label>
				</div>
			</div>
		</div>

		<div class="clearfix"></div>
		<br><br>

		<div class="modal hide fade" id="events-modal">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
				<h3>Event</h3>
			</div>
			<div class="modal-body" style="height: 400px">
			</div>
			<div class="modal-footer">
				<a href="#" data-dismiss="modal" class="btn">Close</a>
			</div>
		</div>
		
		<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
		<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
		<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
		
		<!--<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>-->
		<!--<script type="text/javascript" src="{{ url_for('static', filename='js/underscore-min.js') }}"></script>-->
		<script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
		<script type="text/javascript" src="{{ url_for('static', filename='js/calendar.min.js') }}"></script>
		
		<script>
			(function($) {
				"use strict";
				var options = {
					events_source: 'http://localhost:5000/calendar-events',
					view: 'month',
					tmpl_path: '../../static/tmpls/',
					tmpl_cache: false,
					onAfterViewLoad: function(view) {
						$('.page-header h3').text(this.getTitle());
						$('.btn-group button').removeClass('active');
						$('button[data-calendar-view="' + view + '"]').addClass('active');
					},
					classes: {
						months: {
							general: 'label'
						}
					}
				};

				var calendar = $('#calendar').calendar(options);

				$('.btn-group button[data-calendar-nav]').each(function(){
					var $this = $(this);
					$this.click(function() {
						calendar.navigate($this.data('calendar-nav'));
					});
				});

				$('.btn-group button[data-calendar-view]').each(function(){
					var $this = $(this);
					$this.click(function() {
						calendar.view($this.data('calendar-view'));
					});
				});

				$('#first_day').change(function(){
					var value = $(this).val();
					value = value.length ? parseInt(value) : null;
					calendar.setOptions({first_day: value});
					calendar.view();
				});

				$('#events-in-modal').change(function(){
					var val = $(this).is(':checked') ? $(this).val() : null;
					calendar.setOptions({modal: val});
				});
				$('#format-12-hours').change(function(){
					var val = $(this).is(':checked') ? true : false;
					calendar.setOptions({format12: val});
					calendar.view();
				});
				$('#show_wbn').change(function(){
					var val = $(this).is(':checked') ? true : false;
					calendar.setOptions({display_week_numbers: val});
					calendar.view();
				});
				$('#show_wb').change(function(){
					var val = $(this).is(':checked') ? true : false;
					calendar.setOptions({weekbox: val});
					calendar.view();
				});
				$('#events-modal .modal-header, #events-modal .modal-footer').click(function(e){
					//e.preventDefault();
					//e.stopPropagation();
				});
			}(jQuery));
		</script>
	</div>
</body>
</html>

In the body of the page we have put different navigation controls for the calendar.

You do have also checkboxes for showing week box and week number. You can also change the data format as 12 hours format. You also have the option for seeing events in modal windows.

Then you have div area for defining modal window, which will be shown when a user clicks on even link with ‘Open events in modal window’ checkbox selected.

Next we added required JavaScript files and calendar setup options.

We set the events_source link and bootstrap calendar template paths.

Rendering View and Defining REST Endpoint

We will create a file called main.py with the following source code to render a view and define a REST endpoint for fetching data from MySQL databasse server.

import pymysql
from app import app
from db_config import mysql
from flask import flash, render_template, jsonify

@app.route('/')
def home():
	return render_template('calendar_events.html')

@app.route('/calendar-events')
def calendar_events():
	conn = None
	cursor = None
	try:
		conn = mysql.connect()
		cursor = conn.cursor(pymysql.cursors.DictCursor)
		cursor.execute("SELECT id, title, url, class, UNIX_TIMESTAMP(start_date)*1000 as start, UNIX_TIMESTAMP(end_date)*1000 as end FROM event")
		rows = cursor.fetchall()
		resp = jsonify({'success' : 1, 'result' : rows})
		resp.status_code = 200
		return resp
	except Exception as e:
		print(e)
	finally:
		cursor.close() 
		conn.close()
		
if __name__ == "__main__":
    app.run()

Rendering Template View

We will define a function using flask API, which will render the template file.

The template file is read from templates folder so you don’t need to mention the name of the folder.

@app.route('/')
def home():
	return render_template('calendar_events.html')

Configuring REST Endpoint

We will define a REST endpoint which will fetch all the events from MySQL database and display on the view.

@app.route('/calendar-events')
def calendar_events():
	conn = None
	cursor = None
	try:
		conn = mysql.connect()
		cursor = conn.cursor(pymysql.cursors.DictCursor)
		cursor.execute("SELECT id, title, url, class, UNIX_TIMESTAMP(start_date)*1000 as start, UNIX_TIMESTAMP(end_date)*1000 as end FROM event")
		rows = cursor.fetchall()
		resp = jsonify({'success' : 1, 'result' : rows})
		resp.status_code = 200
		return resp
	except Exception as e:
		print(e)
	finally:
		cursor.close() 
		conn.close()

We are retrieving timestamp values in seconds using UNIX_TIMESTAMP() function and converting them to milliseconds as it is required by the bootstrap calendar plugin.

Also notice that I have put alias for date fields as the bootstrap calendar plugin requires following structure:

[
	...
	
	{
		"id": 293,
		"title": "Event 1",
		"url": "http://example.com",
		"class": "event-important",
		"start": 12039485678000, // Milliseconds
		"end": 1234576967000 // Milliseconds
	}
	
	...
]

Testing the Application

Now after doing so much hard work, it’s time to see the live on browser how it looks like.

When you are on home page, you should see the similar page on your browser:

bootstrap calendar events demo using python flask mysql

When you click on the colorful rounded circle on the event links then you will be redirected to the new page.

When you mouse hover on the calendar date then you see the week box with week number.

When you select the checkbox for Open events in modal window and click on the event link you will see it in modal popup/window.

If you are unable to see the events with colorful circle then you may not have the events in the database for current month.

Source Code

download source code

Thanks for reading.

2 thoughts on “Bootstrap Calendar Events Demo using Python Flask MySQL

  1. Your tutorial is very helpful! Thanks!
    But I have some problem when opening the page ‘calendar-events’, it only displays the text like json without the colorful calendar template. I did no change to your code. (Except for the password and database name of my mysql)
    Where do you think I made a mistake? I really need help in a hurry! Thank you so much!

Leave a Reply

Your email address will not be published. Required fields are marked *