【JQuery】DataTables に Ajax で動的に取得したデータを表示する
おはようございます。
なんと、約4ヶ月ぶりのプログラム記事です。
いつの間にそんなに時間が経ってしまったのか。。
ということで、
久しぶりのプログラムは以前少し触ってほったらかしにしていた、JQueryプラグイン「DataTables」の話し。
今回は条件を指定して検索などを実施して得たデータを動的に DataTables に設定する方法を試してみました。
以前までのプログラムは次の記事を参照してください。
【JQuery】PythonサーバーでMySQLに接続して DataTable にデータを表示する
スポンサーリンク
画面の修正
大きく変更はありませんが、検索するためのテキストボックス及びボタンの配置、Javascriptの外出しをしました。(あとファイル名の変更)
templates/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>DataTableサンプル</title>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<style>
.container {
border: 1px solid black;
padding: 1rem;
margin: 1rem;
}
</style>
</head>
<body>
<div class="container container-fluid">
<div>
名前:
<input type="text" id="searchName" value="">
<input type="button" id="searchButton" value="検索">
</div>
<div>
<table id="myTable" class="table table-striped tagle-bordered">
<thead>
<tr>
<th>No</th>
<th>名前</th>
<th>性別</th>
<th>年齢</th>
<th>種別</th>
<th>好物</th>
</tr>
</thead>
<tfoot>
<tr>
<th>No</th>
<th>名前</th>
<th>性別</th>
<th>年齢</th>
<th>種別</th>
<th>好物</th>
</tr>
</tfoot>
</table>
</div>
</div>
</body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript" src="{{ static_url('js/script.js') }}"></script>
</html>プログラムの修正
クライアント
static/js/script.js
ポイント
1.「ajax」オプションでページ読み込み時にサーバーサイドの「/init」メソッド呼び出し
2.「ajax」オプションの「data」に、サーバーへ送信するパラメータの設定をしておく
3.なぜか「serverSide」を「true」にすると、件数が正しく表示されかったりページングやソートが動かなかったり(それらもサーバーサイドでやれということなのかな?)
4.検索ボタン押下時に、urlの設定及び、ajaxのリロードを行うことでデータが再設定できる
といったところですかね。
$(document).ready( function () {
$('#myTable').DataTable({
'paging' : true,
'pageLength' : 5,
'lengthChange': false,
'searching' : true,
'ordering' : true,
'info' : true,
'autoWidth' : true,
"scrollCollapse": true,
'scrollX' : true,
'scrollY' : '185px',
'tabIndex' : -1,
'order' : [[ 0, 'asc' ]],
'colReorder' : true,
'serverSide' : false,
'ajax' : {
'url' : '/init',
'type' : 'POST',
'data' : function ( d ) {
d.searchName = $("#searchName").val();
}
},
'columns' : [
{ 'data' : 'no', width: 40 },
{ 'data' : 'name', width: 60 },
{ 'data' : 'sex', width: 40 },
{ 'data' : 'age', width: 40 },
{ 'data' : 'kind_name', width: 100 },
{ 'data' : 'favorite', width: 120 },
],
'language' : {
'decimal': ".",
'emptyTable': "表示するデータがありません。",
'info': "_START_ ~ _END_ / _TOTAL_ 件中",
'infoEmpty': "0 ~ 0 / 0 件",
'infoFiltered': "(合計 _MAX_ 件からフィルタリングしています)",
'infoPostFix': "",
'thousands': ",",
'lengthMenu': "1ページ _MENU_ 件を表示する",
'loadingRecords': "読み込み中...",
'processing': "処理中...",
'search': "絞り込み:",
'zeroRecords': "一致するデータが見つかりません。",
'paginate': {
'first': "最初",
'last': "最後",
'next': "次",
'previous': "前"
}
}
});
$("#searchButton").on("click", function() {
$('#myTable').DataTable().ajax.url("/search").load();
$('#myTable').DataTable().ajax.reload();
})
} );
サーバー
Main.py
主な変更点
1.InitHandlerメソッドを追加し、空のリストを返却(初期表示用)
2.SearchHandlerメソッドで、クライアントから送られたパラメータを利用して検索するように
import json
import logging
import os
import tornado.ioloop
import mysql.connector
from tornado.web import RequestHandler
from tornado.options import options
from contextlib import closing
class MainHandler(RequestHandler):
"""
画面表示
"""
def get(self):
logging.info("MainHandler [get]")
self.render("index.html")
class InitHandler(RequestHandler):
def post(self):
list = []
result = {
'data': list
}
self.write(json.dumps(result, ensure_ascii=False))
class SearchHandler(RequestHandler):
"""
データ検索
"""
def post(self):
"""
データをJSON形式で返します
:return:
"""
logging.info("SearchHandler [post]")
searchName = self.get_argument("searchName")
with closing(mysql.connector.connect(
host="localhost",
port="3306",
user="USER01",
password="USER01",
database="DB01"
)) as conn:
c = conn.cursor(dictionary=True)
# SQL組み立て
sql = "SELECT C.NO, C.NAME, C.SEX, C.AGE, C.KIND_CD, K.KIND_NAME, C.FAVORITE FROM TBLCAT C"
sql += " LEFT OUTER JOIN MSTKIND K ON ( C.KIND_CD = K.KIND_CD)"
sql += " WHERE C.NAME LIKE '" + searchName + "%'"
list = []
c.execute(sql)
for r in c.fetchall():
list.append({
"no": r['NO'],
"name": r['NAME'],
"sex": r['SEX'],
"age": r['AGE'],
"kind_name": r['KIND_NAME'],
"favorite": r['FAVORITE'],
})
result = {
'data': list
}
self.write(json.dumps(result, ensure_ascii=False))
app = tornado.web.Application([
(r"/", MainHandler),
(r"/init", InitHandler),
(r"/search", SearchHandler),
],
template_path=os.path.join(os.getcwd(), "templates"),
static_path=os.path.join(os.getcwd(), "static"),
)
if __name__ == "__main__":
options.parse_command_line()
app.listen(8080)
logging.info("server started")
tornado.ioloop.IOLoop.instance().start()
起動してみる
初期表示はデータが表示されていない状態。
名前の指定をしないで検索ボタンをクリックします。
全件が表示されます。
「そ」を指定して検索をすると、「そら」のデータが表示されました。
期待通りの動きですね。
まとめ
調べると色々とサンプルが出てくるものの、微妙にやりたい事と違っていたり、動作がおかしくてハマったりしました。
ひとまずこの方法で進めていこうかな。
次回はデータの追加・更新・削除なんかをやる予定です。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません