() translation by (you can also view the original English article)
Pada bagian sebelumnya dari seri tutorial ini, kita mengimplementasi fungsi yang dibutuhkan untuk user yang sudah login untuk menambahkan keinginan. Kita juga lihat bagaimana menampilkan keinginan yang dimasukkan user di halaman beranda user.
Pada bagian ini kita akan membuat fungsi untuk mengedit dan menghapus keinginan yang dimasukkan user.
Memulai
Kita mulai dengan membuat klon bagian sebelumnya dari tutorial dari GitHub.
1 |
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part3.git |
Setelah source code sudah diklon, masuk ke direktori proyek dan nyalakan web server.
1 |
cd PythonFlaskMySQLApp_Part3
|
2 |
python app.py |
Arahkan browser ke http://localhost:5002/ dan kamu akan menemukan aplikasinya berjalan.
Mengedit Daftar Keinginan
Langkah 1: Menampilkan Ikon Edit
Kita sudah mengikat data yang diterima dari jQuery ke HTML kita. Kita akan memodifikasi kode dan menggunakan template jQuery untuk membuatnya lebih mudah untuk mengikat data. Kita juga menambahkan ikon edit
pada HTML kita untuk menyediakan cara untuk mengupdate keinginan. Buka userHome.html
dan tambahkan referensi ke template jQuery.
1 |
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script> |
Hapus div list-group
yang ada dan gantikan dengan kode HTML berikutt:
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>
|
Di dalam UL
dengan kelas list-group
kita akan mengikat data kita. Definisikan listTemplate
seperti terlihat di body HTML berikut:
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>
|
Ubah pemanggilan sukses AJAX jQuery
untuk mengikat data ke 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>
|
Tambahkan juga beberapa gayar di 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> |
Simpan semua perubahan dan restart server. Arahkan browser ke http://localhost:5002 dan sign in menggunakan email dan password yang sah. Setelah login, kamu bisa melihat keinginan yang dibuat user.



Langkah 2: Menampilkan popup Edit
Kita akan menggunakan Bootstrap untuk menampilkan popup untuk menyediakan antarmuka untuk mengedit keinginan. Tambahkan referensi untuk Bootstrap di userHome.html
.
1 |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> |
Begitu referensi dimasukkan, tambahkan HTML berikut ke 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">×</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>
|
HTML di atas akan menjadi popup. Ketika user menekan ikon edit
popup akan muncul. Kita sudah menambahkan atribut data-target
dan data-toggle
yang akan memunculkan popup.
1 |
<a data-toggle="modal" data-target="#editModal"><span class="glyphicon glyphicon-pencil"></span></a> |
Simpan perubahan di atas dan restart aplikasi. Setelah sign-in ke aplikasi, klik ikon edit
dan kamu akan melihat popup.



Langkah 3: Mengisi Popup Edit
Ketika user menekan ikon edit, kita aman munculkan popup untuk memperbarui dengan title
dan description
yang akan diperbarui. Untuk memulai, kita perlu ID keinginan untuk mengambil detail keinginan yang bersangkutan saat user menekan ikon edit. Jadi ubah kode template jQuery dengan tambahan atribut data-id
pada tautan elemen edit.
1 |
<a data-id=${Id} onclick="Edit(this)" ><span class="glyphicon glyphicon-pencil"></span></a> |
Kita juga menyimpan event onclick
untuk memanggil fungsi Edit
. Di dalam fungsi Edit, kita akan membuat panggilan AJAX ke fungsi python bernama getWishById
yang akan mengembalikan detail keinginan yang dibutuhkan.
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 |
}
|
Berikutnya, buka app.py
dan buat fungsi baru bernama getWishById
. Menggunakan fungsi ini, kita akan ambil detail keinginan dari 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)) |
Seperti yang kamu lihat di fungsi di atas, kita melempar ID keinginan ke fungsi ini dan fungsi tersebut mendapatkan data dari database menggunakan user ID
dan wish ID
. Setelah data didapat, fungsi tersebut mengubah data menjadi list dan mengembalikannya sebagai data JSON
.
Berikutnya, kita buat stored procedure MySQL yang dibutuhkan untuk mengambil data dari 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
|
Kode di atas adalah stored procedure untuk mengambil detail keinginan menggunakan wish ID
dan user ID
.
Simpan perubahan dan restart server. Setelah kamu sign-in ke aplikasi, klik ikon edit
dan kamu akan melihat detail yang tertulis di konsol browsermu.
Untuk mengikat data yang diterima ke popup HTML, kita perlu menghapus atribut data-target
dan data-toggle
dari tag tautan ikon edit. Lalu tambahkan kode berikut ke callback sukses dari fungsi JavaScript Edit
untuk mengisi popup dan memicunya.
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(); |
Simpan perubahan dan restart server. Setelah sign-in ke aplikasi, cobalah klik ikon edit dan kamu akan lihat popup dengan judul dan deskripsi.



