0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

python Bottleの基本10 編集機能付きテーブル

Posted at

このテーマは、編集機能付きテーブルをサクッと作るためのテンプレートです。

image.png

mindmup-editabletable.jsを利用して編集機能付きテーブルを実現しています。

ex10.py
from bottle import *
import json,os
save=None
# HTML デコレーション(Bootstrap4)
def Html(title):
    html='''
        <!DOCTYPE html>
            <html lang="ja">
            <head>
                <meta charset="utf-8" />
                <title>%s</title>
                <link rel="stylesheet" type="text/css" href="/static/content/bootstrap.min.css" />
	            <link href="static/content/jumbotron.css" rel="stylesheet" />
                <link rel="stylesheet" type="text/css" href="/static/content/site.css" />
                <script src="/static/scripts/modernizr-2.6.2.js"></script>
                <script src="/static/scripts/jquery-1.10.2.min.js"></script>
                <script src="/static/scripts/bootstrap.min.js"></script>
                <script src="/static/scripts/respond.min.js"></script>
	            <script src="/static/scripts/mindmup-editabletable.js"></script>
                <script src="/static/scripts/jquery.redirect.js"></script>
            </head>
            <body>
            %s          
            </body>
            </html>'''
    def f0(f):
        def f1(*a,**b):          
            return html%(title,f(*a,**b))
        return f1
    return f0
def Body():
    def f0(f):
        def f1(*a,**b):
            return '<div class="container body-content">%s</div>'%f(*a,**b)
        return f1
    return f0
def Navi(menu):
    nav='''<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
            <a class="navbar-brand" href="/">%s</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarsExampleDefault">
            <ul class="navbar-nav mr-auto">
                %s
            </ul>
            <form class="form-inline my-2 my-lg-0">
                <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
                <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
            </form>
            </div>
     </nav>%s'''
    def f0(f):
        def f1(*a,**b):
            nm=''.join(['<li class="nav-item"><a class="nav-link" href="/%s">%s</a></li>'%(x,x) for x in menu[1:]])
            return nav%(menu[0],nm,f(*a,**b))
        return f1
    return f0
def routes(menu):
    def f0(f):
        route('/','GET',f)
        [route("/%s"%x,'GET',f) for x in menu]
        def f1(*a,**b):
            return f(*a,**b)
        return f1
    return f0
# JOMBOTRON デコレーション
def Jumbotron(title,paragraph):
    jumbo='''<div class="jumbotron">
        <div class="container">
          <h1 class="display-3">%s</h1>
          <p>%s</p>
        </div>
      </div>%s'''
    def f0(f):
        def f1(*a,**b):
            return jumbo%(title,paragraph,f(*a,**b))
        return f1
    return f0
# script デコレーション
def script(js):
    def f0(f):
        def f1(*a,**b):
            return f(*a,**b)+js
        return f1
    return f0
# string csv data to dict
def csv2js(d):
    dx=[x.split(',') for x in d.splitlines()]
    return [{ a:b for a,b in zip(dx[0],x)}for x in dx[1:]]
# Table デコレーション
def table(dx):
    head='<tr>'+''.join(['<th scope="col" class="text-nowrap">%s</th>'%x for x in dx[0]])+'</tr>'
    body=''.join(['<tr>'+''.join(['<td scope="col" class="text-nowrap">%s</td>'%x[a] for a in x])+'</tr>' for x in dx])
    def f0(f):
        def f1(*a,**b):
            return '<table style="margin-top:1em" class="table table-sm table-bordered table-striped table-responsive-sm table-hover">%s%s</table>%s'%(head,body,f(*a,**b))
        return f1
    return f0
def table_(dx):
    head='<tr>'+''.join(['<th scope="col" class="text-nowrap">%s</th>'%x for x in dx[0]])+'</tr>'
    body=''.join(['<tr>'+''.join(['<td scope="col" class="text-nowrap">%s</td>'%x[a] for a in x])+'</tr>' for x in dx])
    return '<table style="margin-top:1em" class="table table-sm table-bordered table-striped table-responsive-sm table-hover">%s%s</table>'%(head,body)

