【JQuery】DataTables に Ajax で動的に取得したデータを表示する

Javascript,Python,開発

おはようございます。

なんと、約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()

起動してみる

初期表示

初期表示はデータが表示されていない状態。

名前の指定をしないで検索ボタンをクリックします。

全件検索

全件が表示されます。

名前指定検索

「そ」を指定して検索をすると、「そら」のデータが表示されました。

期待通りの動きですね。

まとめ

調べると色々とサンプルが出てくるものの、微妙にやりたい事と違っていたり、動作がおかしくてハマったりしました。

ひとまずこの方法で進めていこうかな。

次回はデータの追加・更新・削除なんかをやる予定です。

ではでは。

 

スポンサーリンク


関連するコンテンツ

Javascript,Python,開発DataTables,JQuery

Posted by doradora