Langkah 4: Memperbarui Detail Keinginan
Untuk mengimplementasi fungsi update, kita buat stored procedure MySQL.
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 ; |
Seperti yang terlihat pada stored procedure di atas, kita akan mengirim title
dan description
yang sudah dimodifikasi bersama dengan ID
dari keinginan dan user untuk memperbarui detail di database.
Lalu, buat fungsi baru bernama updateWish
untuk memperbarui detail. Berikut adalah fungsi updateWish
:
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() |
Seperti yang terlihat di kode di atas, setelah memvalidasi session yang sah, kita mengumpulkan data yang dikirim dan memanggil fungsi sp_updateWish
untuk memperbarui detail.
Untuk memanggil fungsi updateWish
, kita perlu menambahkan event saat user menekan tombol Update
. Jadi, beri nama tombol update btnUpdate
dan tambahkan event onclick
sebagai beirkut:
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 |
});
|
Seperti terlihat pada kode di atas, kita sudah mengumpulkan editId
dari localStorage
, jadi di dalam fungsi Edit
simpan ID
ke localStorage
.
1 |
localStorage.setItem('editId',$(elm).attr('data-id')); |
Masukkan pemanggilan AJAX getWish
ke sebuah fungsi, jadi kita bisa memanggilnya kembali saat data sudah diperbarui.
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 |
}
|
Panggil fungsi GetWishes
pada kondisi sukses dari pemanggilan AJAX update
.
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 |
});
|
Simpan semua perubahan dan restart server. Setelah sign-in ke aplikasi, cobalah edit keinginan yang sudah dibuat oleh user.
Menghapus Keinginan
Langkah 1: Menampilkan Popup Konfirmasi
Tambahkan kode HTML berikut ke 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>
|
Tambahkan ikon hapus di dalam listTemplate
dengan menambahkan HTML berikut:
1 |
<a data-id=${Id} onclick="ConfirmDelete(this)" ><span class="glyphicon glyphicon-trash"></span></a> |
Saat menekan ikon hapus di atas, kita panggil fungsi JavaScript bernama ConfirmDelete
yang akan memicu popup konfirmasi.
1 |
function ConfirmDelete(elem) { |
2 |
localStorage.setItem('deleteId', $(elem).attr('data-id')); |
3 |
$('#deleteModal').modal(); |
4 |
}
|
Simpan perubahan dan restart server. Setelah sign-in, klik ikon hapus pada daftar keinginan dan kamu akan lihat popup konfirmasi yang muncul.



Langkah 2: Hapus sebuah Keinginan
Untuk mengimplementasi fungsi menghapus keinginan, kita buat stored procedure untuk menghapus.
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 ; |
Prosedur tersebut menerima ID keinginan dan user dan menghapus keinginan yang bersangkutan dari database.
Lalu, buat sebuah fungsi di dalam app.py
untuk memanggil prosedur sp_deleteWish
.
Kita akan buat sebuah fungsi bernama deleteWish
untuk menghapus keinginan.
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() |
Pada fungsi di atas, kita perlu memvalidasi session. Setelah kita validasi user session, gunakan ID keinginan dan user yang kita dapat untuk memanggil stored procedure sp_deleteWish
.
Untuk memanggil fungsi deleteWish
, tambahkan event onclick
ke tombol Delete pada popup konfirmasi menghapus.
1 |
<button type="button" class="btn btn-primary" onclick="Delete()">Delete</button> |
Buat fungsi JavaScript bernama Delete
, dan di dalam Delete buat pemanggilan AJAX ke fungsi python 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 |
}
|
Pada kondisi sukses fungsi Delete
di atas, kita akan peruksa status yang dikembalikan, jika OK kita kaan sembunyikan popup dan memuat ulang daftar keinginan.
Simpan perubahan dan restart server. Setelah login di aplikasi, cobalah menghapus sebuah keinginan dari halaman beranda user.
Kesimpulan
Pada bagian ini, kita lihat bagaimana untuk mengimplementasi fitur Edit
dan Delete
pada aplikasi Daftar Keinginan kita. Pada bagian berikutnya, kita akan implementasi pagination untuk daftar pada halaman beranda user dan mengimplementasi beberapa fitur lain.
Source code dari tutorial ini tersedia di GitHub.
Beri tahu kami pendapatmu di komentar di bawah!