Dasar-dasar View

6. Dasar-dasar View

Penulis: Noprianto

Pada bab-bab sebelumnya, kita telah melihat view yang didefinisikan dalam file-file XML. Di bab ini, kita akan membahas lebih lanjut tentang dasar-dasar view pada OpenERP. Termasuk bagaimana menambahkan menu/menu item.

OpenERP mendukung beberapa macam tipe view. Namun, kita hanya akan membahas tentang form dan tree. Form digunakan untuk menampilkan suatu record secara detil. Sementara, tree digunakan untuk menampilkan beberapa record sekaligus (list). Keduanya dapat pula digunakan untuk menambahkan/mengedit data, walau pada tree, ini akan lebih terbatas.

Pembahasan akan dilakukan langsung pada contoh modul. Catatan: definisi view umumnya ditempatkan dalam sub direktori view dalam modul.

6.1 Kerangka

Berikut ini adalah kerangka definisi view dalam sebuah file XML: <?xml version="1.0"?>

<openerp> <data> <definisi view> …. …. …. <definisi view>

</data> </openerp>

Di dalam bab ini, kita akan menggunakan tag-tag berikut: • <record> dengan atribut model=”ir.ui.view”, untuk mendefinisikan view itu sendiri. • <record> dengan atribut model=”ir.actions.act_window”, untuk link action ke view. • <menuitem>, untuk membuat entri pada menu dan link ke action.

Contoh 1:

<record model="ir.ui.view" id="view_partner_form">

</record>

Contoh 2:

<record model="ir.ui.view" id="view_catatan_tree">

</record>

Contoh 3:

<record model="ir.actions.act_window" id="action_buku_catatan_tree">

</record>

Contoh 4:

<menuitem name="Buku" id="menu_buku"/>

Di dalam setiap <record>, kita umumnya bekerja dengan tag <field> dengan berbagai atribut, <form> dengan berbagai elemen di dalamnya, <tree> ataupun lainnya.

Berikut adalah contoh tag <field>:

<field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml">

</field>

Mari kita lihat lebih lanjut dalam contoh pembahasan modul.

6.2 Field pada model

Untuk merujuk pada suatu field pada model, kita menggunakan tag <field> dengan atribut name=”nama_field”, sebagai contoh:

<field name="fax"/> Lebih lanjut, terdapat sejumlah atribut tambahan yang bisa diberikan pada tag ini, yang mana akan

memiliki arti/efek. Contoh 1: <field name="fax" position="replace"/>

Contoh 2: <field name="mobile" position="before">

<field name="fax"/> </field>

Contoh 3: <field name="buku_field_17" password="True" nolabel="1" colspan="2"/>

Contoh 4: <field name="buku_field_18" attrs="{'required': ['&', ('is_company', '=',

False), ('street', '=', False)]}"/>

6.3 Inheritance pada view

Ketika kita menurunkan dari suatu model, misal untuk menambah field, kita umumnya fokus pada apa yang kita tambahkan tersebut. Walau, tentu saja, kita selalu bisa merujuk pada field-field yang ada sebelumnya.

Begitupun juga dengan view. View dapat diturunkan, dan kita bisa fokus pada perubahan spesifik yang ingin kita lakukan.

Perubahan spesifik yang dimaksud tidak harus selalu mendefinisikan bagaimana field yang kita tambahkan, dapat ditampilkan. Kita tidak harus selalu menambahkan field dan mendefinisikan pada view. Ketika menurunkan dari suatu view, kita bisa mengubah apa yang telah didefinisikan sebelumnya.

Dengan demikian, sama seperti pada model, ketika kita ingin mengubah suatu view yang ada, kita tidak edit langsung. Tapi, kita turunkan dan lakukan perubahan pada apa yang kita kerjakan.

Untuk menurunkan, kita perlu mengetahui id sebuah view. Salah satu cara nyaman untuk mengetahui id suatu view aktif adalah dengan mengaktifkan developer mode dan memilih Manage Views pada pilihan yang ada.

Untuk mencoba, bukalah informasi detil untuk partner tertentu (form). Kemudian, pilihlah Manage Views. Dari popup yang tampil, kita bisa melihat berbagai informasi yang ada, termasuk External ID.

Id tersebut dapat kita gunakan pada tag <field> dengan atribut name=”inherit_id”, seperti pada contoh berikut:

<field name="inherit_id" ref="base.view_partner_form"/>

Catatan: pada saat kita mendefinisikan view, kita juga memberikan nilai id unik per modul.

6.4 Form: mengatur ulang posisi field

