Advertisement
  1. Code
  2. Coding Fundamentals
  3. Databases & SQL

Creating a Web App From Scratch Using Python Flask and MySQL: Part 4

Scroll to top
Read Time: 11 min
This post is part of a series called Creating a Web App From Scratch Using Python Flask and MySQL.
Creating a Web App From Scratch Using Python Flask and MySQL: Part 3
Creating a Web App From Scratch Using Python Flask and MySQL: Part 5

In the previous part of this tutorial series, we implemented the required functionality for a logged-in user to add a wish. We also saw how to display the wishes entered by a user on the user home page.

In this part, we'll implement the functionality for editing and deleting the wishes entered by a user.

Getting Started

Let's start by cloning the previous part of the tutorial from GitHub.

1
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part3.git

Once the source code has been cloned, navigate to the project directory and start the web server. 

1
cd PythonFlaskMySQLApp_Part3
2
python app.py

Point your browser to http://localhost:5002/ and you should have the application running.

Editing the Wish List

Step 1: Display the Edit Icon

We are already binding the received data using jQuery to our HTML. We'll modify that code and use jQuery templates to make it easier to bind data. We'll also add an edit icon to our HTML to provide a way to update the wish. Open userHome.html and include a reference to jQuery templates.

1
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>

Remove the existing list-group div and replace it with the following HTML code:

1
<div class="row">
2
    <div class="col-md-12">
3
4
        <div class="panel-body">
5
6
            <ul id="ulist" class="list-group">
7
8
9
10
            </ul>
11
        </div>
12
13
    </div>
14
</div>

Inside the UL with class list-group we'll be binding our data. Define a listTemplate as shown in the body of the HTML:

1
<script id="listTemplate" type="text/x-jQuery-tmpl">
2
    <li class="list-group-item">
3
        <div class="checkbox">
4
            <label>
5
                ${Title}
6
            </label>

7
        </div>

8
        <div class="pull-right action-buttons">
9
            <a data-toggle="modal" data-target="#editModal"><span class="glyphicon glyphicon-pencil"></span></a>
10
           
11
        </div>

12
    </li>

13
</script>

Modify the jQuery AJAX success callback to bind the data to the listTemplate.

1
<script>
2
    $(function() {
3
        $.ajax({
4
            url: '/getWish',
5
            type: 'GET',
6
            success: function(res) {
7
8
                // Parse the JSON response

9
                var wishObj = JSON.parse(res);
10
                
11
                // Append to the template

12
                $('#listTemplate').tmpl(wishObj).appendTo('#ulist');
13
14
15
            },
16
            error: function(error) {
17
                console.log(error);
18
            }
19
        });
20
    });
21
</script>

Also, include some styles in userHome.html:

1
<style>
2
    .trash {
3
        color: rgb(209, 91, 71);
4
    }
5
    .panel-body .checkbox {
6
        display: inline-block;
7
        margin: 0px;
8
    }
9
    .list-group {
10
        margin-bottom: 0px;
11
    }
12
</style>

Save all the changes and restart the server. Point your browser to http://localhost:5002 and sign in using a valid email address and password. Once logged in, you should be able to see the wishes created by the user.

User Home with Edit IconUser Home with Edit IconUser Home with Edit Icon

Step 2: Display the Edit Popup

We'll be using Bootstrap to show a popup to provide an interface to edit the wishes. Include a reference to Bootstrap in userHome.html.

1
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

Once the reference has been included, add the following HTML to userHome.html.

1
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
2
    <div class="modal-dialog">
3
        <div class="modal-content">
4
            <div class="modal-header">
5
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span>
6
                </button>
7
                <h4 class="modal-title" id="editModalLabel">Update Wish</h4>
8
            </div>
9
            <div class="modal-body">
10
                <form role="form">
11
                    <div class="form-group">
12
                        <label for="recipient-name" class="control-label">Title:</label>
