Database Table
CREATE TABLE `tbl_blog` (
`blog_id` int(11) NOT NULL,
`blog_title` varchar(200) NOT NULL,
`blog_description` text NOT NULL,
`blog_user_id` int(11) NOT NULL,
`blog_date` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
#app.py from flask import Flask, render_template, json, request, redirect, session, jsonify from flask_mysqldb import MySQL,MySQLdb #pip install flask-mysqldb https://github.com/alexferl/flask-mysqldb from datetime import datetime app = Flask(__name__) app.secret_key = "caircocoders-ednalan-2020" app.config['MYSQL_HOST'] = 'localhost' app.config['MYSQL_USER'] = 'root' app.config['MYSQL_PASSWORD'] = '' app.config['MYSQL_DB'] = 'flaskdb' app.config['MYSQL_CURSORCLASS'] = 'DictCursor' mysql = MySQL(app) @app.route('/') def main(): return redirect('/userHome') @app.route('/userHome') def userHome(): session['sessionusername'] = "cairocoders@gmail.com" print(session.get('sessionusername')) if session.get('sessionusername'): return render_template('userHome.html') else: return render_template('error.html',error = 'Unauthorized Access') @app.route('/addBlog', methods=['GET', 'POST']) def addBlog(): now = datetime.now() print("now =", now) if request.method == 'POST': _title = request.form['inputTitle'] _description = request.form['inputDescription'] _user = session.get('sessionusername') # validate the received values if _title and _description: cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) result = cur.execute("SELECT * FROM users WHERE email = %s", [_user]) print(result) if result > 0: data = cur.fetchone() blog_user_id = data['id'] cur.execute("INSERT INTO tbl_blog (blog_title, blog_description, blog_user_id, blog_date) VALUES (%s,%s,%s,%s)",(_title,_description,blog_user_id,now,)) mysql.connection.commit() cur.close() return redirect('/userHome') else: error = 'Invalid login' return render_template('addBlog.html', error=error) else: error = 'Enter the required fields' return render_template('addBlog.html', error=error) return render_template('addBlog.html') @app.route('/getBlog') def getBlog(): if session.get('sessionusername'): #_user = session.get('sessionusername') _user = '12' cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) result = cur.execute("SELECT * FROM tbl_blog WHERE blog_user_id = %s", [_user]) blogs = cur.fetchall() blogs_dict = [] for blog in blogs: blog_dict = { 'Id': blog['blog_id'], 'Title': blog['blog_title'], 'Description': blog['blog_description'], 'Date': blog['blog_date']} blogs_dict.append(blog_dict) return json.dumps(blogs_dict) else: print("error getblog") return render_template('error.html', error = 'Unauthorized Access') @app.route('/getBlogById',methods=['GET', 'POST']) def getBlogById(): if session.get('sessionusername'): _id = request.form['id'] cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) result = cur.execute("SELECT * FROM tbl_blog WHERE blog_id = %s", [_id]) blogs = cur.fetchall() blogs_dict = [] for blog in blogs: blog_dict = { 'Id': blog['blog_id'], 'Title': blog['blog_title'], 'Description': blog['blog_description']} blogs_dict.append(blog_dict) return json.dumps(blogs_dict) else: return render_template('error.html', error = 'Unauthorized Access') @app.route('/updateBlog', methods=['POST']) def updateBlog(): if session.get('sessionusername'): _title = request.form['title'] _description = request.form['description'] _blog_id = request.form['id'] cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) cur.execute(""" UPDATE tbl_blog SET blog_title = %s, blog_description = %s WHERE blog_id = %s """, (_title, _description, _blog_id)) mysql.connection.commit() cur.close() return json.dumps({'status':'OK'}) else: return render_template('error.html', error = 'Unauthorized Access') @app.route('/deleteBlog',methods=['POST']) def deleteBlog(): if session.get('sessionusername'): _id = request.form['id'] _user = session.get('user') cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) cur.execute('DELETE FROM tbl_blog WHERE blog_id = {0}'.format(_id)) mysql.connection.commit() cur.close() return json.dumps({'status':'OK'}) else: return render_template('error.html', error = 'Unauthorized Access') if __name__ == '__main__': app.run(debug=True)templates/userHome.html
Binding retrieved data to html via JQuery templates
url for uquery templates https://github.com/BorisMoore/jquery-tmpl
http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js
bind data inside the ul with class list-group
//templates/userHome.html <!DOCTYPE html> <html lang="en"> <head> <title>Flask Add Edit Delete with Jquery ajax, jQuery Templates and MySQLdb Database</title> <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script> <script> $(function(){ $('#btnUpdate').click(function(){ $.ajax({ url : '/updateBlog', data : {title:$('#editTitle').val(),description:$('#editDescription').val(),id:localStorage.getItem('editId')}, type : 'POST', success: function(res){ $('#editModal').modal('hide'); // Re populate the grid GetBlogs(); }, error: function(error){ console.log(error); } }); }); }); function GetBlogs(){ $.ajax({ url : '/getBlog', type : 'GET', success: function(res){ var blogObj = JSON.parse(res); $('#ulist').empty(); $('#listTemplate').tmpl(blogObj).appendTo('#ulist'); }, error: function(error){ console.log(error); } }); } // get blog posts from db when the user signed in $(function() { $.ajax({ url: '/getBlog', type: 'GET', success: function(res) { // Parse the JSON response var blogObj = JSON.parse(res); // Append to the template $('#listTemplate').tmpl(blogObj).appendTo('#ulist'); }, error: function(error) { console.log(error); } }); }); function Edit(elm) { localStorage.setItem('editId',$(elm).attr('data-id')); $.ajax({ url: '/getBlogById', data: { id: $(elm).attr('data-id') }, type: 'POST', success: function(res) { // Parse the received JSON string var data = JSON.parse(res); //Populate the Pop up $('#editTitle').val(data[0]['Title']); $('#editDescription').val(data[0]['Description']); // Trigger the Pop Up $('#editModal').modal('show'); }, error: function(error) { console.log(error); } }); } function ConfirmDelete(elm){ localStorage.setItem('deleteId',$(elm).attr('data-id')); $('#deleteModal').modal('show'); } function Delete(){ $.ajax({ url : '/deleteBlog', data : {id:localStorage.getItem('deleteId')}, type : 'POST', success: function(res){ var result = JSON.parse(res); if(result.status == 'OK'){ $('#deleteModal').modal('hide'); GetBlogs(); } else{ alert(result.status); } }, error: function(error){ console.log(error); } }); } </script> <style> .trash { color: rgb(209, 91, 71); } .panel-body .checkbox { display: inline-block; margin: 0px; } .list-group { margin-bottom: 0px; } </style> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="/userHome">Dashboard</a></li> <li role="presentation"><a href="/addBlog">Add Blog</a></li> <li role="presentation"><a href="/logout">Log Out</a></li> </ul> </nav> <img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ > </div> <script id="listTemplate" type="text/x-jQuery-tmpl"> <li class="list-group-item"> <div class="checkbox"> <label> ${Title} </label> </div> <div class="pull-right action-buttons"> <a data-id=${Id} onclick="Edit(this)"><span class="glyphicon glyphicon-pencil"></span></a> <a data-id=${Id} onclick="ConfirmDelete(this)"><span class="glyphicon glyphicon-trash"></span></a> </div> </li> </script> <div class="row"> <div class="col-md-12"> <div class="panel-body"> <ul id="ulist" class="list-group"> </ul> </div> </div> </div> <div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <h4 class="modal-title" id="editModalLabel">Update Blog</h4> </div> <div class="modal-body"> <form role="form"> <div class="form-group"> <label for="recipient-name" class="control-label">Title:</label> <input type="text" class="form-control" id="editTitle"> </div> <div class="form-group"> <label for="message-text" class="control-label">Description:</label> <textarea class="form-control" id="editDescription"></textarea> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button id="btnUpdate" type="button" class="btn btn-primary">Update</button> </div> </div> </div> </div> <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header" style="text-align:center;"> <h4 class="modal-title" style="color:red;" id="deleteModalLabel">You are going to Delete this forever !!</h4> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-primary" onclick="Delete()">Delete</button> </div> </div> </div> </div> <footer class="footer"> <p>©tutorial101.blogspot.com</p> </footer> </div> </body> </html>templates/error.html
//templates/error.html <!DOCTYPE html> <html lang="en"> <head> <title>Unauthorized Access</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="/">Home</a></li> <li role="presentation"><a href="/login">Sign In</a></li> <li role="presentation"><a href="/signUp">Sign Up</a></li> </ul> </nav> <img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ > </div> <div class="jumbotron"> <h1>{{error}}</h1> </div> <footer class="footer"> <p>©tutorial101.blogspot.com</p> </footer> </div> </body> </html>
templates/addBlog.html
//templates/addBlog.html <!DOCTYPE html> <html lang="en"> <head> <title>Add Blog</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="/userHome">Dashboard</a></li> <li role="presentation"><a href="/addBlog">Add Blog</a></li> <li role="presentation"><a href="/logout">Log Out</a></li> </ul> </nav> <img src="/static/images/Flask_Icon.png" alt="Flask_Icon.png"/ > </div> <section> <form class="form-horizontal" method="post" action="/addBlog"> <fieldset> <legend>Create Your Blog</legend> {% if error %} <div class="alert alert-danger">{{error}}</div> {% endif %} <div class="form-group"> <label class="col-md-4 control-label" for="txtTitle">Title</label> <div class="col-md-4"> <input id="txtTitle" name="inputTitle" type="text" placeholder="placeholder" class="form-control input-md"> </div> </div> <div class="form-group"> <label class="col-md-4 control-label" for="txtPost">Post</label> <div class="col-md-4"> <textarea class="form-control" id="txtPost" name="inputDescription" ></textarea> </div> </div> <div class="form-group"> <label class="col-md-4 control-label" for="singlebutton"></label> <div class="col-md-4"> <input id="singlebutton" name="singlebutton" class="btn btn-primary" type="submit" value="Publish" /> </div> </div> </fieldset> </form> </section> <footer class="footer"> <p>©tutorial101.blogspot.com</p> </footer> </div> </body> </html>