Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3546f26
[add] cms_form + cms_form_example
simahawk Feb 16, 2017
bbf131f
can_edit: check for access rules too
simahawk Mar 10, 2017
dccf035
[imp] support selection field
simahawk Mar 17, 2017
2b44108
remove useless coverage conf
simahawk Mar 17, 2017
6f1780c
[fix] boolean widget value handler
simahawk Mar 17, 2017
6b781fd
add form_to_bool util [ci skip]
simahawk Mar 21, 2017
a6d80c7
add master/slave field support
simahawk Mar 22, 2017
dd52920
allow override of redirect url via "redirect" param [ci skip]
simahawk Mar 23, 2017
81af2bf
fixup! allow override of redirect url via "redirect" param [ci skip]
simahawk Mar 24, 2017
31d7852
update german transl [ci skip]
simahawk Mar 30, 2017
c8ff5a7
fix translation [ci skip]
simahawk Mar 31, 2017
b882f36
[imp] wrap help block into div to allow custom <p />
simahawk Apr 21, 2017
b929121
[fix] request value retrieval w/ extra querystring args
simahawk Apr 27, 2017
c17bbf4
[fix] master/slave: get only changed input
simahawk May 12, 2017
f8d8114
[add] selection radio widget
simahawk May 12, 2017
86a72ed
add option item class
simahawk May 15, 2017
f5fd149
add subwidgets facilities and help msg by option
simahawk May 15, 2017
0000512
improve master slave js
simahawk May 15, 2017
270423e
improve search form template
simahawk May 16, 2017
92eb4f8
add TODO to improve validation [ci skip]
simahawk May 18, 2017
274c7d2
[imp] include form name into wrapper css class
simahawk May 22, 2017
7325809
fix tests
simahawk May 25, 2017
0b28ebc
[imp] cache form_fields
simahawk May 25, 2017
119ea33
[imp] move widgets to models
simahawk May 25, 2017
891d7cb
ease widget override
simahawk May 25, 2017
60429a1
widgets fix/imp
simahawk May 25, 2017
bda440c
better subfields
simahawk May 26, 2017
6f7a594
Relicense under LGPL
simahawk May 26, 2017
3bf0c52
update license in README [ci skip]
simahawk May 26, 2017
48e083d
[fix] load defaults via defaults_get
simahawk May 26, 2017
3c25917
oops, remove print statement
simahawk May 29, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions cms_form/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
.. image:: https://img.shields.io/badge/licence-lgpl--3-blue.svg
:target: http://www.gnu.org/licenses/LGPL-3.0-standalone.html
:alt: License: LGPL-3

CMS Form
========

Basic website contents form framework. Allows to define front-end forms for every models in a simple way.

If you are tired of re-defining every time an edit form or a search form for your odoo website,
this is the module you are looking for.

Features
========

* automatic form generation (create, write, search)
* automatic route generation (create, write, search)
* automatic machinery based on fields' type:
* widget rendering
* field value load (from existing instance or from request)
* field value extraction (from request)
* field value write (to existing instance)

* highly customizable
* works with every odoo model
* works also without any model
* add handy attributes to models inheriting from ``website.published.mixin``:
* ``cms_add_url``: lead to create form view. By default ``/cms/form/create/my.model``
* ``cms_edit_url``: lead to edit form view. By default ``/cms/form/edit/my.model/model_id``
* ``cms_search_url``: lead to search form view. By default ``/cms/form/search/my.model``

Usage
=====

Create / Edit form
------------------

Just inherit from ``cms.form`` to add a form for your model. Quick example for partner:

.. code-block:: python

class PartnerForm(models.AbstractModel):

_name = 'cms.form.res.partner'
_inherit = 'cms.form'
_form_model = 'res.partner'
_form_model_fields = ('name', 'country_id')
_form_required_fields = ('name', 'country_id')


In this case you'll have form with the following characteristics:

* works with ``res.partner`` model
* have only ``name`` and ``country_id`` fields
* both fields are required (is not possible to submit the form w/out one of those values)

Here's the result:

|preview_create|
|preview_edit|

The form will be automatically available on these routes:

* ``/cms/form/create/res.partner`` to create new partners
* ``/cms/form/edit/res.partner/1`` edit existing partners (partner id=1 in this case)