13
                        <input type="text" class="form-control" id="editTitle">
14
                    </div>
15
                    <div class="form-group">
16
                        <label for="message-text" class="control-label">Description:</label>
17
                        <textarea class="form-control" id="editDescription"></textarea>
18
                    </div>
19
                </form>
20
            </div>
21
            <div class="modal-footer">
22
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
23
                <button type="button" id="btnUpdate" class="btn btn-primary">Update</button>
24
            </div>
25
        </div>
26
    </div>
27
</div>

The above HTML will serve as the popup. When the user clicks the edit icon the popup will show. We have already added the attributes data-target and data-toggle which will trigger the modal popup.

1
 <a data-toggle="modal" data-target="#editModal"><span class="glyphicon glyphicon-pencil"></span></a>

Save the above changes and restart the app. Once signed in to the application, click on the edit icon and you should be able to view the popup.

Edit Wish PopupEdit Wish PopupEdit Wish Popup

Step 3: Populate the Edit Popup

When the user clicks the edit icon, we'll show the update popup with the title and description to update. In order to get started, first we need the wish ID to fetch the particular wish details once the user clicks the edit icon. So modify the jQuery template code to include an extra attribute data-id on the edit anchor element.

1
<a data-id=${Id} onclick="Edit(this)" ><span class="glyphicon glyphicon-pencil"></span></a>

We have also attached an onclick event to call the method Edit. Inside the Edit function, we'll make an AJAX call to a python method called getWishById which will return the wish details.

1
function Edit(elm) {
2
    $.ajax({
3
        url: '/getWishById',
4
        data: {
5
            id: $(elm).attr('data-id')
6
        },
7
        type: 'POST',
8
        success: function(res) {
9
            console.log(res);
10
        },
11
        error: function(error) {
12
            console.log(error);
13
        }
14
    });
15
}

Next, open up app.py and create a method called getWishById. Using this method, we'll get the particular wish details from the database.

1
@app.route('/getWishById',methods=['POST'])
2
def getWishById():
3
    try:
4
        if session.get('user'):
5
6
            _id = request.form['id']
7
            _user = session.get('user')
8
9
            conn = mysql.connect()
10
            cursor = conn.cursor()
11
            cursor.callproc('sp_GetWishById',(_id,_user))
12
            result = cursor.fetchall()
13
14
            wish = []
15
            wish.append({'Id':result[0][0],'Title':result[0][1],'Description':result[0][2]})
16
17
            return json.dumps(wish)
18
        else:
19
            return render_template('error.html', error = 'Unauthorized Access')
20
    except Exception as e:
21
        return render_template('error.html',error = str(e))

As you can see in the above method, we have passed in the wish ID to this method and it gets the data from the database using the user ID and wish ID. Once the data has been fetched, it converts that data into a list and then returns it as JSON data.

Next, let's create the required MySQL stored procedure to fetch data from the database.

1
DELIMITER $$
2
3
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishById`(
4
IN p_wish_id bigint,
5
In p_user_id bigint
6
)
7
BEGIN
8
select * from tbl_wish where wish_id = p_wish_id and wish_user_id = p_user_id;
9
END

The code shown above is the stored procedure to get particular wish details using the wish ID and user ID.

Save the changes and restart the server. Once signed in to the application, click on the edit icon and you should have the details logged in your browser console.

To bind the received data to the HTML popup, first remove the data-target and data-toggle attributes from the edit icon anchor tag. Then add the following code to the Edit JavaScript function success callback to populate the popup and trigger it.

1
// Parse the received JSON string

2
var data = JSON.parse(res);
3
4
//Populate the Pop up

5
$('#editTitle').val(data[0]['Title']);
6
$('#editDescription').val(data[0]['Description']);
7
8
// Trigger the Pop Up

9
$('#editModal').modal();

Save the changes and restart the server. Once signed in to the application, try to click the edit icon and you should have the popup with the title and description.

Populated Edit Pop UpPopulated Edit Pop UpPopulated Edit Pop Up

Step 4: Update Wish Details

To implement the update functionality, let's first create a MySQL stored procedure.

1
DELIMITER $$
2
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_updateWish`(
3
IN p_title varchar(45),
4
IN p_description varchar(1000),
5
IN p_wish_id bigint,
6
In p_user_id bigint
7
)
8
BEGIN
9
update tbl_wish set wish_title = p_title,wish_description = p_description
10
    where wish_id = p_wish_id and wish_user_id = p_user_id;