Dalam contoh modul buku_partner_nop_6, kita bekerja pada model res.partner dan akan mengatur ulang posisi field, dimana posisi fax dan mobile akan kita tukar. Pada modul ini, kita tidak menambah field apapun pada model res.partner.

Berikut adalah definisi view selengkapnya (buku_partner_nop_6_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml">

<data> <field name="fax" position="replace"/> <field name="mobile" position="before">

<field name="fax"/> </field> </data>

</field> </record>

</data> </openerp>

Mari kita fokus pada blok:

<data> <field name="fax" position="replace"/> <field name="mobile" position="before">

<field name="fax"/> </field> </data>

Tag <data> dapat digunakan untuk perubahan pada beberapa lokasi sekaligus.

Apa yang kita lakukan adalah: • Menghapus field fax. Menghapus dapat dilakukan dengan memberikan atribut position=”replace”

(mengganti dengan sebuah elemen kosong).

<field name="fax" position="replace"/>

• Menambah field fax sebelum field mobile. Kita akan mulai dari field mobile dengan position=”before”, barulah mendefinisikan field fax di dalamnya.

<field name="mobile" position="before"> <field name="fax"/> </field>

File __openerp__.py dalam modul: {

'name' : 'Partner 6' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), atur posisi field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_6_view.xml' ],

} Sementara __init__.py merupakan file kosong.

6.5 Form: menambah field

Dalam contoh modul buku_partner_nop_7, kita bekerja pada model res.partner dan menambahkan beberapa field. Sebagian dari field yang ditambahkan pada model, akan didefinisikan pada view, dengan pengaturan posisi tertentu.

Field yang ditambahkan (file buku_partner_nop_7.py): from openerp.osv import orm, fields

class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'

