{ "info": { "author": "Kevin Gill", "author_email": "kevin@movieextras.ie", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Plone", "Framework :: Plone :: 5.1", "Framework :: Plone :: 5.2", "Framework :: Plone :: Addon", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. contents:: Table of Contents\n\nIntroduction\n============\n\nProvides a field with a datagrid (table), where each row is a sub form.\n\nIt is a `z3c.form `_ implementation of the `Products.DataGridField `_ .\n\nThis product was developed for use with Plone and Dexterity.\n\n.. image:: https://travis-ci.org/collective/collective.z3cform.datagridfield.png\n :target: http://travis-ci.org/collective/collective.z3cform.datagridfield\n\n\nRequirements\n------------\n\n* Versions >= 1.4 are for Plone 5+, if you use Plone 4.3, use versions 1.3.x\n* For Python 3.7 at least PyYAML 4.2b1\n* z3c.forms\n* A browser with javascript support\n* jquery 1.4.3 or later\n\n\nInstallation\n============\n\nAdd collective.z3cform.datagridfield to your buildout eggs:\n\n.. code-block:: ini\n\n [buildout]\n ...\n eggs =\n collective.z3cform.datagridfield\n\n\nExample usage\n=============\n\nThis piece of code demonstrates a schema which has a table within it.\nThe layout of the table is defined by a second schema:\n\n.. code-block:: python\n\n from collective.z3cform.datagridfield import DataGridFieldFactory\n from collective.z3cform.datagridfield import DictRow\n from z3c.form import field\n from z3c.form import form\n from z3c.form.form import extends\n from zope import interface\n from zope import component\n from zope import schema\n\n\n class ITableRowSchema(interface.Interface):\n one = schema.TextLine(title=u\"One\")\n two = schema.TextLine(title=u\"Two\")\n three = schema.TextLine(title=u\"Three\")\n\n\n class IFormSchema(interface.Interface):\n four = schema.TextLine(title=u\"Four\")\n table = schema.List(title=u\"Table\",\n value_type=DictRow(title=u\"tablerow\", schema=ITableRowSchema))\n\n @component.adapter(IFormSchema)\n class EditForm(form.EditForm):\n\n fields = field.Fields(IFormSchema)\n label=u\"Demo Usage of DataGridField\"\n\n fields['table'].widgetFactory = DataGridFieldFactory\n\nConfigured like so:\n\n.. code-block:: xml\n\n \n\n\nAlso it can be used from a supermodel XML:\n\n.. code-block:: xml\n\n \n \n Table\n \n your.package.interfaces.ITableRowSchema\n \n \n \n\n\nStorage\n-------\n\nThe data can be stored as either a list of dicts or a list of objects.\nIf the data is a list of dicts, the value_type is DictRow.\nOtherwise, the value_type is 'schema.Object'.\n\nIf you are providing an Object content type (as opposed to dicts) you must provide your own conversion class.\nThe default conversion class returns a list of dicts,\nnot of your object class.\nSee the demos.\n\n\nConfiguration\n=============\n\n\nRow editor handles\n------------------\n\nThe widget can be customised via the updateWidgets method.\n\n.. code-block:: python\n\n def updateWidgets(self):\n super(EditForm, self).updateWidgets()\n self.widgets['table'].allow_insert = False # Enable/Disable the insert button on the right\n self.widgets['table'].allow_delete = False # Enable/Disable the delete button on the right\n self.widgets['table'].auto_append = False # Enable/Disable the auto-append feature\n self.widgets['table'].allow_reorder = False # Enable/Disable the re-order rows feature\n self.widgets['table'].main_table_css_class = 'my_custom_class' # Change the class applied on the main table when the field is displayed\n\nThe widget contains an attribute 'columns' which is manipulated to hide column\ntitles.\n\n\nBlock edit mode\n---------------\n\nA widget class variation ``BlockDataGridField`` is provided.\nThis widget renders subform widgets vertically in blocks instead of horizontally in cells.\nIt makes sense when there are many subform fields and they have problem to fit on the screen once.\n\nExample:\n\n.. code-block:: python\n\n class EditForm9(EditForm):\n label = u'Rendering widgets as blocks instead of cells'\n\n grok.name('demo-collective.z3cform.datagrid-block-edit')\n\n def update(self):\n # Set a custom widget for a field for this form instance only\n self.fields['address'].widgetFactory = BlockDataGridFieldFactory\n super(EditForm9, self).update()\n\n\nManipulating the Sub-form\n-------------------------\n\nThe DataGridField makes use of a subform to build each line.\nThe main DataGridField contains a DataGridFieldObject for each line in the table.\nThe DataGridFieldObject in turn creates the DataGridFieldObjectSubForm to store the fields.\n\nThere are two callbacks to your main form:\n\n**datagridInitialise(subform, widget)**\n\n* This is called when the subform fields have been initialised,\n but before the widgets have been created. Field based configuration could occur here.\n\n**datagridUpdateWidgets(subform, widgets, widget)**\n\n* This is called when the subform widgets have been created.\n At this point, you can configure the widgets, e.g. specify the size of a widget.\n\nHere is an example how one can customize per-field widgets for the data grid field:\n\n.. code-block:: python\n\n from .widget import DGFTreeSelectFieldWidget\n from collective.z3cform.datagridfield import DataGridFieldFactory\n from collective.z3cform.datagridfield import DictRow\n from Products.CMFCore.interfaces import ISiteRoot\n from z3c.form import form\n from zope import interface\n from zope import schema\n\n\n class ITableRowSchema(form.Schema):\n\n form.widget(one=DGFTreeSelectFieldWidget)\n one = schema.TextLine(title=u\"Level 1\")\n\n form.widget(two=DGFTreeSelectFieldWidget)\n two = schema.TextLine(title=u\"Level 2\")\n\n # Uses the default widget\n three = schema.TextLine(title=u\"Level 3\")\n\n\n class IFormSchema(form.Schema):\n\n form.widget(table=DataGridFieldFactory)\n table = schema.List(\n title=u\"Nested selection tree test\",\n value_type=DictRow(\n title=u\"tablerow\",\n schema=ITableRowSchema\n )\n )\n\n\nWorking with plone.app.registry\n-------------------------------\n\nTo use the field with plone.app.registry, you'll have to use\na version of the field that has PersistentField as it's base\nclass:\n\n.. code-block:: python\n\n from collective.z3cform.datagridfield.registry import DictRow\n\n\nJavaScript events\n-----------------\n\n``collective.z3cform.datagridfield`` fires jQuery events,\nso that you can hook them in your own Javascript for DataGridField\nbehavior customization.\n\nThe following events are currently fired against ``table.datagridwidget-table-view``\n\n* ``beforeaddrow`` [datagridfield, newRow]\n\n* ``afteraddrow`` [datagridfield, newRow]\n\n* ``beforeaddrowauto`` [datagridfield, newRow]\n\n* ``afteraddrowauto`` [datagridfield, newRow]\n\n* ``aftermoverow`` [datagridfield]\n\n* ``afterdatagridfieldinit`` - All DGFs on the page have been initialized\n\nExample usage:\n\n.. code-block:: javascript\n\n var handleDGFInsert = function(event, dgf, row) {\n row = $(row);\n console.log(\"Got new row:\");\n console.log(row);\n };\n\n // Bind all DGF handlers on the page\n $(document).on('beforeaddrow beforeaddrowauto', '.datagridwidget-table-view', handleDGFInsert);\n\n\nDemo\n====\n\nMore examples are in the demo subfolder of this package.\n\n\nChangelog\n=========\n\n1.5.1 (2019-03-21)\n------------------\n\n- Add missing upgrade profile to_2\n [agitator]\n\n\n1.5.0 (2019-03-09)\n------------------\n\n- Add support for Python 3 and Plone 5.2.\n [pbauer, agitator]\n\n\n1.4.0 (2019-02-21)\n------------------\n\n- Drop support for Plone 4.\n [pbauer]\n\n- Use Ressource-Registry (Pat-Registry), Update JS/CSS, Add Uninstall\n [2silver]\n\n- use Plone5 glyphicons instead of images\n [2silver]\n\n- Added missing upgrade step, calling browserlayer setup.\n [sgeulette]\n\n- Display column description if provided in schema `field.description`.\n [gbastien, bleybaert]\n\n- Specify in README.rst that versions >= 1.4 are for Plone 5+ and\n versions < 1.4 are for Plone 4.\n [gbastien]\n\n- Usability change: add an (hidden) label inside the add commands\n [keul]\n\n- Compatibility with Plone 5 modals/overlay from mockup\n [keul]\n\n1.3.1 (2019-02-21)\n------------------\n\n- Extend uninstall profile.\n [thet]\n\n- Wrapped commands inside ``A`` tags, required for accessibility reason (change backported from Products.DataGridField).\n This also simplify customizing icons with pure CSS.\n [keul]\n\n- Replaced minus icon with a more usable delete icon.\n [keul]\n\n- Removed ols-school ``*`` chars for marking fields as required.\n [keul]\n\n- Fix object access\n [tomgross]\n\n- Fix usage of related items widget in subforms\n https://github.com/plone/Products.CMFPlone/issues/2446\n [tomgross]\n\n1.3.0 (2017-11-22)\n------------------\n\n- Set widget mode on cell widget in order to support autoform mode directive. [jone]\n\n- Bugfix: do not try to update readonly fields. [jone]\n\n- Cleanup: utf8 headers, isort, code-style. [jensens]\n\n- Remove dependency on plone.directives.form in setup.py,\n it was not used any longer. [jensens]\n\n- Feature/Fix: Support widgets using patternslib in a DictRow.\n [jensens]\n\n- Fix: #36 remove grok from all documentation since grok is no longer supported.\n [jensens]\n\n- Copy relevant parts of ObjectSubform from z3c.form 3.2.10 over here, it was removed in later versions.\n [jensens]\n\n- Add Browserlayer and use it, also add uninstall step.\n [jensens]\n\n- Move Demo package to in here.\n [jensens]\n\n\n1.2 (2017-03-08)\n----------------\n\n- Fix validation exception on readonly fields.\n [rodfersou]\n- Fix bug for widget.klass is NonType in the block view when defining the class for the field.\n- Allow deletion of last row in non-auto-append mode.\n [gaudenz]\n- fixed binding for IChoice fields during validation [djay]\n- plone 5 compatibility and fixed travis testing for plone 5 [djay]\n\n\n1.1 (2014-07-25)\n----------------\n\n- Removed JS code that relies on firefox being used.\n [neilferreira]\n\n- Stopped referencing the 'event' element when creating a new row as the event\n that triggered the content of an input changing may have been from another element.\n [neilferreira]\n\n\n1.0 (2014-06-02)\n----------------\n\n- Add 'form-widgets-field_id' as widget css id (consistency with other widgets).\n [thomasdesvenain]\n\n- Fix package dependencies.\n [hvelarde]\n\n- Use BlockDataGridFieldObject for rows in a BlockDataGridField.\n [gaudenz]\n\n- Filter out any auto append or template rows in updateWidgets.\n [gaudenz]\n\n- Add row parameter to aftermoverow JS event\n [gaudenz]\n\n- Don't reset class attribute on cloned template rows\n [gaudenz]\n\n- Replace row index in all template row elements, not just input elements.\n Replace the index in id, name, for, href and data-fieldname attributes\n when cloning the template row.\n [gaudenz]\n\n\n0.15 (2013-09-24)\n-----------------\n\n- Added possibility to define the CSS class for the main table when the field is displayed.\n This way, you can use common Plone existing classes (like 'listing').\n [gbastien]\n\n- Fixed auto-append bug when there is more than one datagrid field in page auto-appending one field binds\n \"change.dgf\" to another field also. added \"$(dgf).find(..\" in datagridfield.js line 138 so it binds to right element only.\n [tareqalam]\n\n- Only abort moveRow if the row is really not found and not if the row idx just happens to be 0.\n [gaudenz]\n\n- Also update hidden data rows when reindexing in row mode. This fix was previously somehow only done for block mode.\n [gaudenz]\n\n- Relax requirements for markup, don't assume inputs are direct childs of table cells. This makes useing custom\n templates much easier.\n [gaudenz]\n\n- Fix validate function signature for IValidator API. The API requires a \"force\" argument.\n [gaudenz]\n\n- Register the SubformAdapter for IPloneForm layer to avoid that the Adapter from plone.app.z3cform\n takes precedence.\n [gaudenz]\n\n\n0.14 (2013-05-24)\n-----------------\n\n- Align travis setup to other packages.\n [saily]\n\n- Add new V1 ``bootstrap.py``.\n [saily]\n\n- Added CSS classes to tbody rows (``row-(1...n)``) and thead columns\n (``cell-(1...m)``) to allow more styling in edit forms.\n [saily]\n\n- Fixed wrong template in display mode when set editing to block edit mode [miohtama]\n\n- Added CSS classes (widget.klass attribute) for DataGridField, to separate it from other MultiWidgets [miohtama]\n\n\n0.13 (2013-04-09)\n-----------------\n\n- Add travis-ci configs [jaroel]\n\n- Convert tests to plone.app.testing [jaroel]\n\n- Fix to expect ``zope.schema.interfaces.ValidationError`` to work better\n with *TooLong* and *TooShort* exceptions. [datakurre]\n\n- Fix IE7 failing on `