NOTE: default generic routes work if the form's name is ``cms.form.`` + model name, like ``cms.form.res.partner``.
If you want you can easily define your own controller and give your form a different name,
and have more elegant routes like ```/partner/edit/partner-slug-1``.
Take a look at `cms_form_example <../cms_form_example>`_.

By default, the form is rendered as an horizontal twitter bootstrap form, but you can provide your own templates of course.
By default, fields are ordered by their order in the model's schema. You can tweak it using ``_form_fields_order``.


Form with extra control fields
------------------------------

Imagine you want to notify the partner after its creation but only if you really need it.

The form above can be extended with extra fields that are not part of the ``_form_model`` schema:

.. code-block:: python

class PartnerForm(models.AbstractModel):

_name = 'cms.form.res.partner'
_inherit = 'cms.form'
_form_model = 'res.partner'
_form_model_fields = ('name', 'country_id', 'email')
_form_required_fields = ('name', 'country_id', 'email')

notify_partner = fields.Boolean()

def form_after_create_or_update(self, values, extra_values):
if extra_values.get('notify_partner'):
# do what you want here...

``notify_partner`` will be included into the form but it will be discarded on create and write.
Nevertheless you can use it as a control flag before and after the record has been created or updated
using the hook ``form_after_create_or_update``, as you see in this example.


Search form
-----------

Just inherit from ``cms.form.search`` to add a form for your model. Quick example for partner:

.. code-block:: python

class PartnerSearchForm(models.AbstractModel):
"""Partner model search form."""

_name = 'cms.form.search.res.partner'
_inherit = 'cms.form.search'
_form_model = 'res.partner'
_form_model_fields = ('name', 'country_id', )
_form_fields_order = ('country_id', 'name', )


|preview_search|

The form will be automatically available at: ``/cms/form/search/res.partner``.

NOTE: default generic routes work if the form's name is ```cms.form.search`` + model name, like ``cms.form.search.res.partner``.
If you want you can easily define your own controller and give your form a different name,
and have more elegant routes like ``/partners``.
Take a look at `cms_form_example <../cms_form_example>`_.


Master / slave fields
---------------------

A typical use case nowadays: you want to show/hide fields based on other fields' values.
For the simplest cases you don't have to write a single line of JS. You can do it like this:

.. code-block:: python

class PartnerForm(models.AbstractModel):

_name = 'cms.form.res.partner'
_inherit = 'cms.form'
_form_model = 'res.partner'
_form_model_fields = ('name', 'type', 'foo')

def _form_master_slave_info(self):
info = self._super._form_master_slave_info()
info.update({
# master field
'type':{
# actions
'hide': {
# slave field: action values
'foo': ('contact', ),
},
'show': {
'foo': ('address', 'invoice', ),
}
},
})
return info

Here we declared that:

* when `type` field is equal to `contact` -> hide `foo` field
* when `type` field is equal to `address` or `invoice` -> show `foo` field


Known issues / Roadmap
======================

* add more tests, especially per each widget and type of field
* provide better widgets for image and file fields in general
* o2m fields: to be tested at all
* move widgets to abstract models too
* search form: generate default search domain in a clever way
* add easy way to switch from horizontal to vertical form
* provide more examples
* x2x fields: allow sub-items creation
* handle api onchanges
* support python expressions into master/slave rules


Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/OCA/website-cms/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.

Credits
=======

Sponsor
-------

* `Fluxdock.io <https://fluxdock.io>`_.

Contributors
------------

* Simone Orsi <simone.orsi@camptocamp.com>

Maintainer
----------

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

This module is maintained by the OCA.

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

To contribute to this module, please visit https://odoo-community.org.

.. |preview_create| image:: ./images/cms_form_example_create_partner.png
.. |preview_edit| image:: ./images/cms_form_example_edit_partner.png
.. |preview_search| image:: ./images/cms_form_example_search.png
2 changes: 2 additions & 0 deletions cms_form/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import controllers
24 changes: 24 additions & 0 deletions cms_form/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Simone Orsi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).

{
'name': 'CMS Form',
'summary': """
Basic content type form""",
'version': '9.0.1.0.0',
'license': 'LGPL-3',
'author': 'Camptocamp SA, Odoo Community Association (OCA)',
'depends': [
'website',
'cms_status_message',
],
'data': [
'security/cms_form.xml',
'templates/assets.xml',
'templates/form.xml',
'templates/widgets.xml',
],
'demo': [
],
}
1 change: 1 addition & 0 deletions cms_form/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
Loading