_columns = { 'buku_field_13' : fields.char( 'Buku Field 13' , size= 10 ), 'buku_field_14' : fields.char( 'Buku Field 14' , size= 10 ), 'buku_field_15' : fields.char( 'Buku Field 15' , size= 10 ), 'buku_field_16' : fields.char( 'Buku Field 16' , size= 10 ), 'buku_field_17' : fields.char( 'Buku Field 17' , size= 10 ), 'buku_field_18' : fields.char( 'Buku Field 18' , size= 10 ), 'buku_field_19' : fields.char( 'Buku Field 19' , size= 10 ), 'buku_field_20' : fields.char( 'Buku Field 20' , size= 10 ),

Berikut adalah definisi view selengkapnya (buku_partner_nop_7_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml">

<data>

<field name="website" position="before"> <field name="buku_field_13"/> </field> <field name="website" position="after">

<field name="buku_field_14"/> </field> <field name="website" position="replace"/>

</data>

</field> </record> </data>

</openerp>

Apa yang kita lakukan adalah: • Menambahkan field buku_field_13 sebelum website.

<field name="website" position="before"> <field name="buku_field_13"/> </field>

• Menambahkan field buku_field_14 setelah website.

<field name="website" position="after"> <field name="buku_field_14"/> </field>

• Menghapus field website (menggantikan dengan elemen kosong).

<field name="website" position="replace"/>

File __openerp__.py dalam modul: {

'name' : 'Partner 7' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), tambah/hapus field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_7_view.xml' ],

} File __init__.py dalam module:

from . import buku_partner_nop_7

6.6 Form: notebook dan group

Dalam contoh modul buku_partner_nop_8, kita bekerja pada model res.partner dan akan mengelompokkan beberapa field yang ditambahkan pada buku_partner_nop_7, dalam notebook dan group tersendiri.

Berikut adalah definisi view selengkapnya (buku_partner_nop_8_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="buku_partner_nop_7.view_partner_form"/> <field name="arch" type="xml">

<field name="buku_field_13" position="replace"/> <field name="buku_field_14" position="replace"/> <notebook>

<page string="contoh notebook/page"> <label for="buku_field_13"/> <field name="buku_field_13"/> <group string="contoh group">

<field name="buku_field_14"/> </group> <group string="contoh group 2 (6 kolom)" col="6">

<field name="buku_field_15" colspan="4"/> <field name="buku_field_16"/>

</group> </page> </notebook>

</field> </record> </data>

</openerp>

Apa yang kita lakukan adalah: • Membuat sebuah notebook/tab terpisah, didefinisikan dengan <notebook> dan <page>.

<notebook> <page string="contoh notebook/page">

</page> </notebook>

• Menambahkan sebuah field di dalam page tersebut. Per OpenERP versi 7.0, <field name=”nama_field”/> tidak menampilkan label, kecuali ditempatkan di dalam <group>. Oleh karena itu, kita menggunakan <label for=”nama_field”/> seperti pada contoh.

<label for="buku_field_13"/> <field name="buku_field_13"/>

• Kita membuat sebuah group baru, yang bisa digunakan untuk mengelompokkan sejumlah kolom dan kemudian membaginya kembali menjadi kolom-kolom. Per OpenERP versi 7.0, jumlah kolom default dalam group adalah 2, kecuali kita menentukan secara eksplisit dengan atribut col=”n”. Group bisa diberikan label/title seperti pada contoh. Kita tambahkan sebuah field ke dalam group tersebut.

<group string="contoh group"> <field name="buku_field_14"/> </group>

• Kemudian, kita buat satu group lagi dengan jumlah kolom adalah 6. Lalu kita tambahkan dua field, yang pertama menempati 4 kolom (dengan atribut colspan=”n”) dan yang kedua menempati sisanya. Perhatikanlah bahwa label secara otomatis ditambahkan karena dibawah <group>.

<group string="contoh group 2 (6 kolom)" col="6"> <field name="buku_field_15" colspan="4"/> <field name="buku_field_16"/>

</group>

Dalam contoh ini, kita turunkan view dari:

<field name="inherit_id" ref="buku_partner_nop_7.view_partner_form"/>

Modul juga membutuhkan buku_partner_nop_7 sebagaimana didefinisikan pada __openerp__.py: {

'name' : 'Partner 8' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), group' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'buku_partner_nop_7' ], 'data' :[ 'buku_partner_nop_8_view.xml' ],

} Sementara __init__.py merupakan file kosong.

6.7 Form: attrs dan atribut lain

Dalam contoh modul buku_partner_nop_9, kita bekerja pada model res.partner dan akan bekerja dengan beberapa field yang ditambahkan pada buku_partner_nop_7.

Kita akan membuat sebuah tab baru, namun tab tersebut hanya tampil apabila partner adalah perorangan, bukan perusahaan. Apabila Is a Company? di centang, maka tab ini tidak ditampilkan.

Lebih lanjut lagi, di dalam tab tersebut, kita tambahkan dua field, di mana salah satunya, akan menjadi required (harus diisi) apabila: • Partner bukanlah perusahaan, dan • Alamat (street) tidak diisikan.

Berikut adalah definisi view selengkapnya (buku_partner_nop_9_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="buku_partner_nop_7.view_partner_form"/>

<field name="priority" eval="100"/> <field name="arch" type="xml">

<notebook>

<page string="Bukan perusahaan" attrs="{'invisible': [('is_company', '=', True)]}">

<group>

<field name="buku_field_17" password="True" nolabel="1" colspan="2"/> <field name="buku_field_18" attrs="{'required': ['&', ('is_company', '=', False), ('street', '=', False)]}"/>

</group> </page> </notebook>

</field> </record> </data>

</openerp> Apa yang kita lakukan adalah:

• Menambahkan satu page dengan atribut attrs. Format atribut ini adalah: • {'atribut 1': [('nama_field 1', 'operator', nilai),...], …} • dimana atribut adalah: readonly (tidak dapat diubah), invisible (tidak ditampilkan), required

(harus diisi). • Nilai default adalah {} • Atribut yang kita tambahkan pada page tersebut menentukan page tersebut akan invisible (tidak ditampilkan) apabila kondisi berikut terpenuhi: [('is_company', '=', True)]

<page string="Bukan perusahaan" attrs="{'invisible': [('is_company', '=', True)]}">

</page>

• Menambahkan satu field dengan atribut password=”True” (input password/masked), nolabel=”1” (tidak menampilkan label) dan colspan=”2” (menempati dua kolom).

<field name="buku_field_17" password="True" nolabel="1" colspan="2"/>

• Menambahkan satu field lagi, dengan atribut attrs, di mana field akan required apabila kondisi berikut terpenuhi (& untuk operator &) : ['&', ('is_company', '=', False), ('street', '=', False)]

<field name="buku_field_18" attrs="{'required': ['&', ('is_company', '=',

False), ('street', '=', False)]}"/>

Catatan: eval digunakan untuk evaluasi ekspresi Python, digunakan untuk nilai non string. Sama seperti sebelumnya, dalam contoh ini, kita turunkan view dari

buku_partner_nop_7.view_partner_form dan modul juga membutuhkan buku_partner_nop_7. File __openerp__.py dalam modul:

{ 'name' : 'Partner 9' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), atribut field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'buku_partner_nop_7' ], 'data' :[ 'buku_partner_nop_9_view.xml' ],

} Sementara __init__.py merupakan file kosong.

