.. meta:: :keywords: web2py, framework, sqleditable SQLEDITABLE デモ ================ .. contents:: 目次 :local: インフォメーション ------------------ - リポジトリ : ``_ - バグ報告 : ``_ - ドキュメント : :doc:`../docs/document` - 動作チェック : Chrome35, Firefox30, InternetExplorer11(document-mode edge,10,9,8,7), Silk - ライセンス : LGPLv3 SQLEDITABLE 基本的な使い方 -------------------------- 最初に、SQLEDITABLEのプラグインファイルをリンクからダウンロードし、アプリケーションにセットします。 ``_ - web2py.plugin.sqleditable.w2p - プラグインファイル - web2py.app.demo.w2p - デモアプリ モデル(db.pyなど)もしくはコントローラ(default.pyなど)に、次の記述を追加します。 :: from plugin_sqleditable.editable import SQLEDITABLE SQLEDITABLE.init() 後は、**SQLFORM** と同様に記述するだけです。 .. _demo1: デモ1 ^^^^^^ `Demo010 `_ - リンクをクリックしてください モデル定義 :: db.define_table('employee_sheet', Field('employee_number','integer',length=5,label='Emp.no.'), Field('name','string',length=50,notnull=True), Field('date_employment','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'})), Field('employee_comment','string',label='Comment'), Field('date_resignation','date',label='Exit',readable=False, requires=IS_EMPTY_OR(IS_DATE())), Field('resigned','boolean', writable=False, default=False), Field('remuneration','decimal(12,2)', readable=False), Field('currency','string',readable=False, requires=IS_IN_SET(['USD','EUR','GBP','JPY']))) コントローラ :: def demo010(): response.title = 'demo010' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, showid=False, maxrow=5).process() return dict(editable=editable) 現在のところ、対応しているフィールドタイプは、**interger** , **double** , **float** , **decimal**, **string** , **boolean** , **date** , **datetime** , **time** です。 また、**IS_IN_SET** バリデータが記述されていると、リストボックスが表示されます。 **IS_IN_DB** にも対応しました(:ref:`demo13`)。 .. figure:: ../../images/sqleditable/sqleditable_001.PNG :width: 80% :class: img-border デモ2 - 縦向き ^^^^^^^^^^^^^^ `Demo011 `_ - リンクをクリックしてください コントローラ :: def demo011(): response.title = 'demo011' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, showid=False, maxrow=5, vertical=False).process() return dict(editable=editable) ``vertical=False`` で横向きに表示されます。 .. figure:: ../../images/sqleditable/sqleditable_002.PNG :width: 80% :class: img-border デモ3 - バリデート ^^^^^^^^^^^^^^^^^^ `Demo012 `_ - リンクをクリックしてください コントローラ :: def demo012(): response.title = 'demo012' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, showid=False, maxrow=5, validate_js=False).process() return dict(editable=editable) ``validate_js=False`` によって、Javascriptバリデータを無効にしています。 .. figure:: ../../images/sqleditable/sqleditable_003.PNG :width: 80% :class: img-border デモ4 - 削除 ^^^^^^^^^^^^ `Demo020 `_ - リンクをクリックしてください コントローラ :: def demo020(): db.employee_sheet.date_resignation.readable = True db.employee_sheet.resigned.writable = True db.employee_sheet.remuneration.readable = True db.employee_sheet.currency.readable = True response.title = 'demo020' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, maxrow=5, deletable=True).process() return dict(editable=editable) ``SQLEDITABLE`` の前にテーブル属性を変更しています。 また、``deletable=True`` によって削除チェックボックスを表示しています。 .. figure:: ../../images/sqleditable/sqleditable_004.PNG :width: 80% :class: img-border デモ5 - レコード指定 ^^^^^^^^^^^^^^^^^^^^ `Demo030 `_ - リンクをクリックしてください コントローラ :: def demo030(): def record(): rows = db(db.employee_sheet).select( orderby=~db.employee_sheet.employee_number, limitby=(0,3)) return [row.id for row in rows.sort(lambda row:row.employee_number)] response.title = 'demo030' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, record=record,showid=False, maxrow=5).process() return dict(editable=editable) ``record`` によって、レコードidを指定しています。 通常はリストで指定しますが、callableのため、DAL構文を記述してもOKです。 3行分を登録したデータで、2行分を新規データ用に表示します。 .. figure:: ../../images/sqleditable/sqleditable_005.PNG :width: 80% :class: img-border デモ6 - as_dict ^^^^^^^^^^^^^^^^ `Demo040 `_ - リンクをクリックしてください コントローラ :: def demo040(): response.title = 'demo040' response.view = 'plugin_sqleditable/sample_as_dict.html' editable = SQLEDITABLE(db.employee_sheet, showid=False, maxrow=5).process() return editable.as_dict() ``as_dict()`` によって、シートとボタン、スクリプトを辞書でビューに渡します。 サンプルビューでは、``editable`` , ``button`` , ``script`` の各値の処理をしています。 {{=button}} はビュー上に何個設置しても動作します。(changed:2015-02) ::
 {{=button}}  
 {{=editable}} 
 {{=button}}  
{{block head}} {{super}} {{=script}} {{end}} .. figure:: ../../images/sqleditable/sqleditable_006.PNG :width: 80% :class: img-border デモ7 - 画面遷移 ^^^^^^^^^^^^^^^^ `Demo050 `_ - リンクをクリックしてください コントローラ :: def demo050(): response.title = 'demo050' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.employee_sheet, showid=False, maxrow=5, deletable=True).process(next=URL('static', 'success.html')) return dict(editable=editable) :strike:`next_js=URL('static', 'success.html')` ``next=URL('static', 'success.html')`` によって、成功時別画面に遷移します。(changed:2014-07-02) .. figure:: ../../images/sqleditable/sqleditable_007.PNG :width: 30% :class: img-border デモ8 ^^^^^^ | `Demo060 `_ - リンクをクリックしてください | `Demo061 `_ - リンクをクリックしてください モデル定義 :: db.define_table('scadule_sheet', Field('scadule_date','date',label='date'), Field('scadule_time','time',label='time'), Field('term','integer'), Field('term_unit','string', requires=IS_IN_SET({'min':'minute','hr':'hour','d':'day','wk':'week', 'mo':'month'})), Field('detail','string',length=30,requires=IS_NOT_EMPTY())) コントローラ :: def demo060(): response.title = 'demo060' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True).process() return dict(editable=editable) def demo061(): response.title = 'demo061' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True, vertical=False).process() return dict(editable=editable) 別のテーブルを表示しています。 .. figure:: ../../images/sqleditable/sqleditable_008.PNG :width: 80% :class: img-border .. figure:: ../../images/sqleditable/sqleditable_009.PNG :width: 80% :class: img-border デモ9 - タッチデバイス ^^^^^^^^^^^^^^^^^^^^^^ | `Demo070 `_ - リンクをクリックしてください | `Demo071 `_ - リンクをクリックしてください | `Demo072 `_ - リンクをクリックしてください | `Demo073 `_ - リンクをクリックしてください コントローラ :: def demo070(): response.title = 'demo070' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True, touch_device=True).process() return dict(editable=editable) def demo071(): response.title = 'demo071' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True, touch_device=False).process() return dict(editable=editable) def demo072(): response.title = 'demo072' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True, touch_device='Auto').process() return dict(editable=editable) def demo073(): response.title = 'demo073' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.scadule_sheet, showid=False, maxrow=8, deletable=True).process() return dict(editable=editable) **date** , **time** , **datetime** フィールド入力で、タッチデバイス用に入力方法を変更します。 **touch_device** パラメータが **Auto** もしくは指定しない場合は、``request.user_agent()`` をチェックし、タッチデバイスと判定したアクセスでは、 web2pyのウィジェットではなく、HTML5対応のブラウザウィジェットを使用します。 .. figure:: ../../images/sqleditable/sqleditable_011.PNG :width: 80% :class: img-border .. figure:: ../../images/sqleditable/sqleditable_010.PNG :width: 80% :class: img-border デモ10 - 仮想フィールド ^^^^^^^^^^^^^^^^^^^^^^^ `Demo090 `_ - リンクをクリックしてください モデル定義 :: db.define_table('employee_sheet', Field('employee_number','integer',length=5,label='Emp.no.'), Field('name','string',length=50,notnull=True), Field('date_employment','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'})), Field('employee_comment','string',label='Comment'), Field('date_resignation','date',label='Exit',readable=False, requires=IS_EMPTY_OR(IS_DATE())), Field('resigned','boolean', writable=False, default=False), Field('remuneration','decimal(12,2)', readable=False), Field('currency','string',readable=False, requires=IS_IN_SET(['USD','EUR','GBP','JPY']))) class san(object): def san(self): return self.employee_sheet.name + '-san' db.employee_sheet.virtualfields.append(san()) db.employee_sheet.san2 = Field.Virtual(lambda row: row.employee_sheet.name + '-SAN') コントローラ :: def demo090(): response.title = 'demo090' response.view = 'plugin_sqleditable/sample.html' header = ['employee_number','name','san','san2'] editable = SQLEDITABLE(db.employee_sheet, header=header, showid=False, maxrow=5, deletable=True).process() return dict(editable=editable) 仮想フィールドを表示します。 ``header`` パラメータで表示フィールドを指定します。 .. figure:: ../../images/sqleditable/sqleditable_012.PNG :width: 80% :class: img-border 仮想フィールドでラベルを表示する場合、 ``field`` と ``label`` を使用ください。 :: def demo090(): response.title = 'demo090' response.view = 'plugin_sqleditable/sample.html' header = ['employee_number','name',{'field':'san2','label':'xxxx'}] editable = SQLEDITABLE(db.employee_sheet, header=header, showid=False, maxrow=5, deletable=True).process() return dict(editable=editable) 辞書型で ``field`` に仮想フィールドを、 ``label`` にはラベルを指定します。 なお、旧タイプの仮想フィールドでは動作しません(サンプルコードの *san* は旧タイプ仮想フィールド)。 デモ11 - アンカーリンク ^^^^^^^^^^^^^^^^^^^^^^^ `Demo091 `_ - リンクをクリックしてください モデル定義 :: db.define_table('employee_sheet', Field('employee_number','integer',length=5,label='Emp.no.'), Field('name','string',length=50,notnull=True), Field('date_employment','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'})), Field('employee_comment','string',label='Comment'), Field('date_resignation','date',label='Exit',readable=False, requires=IS_EMPTY_OR(IS_DATE())), Field('resigned','boolean', writable=False, default=False), Field('remuneration','decimal(12,2)', readable=False), Field('currency','string',readable=False, requires=IS_IN_SET(['USD','EUR','GBP','JPY']))) db.employee_sheet.history = Field.Virtual(lambda row: A('History', _href=URL(f='demo092', args=row.employee_sheet.id))) db.define_table('history_in_house', Field('employee',db.employee_sheet), Field('date_history','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'}))) コントローラ :: def demo091(): response.title = 'demo091' response.view = 'plugin_sqleditable/sample.html' header = ['employee_number','name','history'] editable = SQLEDITABLE(db.employee_sheet, header=header, showid=False, maxrow=5, deletable=True).process() return dict(editable=editable) def demo092(): def record(): session.employee = request.args(0) rows = db(db.history_in_house.employee==request.args(0)).select( orderby=~db.history_in_house.date_history, limitby=(0,4)) return [row.id for row in rows.sort(lambda row:row.date_history)] def onvalidation(form): form.vars.employee = session.employee db.history_in_house.employee.readable = False response.title = 'demo092' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.history_in_house, record=record, showid=False, maxrow=5, deletable=True).process(onvalidation=onvalidation) return dict(editable=editable) アンカーリンクを仮想フィールドを使って表示します。 ``header`` パラメータで表示フィールドを指定します。 リンク先のテーブルでは、関連するレコードのみを表示します。このため、 processメソッドで ``onvalidation`` パラメータを指定しています。 onvalidation 関数内で、 employee フィールドの値としてURLパラメータ値を指定しています(record関数内で、一旦セッションに値を渡しています)。 .. figure:: ../../images/sqleditable/sqleditable_013.PNG :width: 80% :class: img-border .. figure:: ../../images/sqleditable/sqleditable_014.PNG :width: 80% :class: img-border なお、仮想フィールドの記述を次のように変更すれば、ボタン部品で配置することも可能です。 :: db.employee_sheet.history = Field.Virtual(lambda row: BUTTON('Hisotry', _onClick="location.href='%s'" % URL(f='demo092', args=row.employee_sheet.id))) onvalidation パラメータを使用せず、 次のように demo092 コントローラを記述することも可能です。フィールドのデフォルト値を設定しています(9行目)。 :: def demo092(): def record(): session.employee = request.args(0) rows = db(db.history_in_house.employee==request.args(0)).select( orderby=~db.history_in_house.date_history, limitby=(0,4)) return [row.id for row in rows.sort(lambda row:row.date_history)] db.history_in_house.employee.readable = False db.history_in_house.employee.default = session.employee response.title = 'demo092' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.history_in_house, record=record, showid=False, maxrow=5, deletable=True).process() return dict(editable=editable) デモ12 - onvalidation ^^^^^^^^^^^^^^^^^^^^^^ `Demo100 `_ - リンクをクリックしてください モデル定義 :: db.define_table('employee_sheet', Field('employee_number','integer',length=5,label='Emp.no.'), Field('name','string',length=50,notnull=True), Field('date_employment','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'})), Field('employee_comment','string',label='Comment'), Field('date_resignation','date',label='Exit',readable=False, requires=IS_EMPTY_OR(IS_DATE())), Field('resigned','boolean', writable=False, default=False), Field('remuneration','decimal(12,2)', readable=False), Field('currency','string',readable=False, requires=IS_IN_SET(['USD','EUR','GBP','JPY']))) コントローラ :: def demo100(): def onvalidation(form): if len(form.vars.name) < 5: form.errors.name = 'Enter 5 characters or more' else: form.vars.name = form.vars.name.title() response.title = 'demo100' response.view = 'plugin_sqleditable/sample.html' header = ['employee_number','name'] editable = SQLEDITABLE(db.employee_sheet, header=header, showid=False, maxrow=5, deletable=True, update_display_record=True).process(onvalidation=onvalidation) return dict(editable=editable) onvalidation パラメータのデモです。processメソッドで ``onvalidation`` パラメータを指定しています。 web2py の **Form** と同様に、**form.vars.xxx** や **form.errors.xxx** 変数を使用できます。 onvalidation関数内でフィールド値を変更した場合、通常はテーブルの表示は変更されません。このため、SQLEDITABLEのパラメータの ``update_display_record`` を **True** にすると、 変更された値にテーブルの表示が更新されます。 .. figure:: ../../images/sqleditable/sqleditable_015.PNG :width: 80% :class: img-border .. _demo13: デモ13 - IS_IN_DB ^^^^^^^^^^^^^^^^^^ `Demo093 `_ - リンクをクリックしてください モデル定義 :: db.define_table('employee_sheet', Field('employee_number','integer',length=5,label='Emp.no.'), Field('name','string',length=50,notnull=True), Field('date_employment','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'})), Field('employee_comment','string',label='Comment'), Field('date_resignation','date',label='Exit',readable=False, requires=IS_EMPTY_OR(IS_DATE())), Field('resigned','boolean', writable=False, default=False), Field('remuneration','decimal(12,2)', readable=False), Field('currency','string',readable=False, requires=IS_IN_SET(['USD','EUR','GBP','JPY'])), format='%(name)s') db.define_table('history_in_house', Field('employee',db.employee_sheet), Field('date_history','date',label='Enter',requires=IS_DATE()), Field('employee_section','string',label='Section', requires=IS_IN_SET({'s':'sales','p':'production','d':'development', 'c':'control'}))) コントローラ :: def demo093(): response.title = 'demo093' response.view = 'plugin_sqleditable/sample.html' editable = SQLEDITABLE(db.history_in_house, showid=False, maxrow=5, deletable=True).process() return dict(editable=editable) **IS_IN_DB** バリデータをサポートするようになりました。 セレクトボックスから、他のテーブルのデータを表示します。フィールドに IS_IN_DB バリデータをセットするか、 web2pyによる暗黙設定によってリンク先データをセレクトボックスに表示可能です(暗黙設定では、リンク先のテーブルに **format** 設定が必要です)。 .. figure:: ../../images/sqleditable/sqleditable_016.PNG :width: 80% :class: img-border デモ14 - 自己参照型フィールド ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | `Demo110 `_ - リンクをクリックしてください | `Demo111 `_ - リンクをクリックしてください モデル定義 :: db.define_table('node', Field('parent_id','reference node'), Field('name'), Field('node_comment')) コントローラ :: def demo110(): def record(): session.parent_id = request.args(0) if request.args(0) else None rows = db(db.node.parent_id==request.args(0)).select() rec = [row.id for row in rows] return rec def parent(): parent = [] if session.parent_id: row = db.node(session.parent_id) if row: parent.insert(0, LI(row.name, _class='active')) while row: if row.parent_id: row = db.node(row.parent_id) if row: parent.insert(0, LI(A(row.name, _href=URL(f='demo110', args=row.id)))) else: break parent.insert(0, LI(A('Top', _href=URL(f='demo110')))) return OL(parent, _class='breadcrumb') db.node.children = Field.Virtual(lambda row: A(I(_class='glyphicon glyphicon-arrow-right'), ' Children', _class='btn btn-default btn-sm', _href=URL(f='demo110', args=row.node.id))) response.title = 'demo110' db.node.parent_id.default = session.parent_id header = ['name', 'node_comment', 'children'] editable = SQLEDITABLE(db.node, record=record, maxrow=10, showid=False, deletable=True, header=header).process() return dict(editable=editable, parent=parent()) ビュー ::
{{=parent}}
{{=editable}}
自己参照型フィールドを使ったアプリの例です。 ``parent`` 辞書変数を追加しています。 ``as_dict()`` メソッドを利用する場合は、直接 ``editable`` に変数を追加するのではなく、as_dict()のパラメータとして渡す必要があります。 コントローラ :: def demo111(): def record(): session.parent_id = request.args(0) if request.args(0) else None rows = db(db.node.parent_id==request.args(0)).select() rec = [row.id for row in rows] return rec def parent(): parent = [] if session.parent_id: row = db.node(session.parent_id) if row: parent.insert(0, LI(row.name, _class='active')) while row: if row.parent_id: row = db.node(row.parent_id) if row: parent.insert(0, LI(A(row.name, _href=URL(f='demo111', args=row.id)))) else: break parent.insert(0, LI(A('Top', _href=URL(f='demo111')))) return OL(parent, _class='breadcrumb') db.node.children = Field.Virtual(lambda row: A(I(_class='glyphicon glyphicon-arrow-right'), ' Children', _class='btn btn-default btn-sm', _href=URL(f='demo111', args=row.node.id))) response.title = 'demo111' db.node.parent_id.default = session.parent_id header = ['name', 'node_comment', 'children'] editable = SQLEDITABLE(db.node, record=record, maxrow=10, showid=False, deletable=True, header=header).process() return editable.as_dict(parent=parent()) ビュー ::
{{=parent}}
{{=button}} {{=editable}} {{=button}}
{{block head}} {{super}} {{=script}} {{end}} .. figure:: ../../images/sqleditable/sqleditable_017.PNG :width: 80% :class: img-border .. figure:: ../../images/sqleditable/sqleditable_018.PNG :width: 80% :class: img-border デモ15 - Field.Method ^^^^^^^^^^^^^^^^^^^^^^ `Demo120 `_ - リンクをクリックしてください コントローラ :: def demo120(): def record(): session.parent_id = request.args(0) if request.args(0) else None rows = db(db.node.parent_id==request.args(0)).select() rec = [row.id for row in rows] if request.args(0): rec.insert(0, request.args(0)) return rec def parent(): parent = [] if session.parent_id: row = db.node(session.parent_id) if row: parent.insert(0, LI(row.name, _class='active')) while row: if row.parent_id: row = db.node(row.parent_id) if row: parent.insert(0, LI(A(row.name, _href=URL(f='demo120', args=row.id)))) else: break parent.insert(0, LI(A('Top', _href=URL(f='demo120')))) return OL(parent, _class='breadcrumb') def onvalidation(form): if form.delete and form.vars.id == session.parent_id: form.errors.delete = 'This record is a parent and you can not be removed.' def argument(): return int(session.parent_id) if session.parent_id else None db.node.children = Field.Method(lambda row, parent_id: A(I(_class='glyphicon glyphicon-arrow-right'), ' Children', _class='btn btn-default btn-sm', _href=URL(f='demo120', args=row.node.id)) \ if row.node.id!=parent_id else SPAN(I(_class='glyphicon glyphicon-home'), ' Parent')) response.title = 'demo120' db.node.parent_id.default = session.parent_id header = ['name', 'node_comment', {'field':'children','argument':argument}] editable = SQLEDITABLE(db.node, record=record, maxrow=10, showid=False, deletable=True, header=header).process(onvalidation=onvalidation) return dict(editable=editable, parent=parent()) **Field.Method** を使用したデモです。Field.Method フィールドの情報は ``header`` パラメータに、 :: {'field':'children','argument':argument} のように指定します。辞書型の ``field`` キーの値にフィールド名を、 ``argument`` キーの値にパラメータを指定します。 Field.Method のパラメータは遅延評価のために、呼び出し可能オブジェクト(callable)である必要があります。 .. figure:: ../../images/sqleditable/sqleditable_019.PNG :width: 80% :class: img-border デモ16 - ページネーション ^^^^^^^^^^^^^^^^^^^^^^^^^ `Demo140 `_ - リンクをクリックしてください コントローラ :: def demo140(): # page limit = 5 dbset = db(db.employee_sheet) rows_count = dbset.count() total_page = rows_count // limit + 1 if rows_count % limit < limit else rows_count // limit page = int(request.vars.page) if request.vars.page and int(request.vars.page) <= total_page else 0 vars = request.get_vars vars['page'] = page-1 previous = LI(A('prev', _href=URL(vars=vars, user_signature=True))) if page else '' vars['page'] = page+1 if request.post_vars.keywords: vars['keywords'] = request.post_vars.keywords next = LI(A('next', _href=URL(vars=vars, user_signature=True))) if page*limit+limit <= rows_count else '' page_no = LI('{0}/{1}'.format(page+1, total_page), _style='margin-right:10px;') pagination = TAG.nav(UL(CAT(page_no, previous, next)), _class='pager') response.title = 'demo140' rows = dbset.select(orderby=db.employee_sheet.employee_number, limitby=(page*limit, page*limit+limit)) editable = SQLEDITABLE(db.employee_sheet, rows, showid=False, maxrow=limit, deletable=True).process() return dict(editable=editable, pagination=pagination) ビュー ::
{{=editable}}
{{=pagination}}
大きな表の更新に時間が掛かったり、エラーが発生する場合があります。 この場合は、表を分割表示するテクニックが必要になります。デモ16では、表をページ分割しています。 .. figure:: ../../images/sqleditable/sqleditable_020.JPG :width: 80% :class: img-border