article

Wednesday, October 14, 2020

Flask Add Edit Delete with Jquery ajax, jQuery Templates and MySQLdb Database

 


Flask Add Edit Delete with Jquery ajax, jQuery Templates and MySQLdb Database

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
#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>

Related Post