11
END$$
12
DELIMITER ;

As seen in the stored procedure above, we'll be passing in the modified title and description along with the ID of the wish and the user to update the details in the database.

Next, let's create a new method called updateWish to update the details. Here is the updateWish method:

1
@app.route('/updateWish', methods=['POST'])
2
def updateWish():
3
    try:
4
        if session.get('user'):
5
            _user = session.get('user')
6
            _title = request.form['title']
7
            _description = request.form['description']
8
            _wish_id = request.form['id']
9
10
11
12
            conn = mysql.connect()
13
            cursor = conn.cursor()
14
            cursor.callproc('sp_updateWish',(_title,_description,_wish_id,_user))
15
            data = cursor.fetchall()
16
17
            if len(data) is 0:
18
                conn.commit()
19
                return json.dumps({'status':'OK'})
20
            else:
21
                return json.dumps({'status':'ERROR'})
22
    except Exception as e:
23
        return json.dumps({'status':'Unauthorized access'})
24
    finally:
25
        cursor.close()
26
        conn.close()

As seen in the above code, after validating for a valid session, we have collected the posted data and called the stored procedure sp_updateWish to update the details.

In order to call the updateWish method, we need to attach an event on the Update button click. So, name the update button btnUpdate and attach an onclick event as shown:

1
$('#btnUpdate').click(function() {
2
    $.ajax({
3
        url: '/updateWish',
4
        data: {
5
            title: $('#editTitle').val(),
6
            description: $('#editDescription').val(),
7
            id: localStorage.getItem('editId')
8
        },
9
        type: 'POST',
10
        success: function(res) {
11
            $('#editModal').modal('hide');
12
            // Re populate the grid

13
        },
14
        error: function(error) {
15
            console.log(error);
16
        }
17
    })
18
});

As seen in the above code, we have collected the editId from localStorage, so inside the Edit function save the ID into localStorage.

1
localStorage.setItem('editId',$(elm).attr('data-id'));

Wrap up the getWish AJAX call into a function, so that we can call it again once the data has been updated.

1
function GetWishes() {
2
    $.ajax({
3
        url: '/getWish',
4
        type: 'GET',
5
        success: function(res) {
6
            var wishObj = JSON.parse(res);
7
            $('#ulist').empty();
8
            $('#listTemplate').tmpl(wishObj).appendTo('#ulist');
9
        },
10
        error: function(error) {
11
            console.log(error);
12
        }
13
    });
14
}

Call the GetWishes function in the success callback of the update AJAX call.

1
$('#btnUpdate').click(function() {
2
    $.ajax({
3
        url: '/updateWish',
4
        data: {
5
            title: $('#editTitle').val(),
6
            description: $('#editDescription').val(),
7
            id: localStorage.getItem('editId')
8
        },
9
        type: 'POST',
10
        success: function(res) {
11
            $('#editModal').modal('hide');
12
            
13
            // Re populate the grid

14
            GetWishes();
15
        },
16
        error: function(error) {
17
            console.log(error);
18
        }
19
    })
20
});

Save all the changes and restart the server. Once signed in to the application, try to edit the available wishes created by the user.

Deleting a Wish

Step 1: Show a Confirmation Popup

Add the following HTML code to userHome.html.

1
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
2
    <div class="modal-dialog">
3
        <div class="modal-content">
4
            <div class="modal-header" style="text-align:center;">
