I den forrige del af denne serie så vi, hvordan man implementerer Edit
og Delete
ønsker funktionalitet til vores Bucket List Application. I denne del implementerer vi personsøgningsfunktionaliteten til vores brugerhjemmeliste.
Kom godt i gang
Lad os starte med at klone den forrige del af selvstudiet fra GitHub.
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part4.git
Når kildekoden er blevet klonet, skal du navigere til projektbiblioteket og starte webserveren.
cd PythonFlaskMySQLApp_Part4 python app.py
Peg din browser til http://localhost:5002/ og du burde have applikationen kørende.
Implementering af sideinddeling
Efterhånden som listen over ønsker på brugerhjemmesiden øges, bliver den rullet ned på siden. Så det er vigtigt at implementere paginering. Vi vil begrænse antallet af elementer, der vises på en side, til et bestemt antal.
Rediger Get Wish-proceduren
Vi starter med at ændre sp_GetWishByUser
procedure for at returnere resultater baseret på en limit
og offset
værdi. Denne gang vil vi oprette vores lagrede procedure-sætning dynamisk for at returnere resultatsættet baseret på grænse- og offsetværdien. Her er den ændrede sp_GetWishByUser
MySQL-lagret procedure.
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 ;
Som det fremgår af ovenstående lagrede procedure, oprettede vi vores dynamiske SQL-forespørgsel og udførte den for at få ønskeliste baseret på offset
og limit
parametre.
Tilføjelse af sideinddeling til brugergrænsefladen
Lad os først definere et par standardindstillinger. I app.py
tilføje en variabel for sidegrænse.
# Default setting pageLimit = 2
Lav getWish
python-metoden accepterer POST-anmodninger.
@app.route('/getWish',methods=['POST'])
Læs offset
og limit
inde i getWish
metode og videregive den, mens du kalder MySQL-lagrede procedure sp_GetWishByUser
.
_limit = pageLimit _offset = request.form['offset'] con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset)) wishes = cursor.fetchall()
Rediger GetWishes
JavaScript-funktion i userHome.html
for at gøre det til en POST-anmodning og videregive offset
værdi.
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); } }); }
Gem alle ændringerne og genstart serveren. Log ind med en gyldig e-mailadresse og adgangskode, og du bør kun have to poster vist på skærmen.
Så databasedelen fungerer godt. Dernæst skal vi tilføje pagineringsbrugergrænsefladen til brugerens startside, hvilket vil gøre det muligt for brugeren at navigere på tværs af dataene.
Vi bruger Bootstrap-pagineringskomponenten. Åbn userHome.html
og tilføj følgende HTML-kode efter #ulist
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>
Gem ændringerne og genstart serveren. Når du har logget ind, bør du kunne se sideinddelingen under ønskeliste.
Gør sideinddeling dynamisk
Ovenstående paginering er, hvordan vores paginering vil se ud. Men for at gøre det funktionelt, er vi nødt til at oprette vores paginering dynamisk baseret på antallet af poster i databasen.
For at oprette vores paginering skal vi bruge det samlede antal poster, der er tilgængelige i databasen. Så lad os ændre den MySQL-lagrede procedure sp_GetWishByUser
for at returnere det samlede antal tilgængelige poster som en ud-parameter.
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 ;
Som det ses i den ovenfor ændrede lagrede procedure, tilføjede vi en ny outputparameter kaldet p_total
og valgte det samlede antal ønsker baseret på bruger-id.
Rediger også getWish
python-metode til at sende en outputparameter.
_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()
Som du kan se i ovenstående kode, lukker vi markøren, når vi har kaldt den lagrede procedure, og åbner en ny markør for at vælge den returnerede parameter.
Tidligere returnerede vi en liste over ønsker fra Python-metoden. Nu skal vi også inkludere det samlede antal poster i den returnerede JSON. Så vi laver ønskesedlens ordbog om til en anden liste og tilføjer så ønskesedlen og registreringsantallet til hovedlisten. Her er den ændrede kode for getWish
python-metoden.
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)
I GetWishes
JavaScript-funktion, inde i succes-tilbagekaldet tilføj en konsollog.
console.log(res);
Gem alle ovenstående ændringer og genstart serveren. Log ind med en gyldig e-mailadresse og adgangskode, og tjek browserkonsollen, når du er på brugerhjemmesiden. Du burde kunne se et svar, der ligner det vist nedenfor:
[ [{ "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 } ]
Ved at bruge det samlede antal modtaget fra svaret kan vi få det samlede antal sider.
var total = wishObj[1]['total']; var pageCount = total/itemsPerPage;
Opdeling af det samlede antal varer fra itemsPerPage
count giver os det nødvendige antal sider. Men dette gælder kun, når totalen er et multiplum af itemsPerPage
. Hvis det ikke er tilfældet, bliver vi nødt til at tjekke for det og håndtere sideantallet i overensstemmelse hermed.
var pageRem = total%itemsPerPage; if(pageRem !=0 ){ pageCount = Math.floor(pageCount)+1; }
Så det vil give os det korrekte sideantal.
Nu, da vi har det samlede antal sider, opretter vi paginerings-HTML'en dynamisk. Fjern LI
element fra paginerings-HTML, vi tilføjede tidligere.
<nav> <ul class="pagination"> // li we'll create dynamically </ul> </nav>
I GetWishes
succes tilbagekald, lad os oprette det forrige link dynamisk ved hjælp af jQuery.
var prevLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«'))); $('.pagination').append(prevLink);
I ovenstående kode har vi lige oprettet det forrige knaplink og tilføjet det til paginering UL.
Gem ovenstående ændringer og genstart serveren. Ved vellykket login skulle du kunne se det forrige link under listen.
Lad os på samme måde tilføje siderne i pagineringen baseret på sideantallet.
for (var i = 0; i < pageCount; i++) { var page = $('<li/>').append($('<a/>').attr('href', '#').text(i + 1)); $('.pagination').append(page); }
Lad os også tilføje næste link, efter at sidelinket er blevet tilføjet.
var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»'))); $('.pagination').append(nextLink);
Gem ændringerne og genstart serveren. Log ind med en gyldig e-mailadresse og adgangskode, og når du først er på brugerhjemmesiden, bør du kunne se pagineringen.
Vedhæftning af en klikbegivenhed til et sidenummer
Nu kommer hovedlogikken, der vil gøre vores paginering funktionel. Det, vi skal gøre, er at vedhæfte et klikhændelseskald på hvert sideindeks for at kalde GetWishes
JavaScript funktion. Lad os først vedhæfte en klikhændelse til ankerelementet, der viser sidenummeret.
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); }
Så vi har lige knyttet en onclick-begivenhed til sideankeret. Ved hvert klik kalder vi GetWishes
funktion og videregive offset
. Så erklær offset
uden for for-løkken.
var offset = 0;
Ring til GetWishes
funktion inde i klikhændelseskaldet.
GetWishes(offset);
Forøg også offset
baseret på antallet af viste poster.
offset = offset + 2;
Men hver gang GetWishes
funktionen kaldes, værdien af offset
vil altid være det sidste sæt. Så vi vil gøre brug af JavaScript-lukninger til at overføre den korrekte offset til GetWishes
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; }
Gem alle ovenstående ændringer og genstart serveren. Log ind med gyldige legitimationsoplysninger, og prøv at klikke på siderne i paginering UL en gang på brugerhjemmesiden.
Dernæst implementerer vi de forrige og næste sidelinks. Det kan virke lidt kompliceret, så lad mig forklare det lidt, inden vi begynder med implementeringen.
Vi viser fem sider ad gangen. Ved at bruge næste og forrige link kan brugeren navigere til henholdsvis de næste fem og fem foregående sider. Vi gemmer værdierne for startsiden og slutsiden og bliver ved med at opdatere både ved næste og forrige knapklik. Så lad os starte med at tilføje to skjulte felter til userHome.html
side.
<input type="hidden" id="hdnStart" value="1" /> <input type="hidden" id="hdnEnd" value="5"/>
I GetWishes
succes tilbagekald, efter at vi har tømt .pagination
UL, tilføj følgende kodelinje for at få den seneste startside og slutside.
$('.pagination').empty(); var pageStart = $('#hdnStart').val(); var pageEnd = $('#hdnEnd').val();
Der vil ikke blive vist noget tidligere knaplink, når siderne 1 til 5 vises. Hvis de viste sider er større end 5, viser vi det forrige knaplink.
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); }
Når brugeren klikker på den forrige knap, nulstiller vi hdnStart
og hdnEnd
værdier og kalde GetWishes
JavaScript funktion.
$(aPrev).click(function() { $('#hdnStart').val(Number(pageStart) - 5); $('#hdnEnd').val(Number(pageStart) - 5 + 4); GetWishes(Number(pageStart) - 5); });
Dernæst, baseret på startsiden og slutsiden, vil vi sløjfe og oprette sidelinkene og tilføje .pagination
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); }
Ved at sammenligne det samlede sideantal og sidens startværdi bestemmer vi visningen af det næste knaplink.
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); }
Som det fremgår af ovenstående kode, nulstiller vi hdnStart
ved næste klik på knappen og hdnEnd
knapværdier og kalder GetWishes
JavaScript-funktion.
Så her er den sidste 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); } }); }
Gem alle ovenstående ændringer og genstart serveren. Log ind med en gyldig e-mailadresse og adgangskode. Du bør være i stand til at se den fuldt funktionelle paginering for brugerens ønskeliste.