adr='''ID,名前,性別,血液型,生年月日,電話番号,携帯番号,メール,郵便番号,住所
1,関 波子,女,AB,1980/7/31,03-3060-4716,090-7787-3784,sk@eaccess.net,135-0034,東京都江東区永代8-1-4
2,小倉 準司,男,A,1973/10/8,0166-36-3522,,junzi-kokura@eaccess.net,071-1544,北海道上川郡東神楽町14号6-13-1
3,西村 有紀子,女,O,1972/12/5,0745-67-2723,090-5165-2074,okikuy1972@livedoor.com,635-0805,奈良県北葛城郡広陵町萱野5-2-7 ヴェルテックス萱野 1009
4,谷 僧三郎,男,B,1989/1/17,077-323-7124,090-3781-1181,suzbrutn@dsn.ad.jp,520-0011,滋賀県大津市南志賀2868
5,山口 和久,男,A,1973/2/21,0183-21-6828,070-4790-1232,kazuhisa73@geocities.com,012-0813,秋田県湯沢市前森1-11-7
6,米田 一生,男,O,1984/7/25,043-883-8543,,issei07@dsn.ad.jp,264-0029,千葉県千葉市若葉区桜木北4-13-4
7,村松 希美江,女,O,1980/11/21,075-727-1789,090-4849-6939,kimie.muramatu@odn.ne.jp,616-8151,京都府京都市右京区太秦帷子ヶ辻町6-6-7
8,小野寺 眞八,男,O,1986/4/28,0748-01-7199,090-1457-0772,ondr.sny@gmo-media.jp,527-0135,滋賀県東近江市横溝町6-6-7
9,志村 陽一郎,男,O,1975/7/8,0136-88-6603,,smr-yutru@dion.ne.jp,048-1321,北海道磯谷郡蘭越町湯里5-9-5 ル・メール湯里
10,鎌田 敏美,女,B,1993/6/9,0554-03-0156,090-5690-8749,kamata0609@example.com,409-0115,山梨県上野原市松留4631'''
js='''
<script>
             function getData(){
		        var d=[];$('table tr').each(function(i, e){
		         var dd=[]; if (i===0) $(this).find('th').each(function(j, el){dd.push($(this).text())}); 
					         else $(this).find('td').each(function(j, el){dd.push($(this).text())});
		         d.push(dd);
		        });return d;
            }
            $(function () {
             $('table').editableTableWidget();
	         $('#upload').click(function(){
	            var s=getData();
			        var k=s[0],d=[];for(var i=1;i<s.length;i++){
				        var x=s[i],dd={}; for(var j=0;j<x.length;j++) dd[k[j]]=x[j];
				        d.push(dd);
			        }
               $.redirect('/upload',{js:JSON.stringify(d)});
  	         });
            });
           </script>
'''
save=csv2js(adr)
menu='Home,Table'.split(',')

@routes(menu)
@Html('Hello')
@Navi(menu)
@Jumbotron('Table テンプレート','これさえあればサクッと作ることができます')
@Body()
@script(js)
def Home():
    global save
    p=request.urlparts[2]
    if p=='/Table' or p=='/' :
        return table_(save)+"<button class='btn btn-primary' id='upload'>保存</button>"
    return "<h1>%s</h1><h1>Hello World</h1>"%(p)

@route('/upload',method="POST")
@Html('Hello')
@Jumbotron('Form表示テンプレート','これさえあればサクッと作ることができます')
@Navi(menu)
@Body()
def upload():
    global save
    save=eval(request.params.decode().js)
    return table_(save)+"<button class='btn btn-primary' id='upload'>保存</button>"
# faviconの読み込み    
@route('/favicon.ico')
def favcon():
    return static_file('favicon.ico', root='./static')
# staic ファイルの読み込み
@route('/static/<filepath:path>')
def server_static(filepath):
    return static_file(filepath, root='./static')
# web server のhost portの設定
HOST,PORT='localhost',8080
if __name__ =='__main__':
    run(host=HOST,port=PORT)

table関数は、デコレーション用です。table_は、html生成用です。

scriptデコレーションを作り,jsを定義しています。

snippet.js
<script>
    function getData(){
	 var d=[];$('table tr').each(function(i, e){
		var dd=[]; if (i===0) $(this).find('th').each(function(j, el){dd.push($(this).text())}); 
					else $(this).find('td').each(function(j, el){dd.push($(this).text())});
		d.push(dd);
	 });return d;
    }
    $(function () {
        $('table').editableTableWidget();
	    $('#upload').click(function(){
	    var s=getData();
		var k=s[0],d=[];for(var i=1;i<s.length;i++){
			var x=s[i],dd={}; for(var j=0;j<x.length;j++) dd[k[j]]=x[j];
			d.push(dd);
		}
        $.redirect('/upload',{js:JSON.stringify(d)});
  	    });
    });
</script>
function getData()は、テーブルからデータを剥ぎ取る関数です。
$.redirect('/upload',{js:JSON.stringify(d)});によって/uploadにデータをPOSTしています。この関数は、通常は、$.postとして使いますが画面を新しく遷移するときに使います。

下記のjqueryを導入することにより利用可能です。

<script src="/static/scripts/jquery.redirect.js"></script>

jquery.redirectは、ここにあります。
image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?