5
                <h4 class="modal-title" style="color:red;" id="deleteModalLabel">You are going to Delete this forever !!</h4>
6
            </div>
7
8
            <div class="modal-footer">
9
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
10
                <button type="button" class="btn btn-primary">Delete</button>
11
            </div>
12
        </div>
13
    </div>
14
</div>

Add a delete icon inside the listTemplate by adding the following HTML:

1
<a data-id=${Id} onclick="ConfirmDelete(this)" ><span class="glyphicon glyphicon-trash"></span></a>

On clicking on the above delete icon, we'll call a JavaScript function called ConfirmDelete where we'll trigger the confirmation popup.

1
function ConfirmDelete(elem) {
2
    localStorage.setItem('deleteId', $(elem).attr('data-id'));
3
    $('#deleteModal').modal();
4
}

Save the changes and restart the server. Once signed in, click on the delete icon in the wish list and you should be able to see the confirmation popup.

Delete Confirmation PopupDelete Confirmation PopupDelete Confirmation Popup

Step 2: Delete a Wish

To implement the Delete wish functionality, first let's create the MySQL stored procedure to delete.

1
DELIMITER $$
2
USE `BucketList`$$
3
CREATE PROCEDURE `sp_deleteWish` (
4
IN p_wish_id bigint,
5
IN p_user_id bigint
6
)
7
BEGIN
8
delete from tbl_wish where wish_id = p_wish_id and wish_user_id = p_user_id;
9
END$$
10
11
DELIMITER ;

The above procedure takes in the wish ID and user ID and deletes the corresponding wish from the database.

Next, let's create a method inside app.py to call the procedure sp_deleteWish

We'll create a method called deleteWish for wish deletion.

1
@app.route('/deleteWish',methods=['POST'])
2
def deleteWish():
3
    try:
4
        if session.get('user'):
5
            _id = request.form['id']
6
            _user = session.get('user')
7
8
            conn = mysql.connect()
9
            cursor = conn.cursor()
10
            cursor.callproc('sp_deleteWish',(_id,_user))
11
            result = cursor.fetchall()
12
13
            if len(result) is 0:
14
                conn.commit()
15
                return json.dumps({'status':'OK'})
16
            else:
17
                return json.dumps({'status':'An Error occured'})
18
        else:
19
            return render_template('error.html',error = 'Unauthorized Access')
20
    except Exception as e:
21
        return json.dumps({'status':str(e)})
22
    finally:
23
        cursor.close()
24
        conn.close()

In the above method, we have first validated the session. Once we have validated the user session, using the wish ID and the user ID we have called the stored procedure sp_deleteWish.

To call the above method deleteWish, add an onclick event to the Delete button in the delete confirmation popup.

1
<button type="button" class="btn btn-primary" onclick="Delete()">Delete</button>

Create a JavaScript function called Delete, and inside Delete make an AJAX call to the python method deleteWish.

1
function Delete() {
2
    $.ajax({
3
        url: '/deleteWish',
4
        data: {
5
            id: localStorage.getItem('deleteId')
6
        },
7
        type: 'POST',
8
        success: function(res) {
9
            var result = JSON.parse(res);
10
            if (result.status == 'OK') {
11
                $('#deleteModal').modal('hide');
12
                GetWishes();
13
            } else {
14
                alert(result.status);
15
            }
16
        },
17
        error: function(error) {
18
            console.log(error);
19
        }
20
    });
21
}

On the success callback of the above Delete function, we'll check for the returned status, and if it's OK we'll hide the modal popup and reload the wishes.

Save the changes and restart the server. Once logged in to the application, try to delete a wish from the user home page.

Conclusion

In this part of the series, we saw how to implement the Edit and Delete wish functionality for our Bucket List Application. In the next part of this series, we'll implement pagination for our user home list and also implement a few more features.

Source code from this tutorial is available on GitHub.

Do let us know your thoughts in the comments below!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.