6.8 Form: on change

Dalam contoh modul buku_partner_nop_10, kita bekerja pada model res.partner, dan ketika isi suatu field berubah, fungsi tertentu akan dipanggil. Dalam contoh ini, apa yang dilakukan oleh fungsi akan mengembalikan nilai dengan aturan tertentu, yang diartikan sebagai menampilkan pesan.

Berikut adalah definisi view selengkapnya (buku_partner_nop_10_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="buku_partner_nop_7.view_partner_form"/> <field name="arch" type="xml">

<field name="title" position="after"> <field name="buku_field_19"

on_change="onchange_buku_field_19(buku_field_19)"/>

</field>

</field> </record> </data>

</openerp>

Dan, berikut adalah definisi fungsi yang dipanggil, dalam file buku_partner_nop_10.py: from openerp.osv import orm

class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'

def onchange_buku_field_19(self, cr, uid, ids, buku_field_19, context= None ):

ret = {} ret[ 'warning' ]={

'title' : 'Pesan' , 'message' : 'Isi field buku_field_19 adalah %s' %

(buku_field_19),

return ret

Apa yang kita lakukan adalah menambahkan satu field, dengan atribut on_change, dengan nilai statement pemanggilan fungsi on change, lengkap dengan argumen berupa nama field. Nama field harus didefinisikan dalam view.

<field name="buku_field_19" on_change="onchange_buku_field_19(buku_field_19)"/>

Fungsi yang dipanggil setidaknya harus menerima argumen cr, uid, ids sebagaimana method lain (seperti dibahas pada Bab 4), apa yang ingin kita lewatkan, dan sebuah context (sebagaimana disarankan, disinggung pada Bab 4). Fungsi tersebut dapat merujuk ke record lain yang telah tersimpan dalam database.

def onchange_buku_field_19(self, cr, uid, ids, buku_field_19, context= None ): Nilai kembalian fungsi, sebuah dictionary, akan menentukan apa yang akan dilakukan sesuai key:

• domain: dictionary berupa domain {field: domain}. • value: dictionary berupa nilai field baru: {field: value}. Ini bisa lebih dari satu field, sebagaimana

dibahas pada contoh berikutnya. Dapat memicu pemanggilan fungsi on change pada field lain, apabila didefinisikan.

• warning: dictionary dengan key title (judul) dan message (pesan), yang digunakan untuk menampilkan pesan. Ini adalah yang kita lakukan dalam contoh ini.

ret = {} ret[ 'warning' ]={

'title' : 'Pesan' ,

'message' : 'Isi field buku_field_19 adalah %s' % (buku_field_19),

return ret

Catatan: fungsi on change dapat digunakan pada saat record sedang dibuat dan belum disimpan pada database. Fungsi ini dapat membaca dari database, namun tidak seharusnya menulis ke database.

Sama seperti sebelumnya, dalam contoh ini, kita turunkan view dari buku_partner_nop_7.view_partner_form dan modul juga membutuhkan buku_partner_nop_7.

File __openerp__.py dalam modul: {

'name' : 'Partner 10' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), on change 1' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'buku_partner_nop_7' ], 'data' :[ 'buku_partner_nop_10_view.xml' ],

} File __init__.py dalam modul:

from . import buku_partner_nop_10

6.9 Form: on change (2)

Dalam contoh modul buku_partner_nop_11, kita bekerja pada model res.partner, dan akan menukar nilai field satu dengan field lainnya, apabila isi dari suatu field berubah.

Berikut adalah definisi view selengkapnya (buku_partner_nop_11_view.xml): <?xml version="1.0"?> <openerp>

<data> <record model="ir.ui.view" id="view_partner_form"> <field name="name">res.partner.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="buku_partner_nop_7.view_partner_form"/> <field name="arch" type="xml">

<field name="title" position="after"> <field name="buku_field_20"

on_change="onchange_buku_field_20(buku_field_20, buku_field_19)"/>

</field>

</field> </record> </data>

</openerp> Dan, berikut adalah definisi fungsi on change yang dipanggil, dalam file buku_partner_nop_11.py: </openerp> Dan, berikut adalah definisi fungsi on change yang dipanggil, dalam file buku_partner_nop_11.py:

class res_partner(orm.Model): _name = 'res.partner' _inherit = 'res.partner'

def onchange_buku_field_20(self, cr, uid, ids, buku_field_20,

buku_field_19, context= None ):

ret = {} ret[ 'value' ]={

'buku_field_20' : buku_field_19, 'buku_field_19' : buku_field_20,

return ret

Sebagaimana dibahas pada contoh sebelumnya, fungsi mengembalikan dictionary dengan key berupa value, dengan nilai berupa isi field yang telah ditukar.

Kita lihat bahwa fungsi bekerja dengan isi dua field dilewatkan:

<field name="buku_field_20" on_change="onchange_buku_field_20(buku_field_20, buku_field_19)"/>

Apabila modul pada contoh sebelumnya terinstall, maka ini akan memicu pemanggilan on change. Sama seperti sebelumnya, dalam contoh ini, kita turunkan view dari

buku_partner_nop_7.view_partner_form dan modul juga membutuhkan buku_partner_nop_7. File __openerp__.py dalam modul:

{ 'name' : 'Partner 11' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'form view (partner), on change 2' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'buku_partner_nop_7' ], 'data' :[ 'buku_partner_nop_11_view.xml' ],

} File __init__.py dalam modul:

from . import buku_partner_nop_11

6.10 Tree: tambah/hapus field

Dalam contoh modul buku_partner_nop_12, kita bekerja pada model res.partner, pada tree view (list), dimana: • Field email kita hapus. • Field website kita tambahkan, sebelum phone.

Pada modul ini, kita tidak menambah field apapun pada model res.partner.

Berikut adalah definisi view selengkapnya (buku_partner_nop_12_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_partner_tree"> <field name="name">res.partner.tree</field> <field name="model">res.partner</field> <field name="inherit_id" ref="base.view_partner_tree"/> <field name="arch" type="xml">

<data> <field name="email" position="replace"/> <field name="phone" position="before">

<field name="website"/> </field>

</data>

</field> </record> </data>

</openerp> Apa yang berbeda dengan contoh sebelumnya (5.4, modul buku_partner_nop_6), dari sisi inheritance,

selain field yang terlibat, adalah:

<field name="inherit_id" ref="base.view_partner_tree"/>

Di mana nilai base.view_partner_tree kita dapatkan dari popup Manage Views dengan developer mode diaktifkan.

File __openerp__.py dalam modul: {

'name' : 'Partner 12' , 'version' : '1.0' , 'author' : 'noprianto' , 'description' : 'tree view (partner), tambah/sembunyikan field' , 'category' : 'Buku' , 'website' : 'https://github.com/id-python/buku-openerp' , 'depends' :[ 'base' ], 'data' :[ 'buku_partner_nop_12_view.xml' ],

} Sementara __init__.py merupakan file kosong.

6.11 Menuitem dan editable tree

Dalam contoh ini, kita membuat model buku.catatan, dalam modul buku_catatan, dimana ketika terinstall, sebuah menu/menuitem baru akan ditambahkan. Selain itu, tree view juga kita gunakan untuk menambahkan/mengedit.

Berikut adalah model yang dibuat, dalam file buku_catatan.py: from openerp.osv import orm, fields

class res_partner(orm.Model): _name = 'buku.catatan' _description = 'Catatan'

_columns = { 'title' : fields.char( 'Title' , size= 32 , required= True ),

'content' : fields.text( 'Content' ),

Dan, berikut adalah definisi view selengkapnya (buku_catatan_view.xml): <?xml version="1.0"?>

<openerp> <data> <record model="ir.ui.view" id="view_catatan_form"> <field name="name">buku.catatan.form</field>

<field name="model">buku.catatan</field> <field name="arch" type="xml">

<form string="Catatan"> <group> <field name="title"/> <field name="content"/>

</group> </form>

</field> </record>

<record model="ir.ui.view" id="view_catatan_tree"> <field name="name">buku.catatan.tree</field> <field name="model">buku.catatan</field> <field name="arch" type="xml">

<tree string="Catatan" editable="bottom"> <field name="title"/> <field name="content"/>

</tree>

</field> </record>

<record model="ir.actions.act_window" id="action_buku_catatan_tree"> <field name="name">Catatan</field> <field name="res_model">buku.catatan</field>

</record> <menuitem name="Buku" id="menu_buku"/>

<menuitem name="Catatan" id="menu_buku_catatan" parent="menu_buku"/> <menuitem name="Catatan" id="menu_buku_catatan_tree"

parent="menu_buku_catatan" action="action_buku_catatan_tree"/> </data>

</openerp>

Form didefinisikan dengan:

<form string="Catatan"> <group> <field name="title"/> <field name="content"/>

</group> </form>

Editable tree, dalam hal ini didefinisikan dengan:

<tree string="Catatan" editable="bottom"> <field name="title"/> <field name="content"/>

</tree>

Action didefinisikan dengan: