このシリーズの前のパートでは、Editを実装する方法を見ました およびDelete バケットリストアプリケーションの機能を希望します。このパートでは、ユーザーホームリストのページング機能を実装します。
はじめに
チュートリアルの前の部分をGitHubから複製することから始めましょう。
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part4.git
ソースコードのクローンが作成されたら、プロジェクトディレクトリに移動して、Webサーバーを起動します。
cd PythonFlaskMySQLApp_Part4 python app.py
ブラウザでhttp:// localhost:5002 /を指定すると、アプリケーションが実行されているはずです。
ページネーションの実装
ユーザーのホームページの希望のリストが増えると、ページを下にスクロールします。したがって、ページネーションを実装することが重要です。 1ページに表示されるアイテムの数を特定の数に制限します。
GetWishプロシージャを変更する
まず、sp_GetWishByUserを変更します。 limitに基づいて結果を返す手順 およびoffset 価値。今回は、ストアドプロシージャステートメントを動的に作成して、制限値とオフセット値に基づいて結果セットを返します。変更されたsp_GetWishByUserは次のとおりです MySQLストアドプロシージャ。
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 ;
上記のストアドプロシージャに見られるように、動的SQLクエリを作成して実行し、offsetに基づいてウィッシュリストを取得しました。 およびlimit パラメータ。
UIにページ付けを追加する
まず、いくつかのデフォルト設定を定義しましょう。 app.py内 ページ制限の変数を追加します。
# Default setting pageLimit = 2
getWishを作成します PythonメソッドはPOSTリクエストを受け入れます。
@app.route('/getWish',methods=['POST'])
offsetを読む およびlimit getWish内 メソッドを実行し、MySQLストアドプロシージャsp_GetWishByUserを呼び出しているときに渡します。 。
_limit = pageLimit
_offset = request.form['offset']
con = mysql.connect()
cursor = con.cursor()
cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset))
wishes = cursor.fetchall()
GetWishesを変更します userHome.htmlのJavaScript関数 それをPOSTリクエストにして、offsetを渡します 値。
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);
}
});
} すべての変更を保存して、サーバーを再起動します。有効なメールアドレスとパスワードを使用してサインインすると、画面に表示されるレコードは2つだけになります。
したがって、データベース部分はうまく機能しています。次に、ページネーションUIをユーザーのホームページに追加する必要があります。これにより、ユーザーはデータ間を移動できるようになります。
Bootstrapページネーションコンポーネントを使用します。 userHome.htmlを開きます #ulistの後に次のHTMLコードを追加します 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> 変更を保存して、サーバーを再起動します。サインインに成功すると、ウィッシュリストの下にページネーションが表示されるはずです。
ページネーションを動的にする
上記のページ付けは、私たちのページ付けがどのように見えるかです。ただし、機能させるには、データベース内のレコード数に基づいて動的にページネーションを作成する必要があります。
ページネーションを作成するには、データベースで使用可能なレコードの総数が必要です。それでは、MySQLストアドプロシージャsp_GetWishByUserを変更しましょう。 outパラメータとして使用可能なレコードの総数を返します。
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 ;
上記の変更されたストアドプロシージャに見られるように、p_totalという新しい出力パラメータを追加しました。 そして、ユーザーIDに基づいてウィッシュの総数を選択しました。
getWishも変更します 出力パラメータを渡すPythonメソッド。
_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()
上記のコードでわかるように、ストアドプロシージャを呼び出したら、カーソルを閉じて新しいカーソルを開き、返されたパラメータを選択します。
以前は、Pythonメソッドからウィッシュのリストを返していました。ここで、返されたJSONに合計レコード数も含める必要があります。そこで、ウィッシュリスト辞書を別のリストにしてから、ウィッシュリストとレコード数をメインリストに追加します。これがgetWishの変更されたコードです Pythonメソッド。
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)
GetWishesで JavaScript関数、成功コールバック内にコンソールログを追加します。
console.log(res);
上記の変更をすべて保存して、サーバーを再起動します。有効な電子メールアドレスとパスワードを使用してサインインし、ユーザーのホームページでブラウザコンソールを確認します。以下に示すような応答が表示されるはずです。
[
[{
"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
}
] 回答から受け取った合計数を使用して、合計ページ数を取得できます。
var total = wishObj[1]['total']; var pageCount = total/itemsPerPage;
合計アイテム数をitemsPerPageから除算します countは、必要なページ数を示します。ただし、これは、合計がitemsPerPageの倍数である場合にのみ当てはまります。 。そうでない場合は、それを確認し、それに応じてページ数を処理する必要があります。
var pageRem = total%itemsPerPage;
if(pageRem !=0 ){
pageCount = Math.floor(pageCount)+1;
} これで正しいページ数が得られます。
これでページの総数がわかったので、ページネーションHTMLを動的に作成します。 LIを削除します 以前に追加したページネーションHTMLの要素。
<nav>
<ul class="pagination">
// li we'll create dynamically
</ul>
</nav>
GetWishesで 成功したコールバック、jQueryを使用して前のリンクを動的に作成しましょう。
var prevLink = $('<li/>').append($('<a/>').attr({
'href': '#'
}, {
'aria-label': 'Previous'
})
.append($('<span/>').attr('aria-hidden', 'true').html('«')));
$('.pagination').append(prevLink); 上記のコードでは、前のボタンリンクを作成し、それをページネーションULに追加しました。
上記の変更を保存して、サーバーを再起動します。サインインに成功すると、リストの下に前のリンクが表示されます。
同様に、ページ数に基づいてページネーションにページを追加しましょう。
for (var i = 0; i < pageCount; i++) {
var page = $('<li/>').append($('<a/>').attr('href', '#').text(i + 1));
$('.pagination').append(page);
} ページリンクを追加した後、次のリンクも追加しましょう。
var nextLink = $('<li/>').append($('<a/>').attr({
'href': '#'
}, {
'aria-label': 'Next'
})
.append($('<span/>').attr('aria-hidden', 'true').html('»')));
$('.pagination').append(nextLink); 変更を保存して、サーバーを再起動します。有効なメールアドレスとパスワードを使用してログインすると、ユーザーのホームページにアクセスすると、ページネーションが表示されます。
クリックイベントをページ番号に添付する
ここで、ページネーションを機能させるメインロジックが登場します。これから行うことは、各ページインデックスにクリックイベント呼び出しをアタッチして、GetWishesを呼び出すことです。 JavaScript関数。まず、ページ番号を表示するアンカー要素にクリックイベントを添付しましょう。
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);
}
そのため、onclickイベントをページアンカーにアタッチしました。クリックするたびに、GetWishesを呼び出します。 関数を実行し、offsetを渡します 。したがって、offsetを宣言します forループの外側。
var offset = 0;
GetWishesを呼び出します クリックイベント呼び出し内で機能します。
GetWishes(offset);
また、offsetをインクリメントします 表示されたレコードの数に基づきます。
offset = offset + 2;
しかし、毎回GetWishes 関数が呼び出され、offsetの値 常に最後のセットになります。そのため、JavaScriptクロージャを使用して、正しいオフセットをGetWishesに渡します。 機能。
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;
} 上記の変更をすべて保存して、サーバーを再起動します。有効な認証情報を使用してログインし、ユーザーのホームページが表示されたら、ページネーションULのページをクリックしてみてください。
次に、前のページと次のページのリンクを実装します。少し複雑に思えるかもしれませんので、実装を始める前に少し説明しましょう。
一度に5ページを表示します。次と前のリンクを使用して、ユーザーはそれぞれ次の5ページと前の5ページに移動できます。開始ページと終了ページの値を保存し、次と前のボタンクリックの両方で更新を続けます。それでは、2つの非表示フィールドをuserHome.htmlに追加することから始めましょう。 ページ。
<input type="hidden" id="hdnStart" value="1" /> <input type="hidden" id="hdnEnd" value="5"/>
GetWishesで .paginationを空にした後の成功コールバック ULの場合、次のコード行を追加して、最新の開始ページと終了ページを取得します。
$('.pagination').empty();
var pageStart = $('#hdnStart').val();
var pageEnd = $('#hdnEnd').val(); 1〜5ページを表示する場合、前のボタンのリンクは表示されません。表示されるページが5より大きい場合は、前のボタンのリンクが表示されます。
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);
}
ユーザーが前のボタンをクリックすると、hdnStartがリセットされます およびhdnEnd 値を入力し、GetWishesを呼び出します JavaScript関数。
$(aPrev).click(function() {
$('#hdnStart').val(Number(pageStart) - 5);
$('#hdnEnd').val(Number(pageStart) - 5 + 4);
GetWishes(Number(pageStart) - 5);
});
次に、開始ページと終了ページに基づいて、ループしてページリンクを作成し、.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);
} 合計ページ数とページ開始値を比較して、次のボタンリンクの表示を決定します。
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);
}
上記のコードに見られるように、次のボタンをクリックすると、hdnStartがリセットされます。 およびhdnEnd ボタンの値とGetWishesの呼び出し JavaScript関数。
これが最後のGetWishesです JavaScript関数。
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);
}
});
} 上記の変更をすべて保存して、サーバーを再起動します。有効なメールアドレスとパスワードを使用してサインインします。ユーザーの希望リストの完全に機能するページネーションを確認できるはずです。