Im vorherigen Teil dieser Serie haben wir gesehen, wie man Edit
implementiert und Delete
Wunschfunktionalität für unsere Bucket List Application. In diesem Teil implementieren wir die Paging-Funktionalität für unsere Benutzer-Home-Liste.
Erste Schritte
Beginnen wir damit, den vorherigen Teil der Anleitung von GitHub zu klonen.
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part4.git
Navigieren Sie nach dem Klonen des Quellcodes zum Projektverzeichnis und starten Sie den Webserver.
cd PythonFlaskMySQLApp_Part4 python app.py
Richten Sie Ihren Browser auf http://localhost:5002/ und Sie sollten die Anwendung ausführen.
Paginierung implementieren
Wenn die Wunschliste auf der Startseite des Nutzers länger wird, wird sie auf der Seite nach unten gescrollt. Daher ist es wichtig, die Paginierung zu implementieren. Wir begrenzen die Anzahl der auf einer Seite angezeigten Elemente auf eine bestimmte Anzahl.
Modifizieren Sie das „Get Wish“-Verfahren
Wir beginnen mit der Änderung von sp_GetWishByUser
Prozedur, um Ergebnisse basierend auf einem limit
zurückzugeben und offset
Wert. Dieses Mal erstellen wir unsere Stored Procedure-Anweisung dynamisch, um die Ergebnismenge basierend auf dem Grenzwert und dem Offsetwert zurückzugeben. Hier ist der modifizierte sp_GetWishByUser
Gespeicherte MySQL-Prozedur.
USE `BucketList`; DROP procedure IF EXISTS `sp_GetWishByUser`; DELIMITER $$ USE `BucketList`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`( IN p_user_id bigint, IN p_limit int, IN p_offset int ) BEGIN SET @t1 = CONCAT( 'select * from tbl_wish where wish_user_id = ', p_user_id, ' order by wish_date desc limit ',p_limit,' offset ',p_offset); PREPARE stmt FROM @t1; EXECUTE stmt; DEALLOCATE PREPARE stmt1; END$$ DELIMITER ;
Wie in der obigen gespeicherten Prozedur zu sehen ist, haben wir unsere dynamische SQL-Abfrage erstellt und ausgeführt, um die Wunschliste basierend auf dem offset
zu erhalten und limit
Parameter.
Paginierung zur Benutzeroberfläche hinzufügen
Lassen Sie uns zunächst einige Standardeinstellungen definieren. In app.py
Fügen Sie eine Variable für das Seitenlimit hinzu.
# Default setting pageLimit = 2
Machen Sie den getWish
Python-Methode akzeptiert POST-Anfragen.
@app.route('/getWish',methods=['POST'])
Lesen Sie den offset
und limit
innerhalb von getWish
-Methode und übergeben sie beim Aufrufen der gespeicherten MySQL-Prozedur sp_GetWishByUser
.
_limit = pageLimit _offset = request.form['offset'] con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset)) wishes = cursor.fetchall()
Ändern Sie die GetWishes
JavaScript-Funktion in userHome.html
um es zu einer POST-Anfrage zu machen und den offset
zu übergeben Wert.
function GetWishes() { $.ajax({ url: '/getWish', type: 'POST', data: { offset: 0 }, success: function(res) { var wishObj = JSON.parse(res); $('#ulist').empty(); $('#listTemplate').tmpl(wishObj).appendTo('#ulist'); }, error: function(error) { console.log(error); } }); }
Speichern Sie alle Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an und Sie sollten nur zwei Einträge auf dem Bildschirm sehen.
Der Datenbankteil funktioniert also gut. Als Nächstes müssen wir die Paginierungs-UI zur Benutzer-Homepage hinzufügen, die es dem Benutzer ermöglicht, durch die Daten zu navigieren.
Wir verwenden die Bootstrap-Paginierungskomponente. Öffnen Sie userHome.html
und fügen Sie den folgenden HTML-Code nach #ulist
hinzu UL.
<nav> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a> </li> <li><a href="#">2</a> </li> <li><a href="#">3</a> </li> <li><a href="#">4</a> </li> <li><a href="#">5</a> </li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav>
Speichern Sie die Änderungen und starten Sie den Server neu. Nach erfolgreicher Anmeldung sollten Sie die Seitennummerierung unter der Wunschliste sehen können.
Paginierung dynamisch gestalten
Die obige Paginierung ist, wie unsere Paginierung aussehen wird. Aber um es funktionsfähig zu machen, müssen wir unsere Paginierung dynamisch basierend auf der Anzahl der Datensätze in der Datenbank erstellen.
Um unsere Paginierung zu erstellen, benötigen wir die Gesamtzahl der in der Datenbank verfügbaren Datensätze. Ändern wir also die gespeicherte MySQL-Prozedur sp_GetWishByUser
um die Gesamtzahl der verfügbaren Datensätze als Ausgangsparameter zurückzugeben.
USE `BucketList`; DROP procedure IF EXISTS `sp_GetWishByUser`; DELIMITER $$ USE `BucketList`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`( IN p_user_id bigint, IN p_limit int, IN p_offset int, out p_total bigint ) BEGIN select count(*) into p_total from tbl_wish where wish_user_id = p_user_id; SET @t1 = CONCAT( 'select * from tbl_wish where wish_user_id = ', p_user_id, ' order by wish_date desc limit ',p_limit,' offset ',p_offset); PREPARE stmt FROM @t1; EXECUTE stmt; DEALLOCATE PREPARE stmt; END$$ DELIMITER ;
Wie in der oben geänderten gespeicherten Prozedur zu sehen ist, haben wir einen neuen Ausgabeparameter namens p_total
hinzugefügt und wählte die Gesamtzahl der Wünsche basierend auf der Benutzer-ID aus.
Ändern Sie auch getWish
Python-Methode, um einen Ausgabeparameter zu übergeben.
_limit = pageLimit _offset = request.form['offset'] _total_records = 0 con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset,_total_records)) wishes = cursor.fetchall() cursor.close() cursor = con.cursor() cursor.execute('SELECT @_sp_GetWishByUser_3'); outParam = cursor.fetchall()
Wie Sie im obigen Code sehen können, schließen wir den Cursor, nachdem wir die gespeicherte Prozedur aufgerufen haben, und öffnen einen neuen Cursor, um den zurückgegebenen Ausgangsparameter auszuwählen.
Zuvor haben wir eine Liste mit Wünschen von der Python-Methode zurückgegeben. Jetzt müssen wir auch die Gesamtanzahl der Datensätze in das zurückgegebene JSON aufnehmen. Also machen wir das Wunschlisten-Wörterbuch zu einer anderen Liste und fügen dann die Wunschliste und die Datensatzanzahl zur Hauptliste hinzu. Hier ist der modifizierte Code von getWish
Python-Methode.
response = [] wishes_dict = [] for wish in wishes: wish_dict = { 'Id': wish[0], 'Title': wish[1], 'Description': wish[2], 'Date': wish[4]} wishes_dict.append(wish_dict) response.append(wishes_dict) response.append({'total':outParam[0][0]}) return json.dumps(response)
In den GetWishes
JavaScript-Funktion, innerhalb des Erfolgsrückrufs fügen Sie ein Konsolenprotokoll hinzu.
console.log(res);
Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an, und überprüfen Sie auf der Benutzer-Homepage die Browserkonsole. Sie sollten eine Antwort sehen, die der folgenden ähnelt:
[ [{ "Date": "Sun, 15 Feb 2015 15:10:45 GMT", "Description": "wwe", "Id": 5, "Title": "wwe" }, { "Date": "Sat, 24 Jan 2015 00:13:50 GMT", "Description": "Travel to Spain", "Id": 4, "Title": "Spain" }], { "total": 5 } ]
Anhand der aus der Antwort erhaltenen Gesamtzahl können wir die Gesamtzahl der Seiten ermitteln.
var total = wishObj[1]['total']; var pageCount = total/itemsPerPage;
Teilen der Gesamtzahl der Artikel durch itemsPerPage
count gibt uns die Anzahl der benötigten Seiten. Dies gilt jedoch nur, wenn die Gesamtzahl ein Vielfaches von itemsPerPage
ist . Wenn dies nicht der Fall ist, müssen wir dies überprüfen und die Seitenzahl entsprechend behandeln.
var pageRem = total%itemsPerPage; if(pageRem !=0 ){ pageCount = Math.floor(pageCount)+1; }
Damit erhalten wir die richtige Seitenzahl.
Da wir jetzt die Gesamtzahl der Seiten haben, erstellen wir den Paginierungs-HTML dynamisch. Entfernen Sie das LI
-Element aus dem Paginierungs-HTML, das wir zuvor hinzugefügt haben.
<nav> <ul class="pagination"> // li we'll create dynamically </ul> </nav>
In den GetWishes
Erfolgs-Callback, lassen Sie uns den vorherigen Link dynamisch mit jQuery erstellen.
var prevLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«'))); $('.pagination').append(prevLink);
Im obigen Code haben wir einfach den vorherigen Schaltflächenlink erstellt und an die Paginierung UL angehängt.
Speichern Sie die obigen Änderungen und starten Sie den Server neu. Nach erfolgreicher Anmeldung sollten Sie den vorherigen Link unter der Liste sehen können.
Lassen Sie uns auf ähnliche Weise die Seiten in der Paginierung basierend auf der Seitenzahl hinzufügen.
for (var i = 0; i < pageCount; i++) { var page = $('<li/>').append($('<a/>').attr('href', '#').text(i + 1)); $('.pagination').append(page); }
Lassen Sie uns auch den Weiter-Link hinzufügen, nachdem der Seiten-Link hinzugefügt wurde.
var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»'))); $('.pagination').append(nextLink);
Speichern Sie die Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an, und sobald Sie auf der Benutzer-Homepage sind, sollten Sie die Paginierung sehen können.
Anhängen eines Klickereignisses an eine Seitenzahl
Jetzt kommt die Hauptlogik, die unsere Paginierung funktionsfähig macht. Was wir tun werden, ist, einen Click-Event-Aufruf an jeden Seitenindex anzuhängen, um die GetWishes
aufzurufen JavaScript-Funktion. Lassen Sie uns zuerst ein Klick-Ereignis an das Ankerelement anhängen, das die Seitenzahl anzeigt.
for (var i = 0; i < pageCount; i++) { var aPage = $('<a/>').attr('href', '#').text(i + 1); $(aPage).click(function() { }); var page = $('<li/>').append(aPage); $('.pagination').append(page); }
Also haben wir einfach ein onclick-Ereignis an den Seitenanker angehängt. Bei jedem Klick rufen wir die GetWishes
auf Funktion und übergeben Sie den offset
. Deklarieren Sie also den offset
außerhalb der for-Schleife.
var offset = 0;
Rufen Sie GetWishes
auf Funktion innerhalb des Click-Event-Aufrufs.
GetWishes(offset);
Erhöhen Sie auch den offset
basierend auf der Anzahl der angezeigten Datensätze.
offset = offset + 2;
Aber jedes Mal die GetWishes
Funktion aufgerufen wird, der Wert von offset
wird immer der letzte Satz sein. Daher verwenden wir JavaScript Closures, um den korrekten Offset an GetWishes
zu übergeben Funktion.
var offset = 0; for (var i = 0; i < pageCount; i++) { var aPage = $('<a/>').attr('href', '#').text(i + 1); $(aPage).click(function(offset) { return function() { GetWishes(offset); } }(offset)); var page = $('<li/>').append(aPage); $('.pagination').append(page); offset = offset + itemsPerPage; }
Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit gültigen Anmeldedaten an und versuchen Sie auf der Startseite des Nutzers, auf die Seiten im Paginierungs-UL zu klicken.
Als Nächstes implementieren wir die Links zur vorherigen und nächsten Seite. Es mag etwas kompliziert erscheinen, also lassen Sie mich es ein wenig erklären, bevor wir mit der Implementierung beginnen.
Wir werden fünf Seiten gleichzeitig anzeigen. Unter Verwendung des nächsten und vorherigen Links kann der Benutzer zu den nächsten fünf bzw. vorherigen fünf Seiten navigieren. Wir speichern die Werte der Startseite und der Endseite und aktualisieren sie sowohl beim nächsten als auch beim vorherigen Klick auf die Schaltfläche. Beginnen wir also damit, zwei versteckte Felder zur userHome.html
hinzuzufügen Seite.
<input type="hidden" id="hdnStart" value="1" /> <input type="hidden" id="hdnEnd" value="5"/>
In den GetWishes
Erfolgsrückruf, nachdem wir die .pagination
geleert haben UL, fügen Sie die folgende Codezeile hinzu, um die neueste Startseite und Endseite zu erhalten.
$('.pagination').empty(); var pageStart = $('#hdnStart').val(); var pageEnd = $('#hdnEnd').val();
Bei der Anzeige der Seiten 1 bis 5 wird kein vorheriger Schaltflächen-Link angezeigt. Wenn mehr als 5 Seiten angezeigt werden, zeigen wir den vorherigen Schaltflächen-Link an.
if (pageStart > 5) { var aPrev = $('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«')); $(aPrev).click(function() { // Previous button logic }); var prevLink = $('<li/>').append(aPrev); $('.pagination').append(prevLink); }
Wenn der Nutzer auf die vorherige Schaltfläche klickt, setzen wir hdnStart
zurück und hdnEnd
Werte und rufen Sie die GetWishes
auf JavaScript-Funktion.
$(aPrev).click(function() { $('#hdnStart').val(Number(pageStart) - 5); $('#hdnEnd').val(Number(pageStart) - 5 + 4); GetWishes(Number(pageStart) - 5); });
Als nächstes erstellen wir basierend auf der Startseite und der Endseite eine Schleife und erstellen die Seitenlinks und hängen die .pagination
an UL.
for (var i = Number(pageStart); i <= Number(pageEnd); i++) { if (i > pageCount) { break; } var aPage = $('<a/>').attr('href', '#').text(i); // Attach the page click event $(aPage).click(function(i) { return function() { GetWishes(i); } }(i)); var page = $('<li/>').append(aPage); // Attach the active page class if ((_page) == i) { $(page).attr('class', 'active'); } $('.pagination').append(page); }
Durch den Vergleich der Gesamtseitenanzahl und des Seitenanfangswerts entscheiden wir über die Anzeige des nächsten Schaltflächenlinks.
if ((Number(pageStart) + 5) <= pageCount) { var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»').click(function() { $('#hdnStart').val(Number(pageStart) + 5); $('#hdnEnd').val(Number(pageStart) + 5 + 4); GetWishes(Number(pageStart) + 5); }))); $('.pagination').append(nextLink); }
Wie im obigen Code zu sehen, setzen wir beim Klicken auf die nächste Schaltfläche den hdnStart
zurück und hdnEnd
Schaltflächenwerte und Aufrufen der GetWishes
JavaScript-Funktion.
Hier also die letzten GetWishes
JavaScript-Funktion.
function GetWishes(_page) { var _offset = (_page - 1) * 2; $.ajax({ url: '/getWish', type: 'POST', data: { offset: _offset }, success: function(res) { var itemsPerPage = 2; var wishObj = JSON.parse(res); $('#ulist').empty(); $('#listTemplate').tmpl(wishObj[0]).appendTo('#ulist'); var total = wishObj[1]['total']; var pageCount = total / itemsPerPage; var pageRem = total % itemsPerPage; if (pageRem != 0) { pageCount = Math.floor(pageCount) + 1; } $('.pagination').empty(); var pageStart = $('#hdnStart').val(); var pageEnd = $('#hdnEnd').val(); if (pageStart > 5) { var aPrev = $('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«')); $(aPrev).click(function() { $('#hdnStart').val(Number(pageStart) - 5); $('#hdnEnd').val(Number(pageStart) - 5 + 4); GetWishes(Number(pageStart) - 5); }); var prevLink = $('<li/>').append(aPrev); $('.pagination').append(prevLink); } for (var i = Number(pageStart); i <= Number(pageEnd); i++) { if (i > pageCount) { break; } var aPage = $('<a/>').attr('href', '#').text(i); $(aPage).click(function(i) { return function() { GetWishes(i); } }(i)); var page = $('<li/>').append(aPage); if ((_page) == i) { $(page).attr('class', 'active'); } $('.pagination').append(page); } if ((Number(pageStart) + 5) <= pageCount) { var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»').click(function() { $('#hdnStart').val(Number(pageStart) + 5); $('#hdnEnd').val(Number(pageStart) + 5 + 4); GetWishes(Number(pageStart) + 5); }))); $('.pagination').append(nextLink); } }, error: function(error) { console.log(error); } }); }
Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an. Sie sollten die voll funktionsfähige Paginierung für die Benutzerwunschliste sehen können.