このテーマは、編集機能付きテーブルをサクッと作るためのテンプレートです。
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は、ここにあります。