Giter VIP home page Giter VIP logo

collective.z3cform.datagridfield's Introduction

Introduction

Provides a field with a datagrid (table), where each row is a sub form.

It is a z3c.form implementation of the Products.DataGridField .

This product was developed for use with Plone and Dexterity.

Installation

Add collective.z3cform.datagridfield to your buildout eggs:

[buildout]
...
eggs =
    collective.z3cform.datagridfield

Example usage

This piece of code demonstrates a schema which has a table within it. The layout of the table is defined by a second schema:

from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory
from collective.z3cform.datagridfield.row import DictRow
from plone.autoform.directives import widget
from plone.autoform.form import AutoExtensibleForm
from z3c.form import form
from zope import interface
from zope import schema


class ITableRowSchema(interface.Interface):
    one = schema.TextLine(title=u"One")
    two = schema.TextLine(title=u"Two")
    three = schema.TextLine(title=u"Three")


class IFormSchema(interface.Interface):
    four = schema.TextLine(title=u"Four")
    table = schema.List(
        title=u"Table",
        value_type=DictRow(
            title=u"tablerow",
            schema=ITableRowSchema,
        ),
    )

    widget(table=DataGridFieldFactory)


class EditForm(AutoExtensibleForm, form.EditForm):
    label=u"Demo Usage of DataGridField"
    schema = IFormSchema

And configured via zcml:

<browser:page
    name="editform--example"
    class=".editform.EditForm"
    for="*"
    permission="zope2.View"
    />

Also it can be used from a supermodel XML:

<field name="table" type="zope.schema.List">
  <description/>
  <title>Table</title>
  <value_type type="collective.z3cform.datagridfield.DictRow">
    <schema>your.package.interfaces.ITableRowSchema</schema>
  </value_type>
  <form:widget type="collective.z3cform.datagridfield.DataGridFieldFactory"/>
</field>

Storage

The data can be stored as either a list of dicts or a list of objects. If the data is a list of dicts, the value_type is DictRow. Otherwise, the value_type is 'schema.Object'.

If you are providing an Object content type (as opposed to dicts) you must provide your own conversion class. The default conversion class returns a list of dicts, not of your object class. See the demos.

Configuration

Row editor handles

Widget parameters can be passed via widget hints. Extended schema example from above:

class IFormSchema(interface.Interface):
    four = schema.TextLine(title=u"Four")
    table = schema.List(
        title=u"Table",
        value_type=DictRow(
            title=u"tablerow",
            schema=ITableRowSchema,
        ),
    )

    widget(
        "table",
        DataGridFieldFactory,
        allow_insert=False,
        allow_delete=False,
        allow_reorder=False,
        auto_append=False,
        display_table_css_class="table table-striped",
        input_table_css_class="table table-sm",
    )

Manipulating the Sub-form

The DictRow schema can also be extended via widget hints. Extended schema examples from above:

from z3c.form.browser.checkbox import CheckBoxFieldWidget


class ITableRowSchema(interface.Interface):

    two = schema.TextLine(title=u"Level 2")

    address_type = schema.Choice(
        title="Address Type",
        required=True,
        values=["Work", "Home"],
    )
    # show checkboxes instead of selectbox
    widget(address_type=CheckBoxFieldWidget)


class IFormSchema(interface.Interface):

    table = schema.List(
        title=u"Nested selection tree test",
        value_type=DictRow(
            title=u"tablerow",
            schema=ITableRowSchema
        )
    )
    widget(table=DataGridFieldFactory)

Working with plone.app.registry

To use the field with plone.app.registry, you'll have to use a version of the field that has PersistentField as it's base class:

from collective.z3cform.datagridfield.registry import DictRow

JavaScript events

collective.z3cform.datagridfield fires jQuery events, so that you can hook them in your own Javascript for DataGridField behavior customization.

The following events are currently fired against table.datagridwidget-table-view

  • beforeaddrow [datagridfield, newRow]
  • afteraddrow [datagridfield, newRow]
  • beforeaddrowauto [datagridfield, newRow]
  • afteraddrowauto [datagridfield, newRow]
  • aftermoverow [datagridfield]
  • afterdatagridfieldinit - All DGFs on the page have been initialized

Example usage:

var handleDGFInsert = function(event, dgf, row) {
    row = $(row);
    console.log("Got new row:");
    console.log(row);
};

// Bind all DGF handlers on the page
$(document).on('beforeaddrow beforeaddrowauto', '.datagridwidget-table-view', handleDGFInsert);

Demo

More examples are in the demo subfolder of this package.

Versions

  • Version 3.x is Plone 6+ only (z3c.form >= 4)
  • Versions 1.4.x and 2.x are for Plone 5.x,
  • Versions 1.3.x is for Plone 4.3
  • For Python 3.7 at least PyYAML 4.2b1

Requirements

  • z3c.forms
  • A browser with javascript support
  • jquery 1.4.3 or later

collective.z3cform.datagridfield's People

Contributors

2silver avatar agitator avatar davisagli avatar djay avatar domenkozar avatar erral avatar frapell avatar gaudenz avatar gbastien avatar gomez avatar hvelarde avatar jaroel avatar jensens avatar keul avatar ksuess avatar laulaz avatar lentinj avatar lrowe avatar mauritsvanrees avatar miohtama avatar pbauer avatar petschki avatar rodfersou avatar saily avatar tdesvenain avatar thet avatar thomasmassmann avatar tomgross avatar vangheem avatar vincentfretin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

collective.z3cform.datagridfield's Issues

p.a.registry, DictRow and custom validator

My schema looks like:

from plone.directives import form
from collective.z3cform.datagridfield import DataGridFieldFactory
from collective.z3cform.datagridfield.registry import DictRow

class IPanelRowSchema(form.Schema):
    path = TextLine(title=u"Path", required=False)
    title = TextLine(title=u"Title", required=False)

class IPanelSchema(form.Schema):
    form.widget(paths=DataGridFieldFactory)
    paths = List(value_type=DictRow(title=u"tablerow", schema=IPanelRowSchema))

@form.validator(field=IPanelSchema['paths'])
def validatePaths(value):
    pass

and I'm using the schema as schema for controlpanel.RegistryEditForm (Plone 4.2). The control panel uses p.a.registry as a storage. When I try to apply p.a.registry GS profile, it fails on:

  File "/zope/eggs/plone.app.registry-1.1-py2.6.egg/plone/app/registry/exportimport/handler.py", line 80, in importDocument
    self.importRecords(node)
  File "/zope/eggs/plone.app.registry-1.1-py2.6.egg/plone/app/registry/exportimport/handler.py", line 253, in importRecords
    self.context.registerInterface(interface, omit=tuple(omit), prefix=prefix)
  File "/zope/eggs/plone.registry-1.0.1-py2.6.egg/plone/registry/registry.py", line 112, in registerInterface
    self.records[record_name] = Record(persistent_field, value, _validate=False)
  File "/zope/eggs/plone.registry-1.0.1-py2.6.egg/plone/registry/registry.py", line 164, in __setitem__
    self._setField(name, record.field)
  File "/zope/eggs/plone.registry-1.0.1-py2.6.egg/plone/registry/registry.py", line 257, in _setField
    raise ValueError("The record's field must be an IPersistentField.")
ValueError: The record's field must be an IPersistentField.

as soon as I remove the validator, p.a.registry GS step is applied without any problems. I have tried to register the validator as described in http://developer.plone.org/forms/z3c.form.html#form-widget-validators but the problem is the same.

relationchoice not working ...

from plone.app.vocabularies.catalog import CatalogSource
from z3c.relationfield.schema import RelationChoice
from zope import schema
from zope.interface import Interface

from collective.z3cform.datagridfield import DataGridFieldFactory
from collective.z3cform.datagridfield import DictRow
from plone.autoform import directives
from plone.supermodel import model

class IItemRow(Interface):
    note = schema.TextLine(
        title=u'Note',
        required=True,
        default=u'',
    )
    events = RelationChoice(
        title=u'Event',
        source=CatalogSource(portal_type=['Event']),
        required=True,
    )

class IEventsGroup(model.Schema):
    directives.widget(employees=DataGridFieldFactory)
    employees = schema.List(
        title=u'A list of events with notes.',
        required=False,
        value_type=DictRow(
            title=u'Event',
            schema=IEventRow,
        )
    )

IEventsGroup is a globally addable contenttype.

the widget gets displayed, but when clicking in the relationchoice widget i get a spinner and no result. calling the view "getSource" i get {"error": "Vocabulary lookup not allowed."}
this seems to occur as self.context.context has NO_VALUE

any help?

Test failures in Plone 5.0.7

There are TravisCI test failures on master branch. These tests are running fine in 5.0.6. Any idea what changed from 5.0.6 to 5.0.7 that makes the test setup break?

Displayed datagridfield should use class "listing" instead of "datagridwidget-table-view"

Hi,

I suggest that when displayed (could also be the case when edited but less important), the datagridfield should use the "listing" default Plone table class instead his own "datagridwidget-table-view" class. The first thing is that when integrated in a common skin, it will integrate with other displayed table (using class "listing") on the same page, moreover, in Plone4+, the "odd/even" is managed automatically using jQuery and applies to tables having the "listing" class...

So what about : just changing the table class to "listing", or propose a way to define the table class on the widget?

Thank you for considering this ;-)

Gauthier

Please release latest changes

hi, can someone do a release of the latest changes or give me permissions on pypi (user rnix) so i can do it?

thanks

Need help with indexing a field of a subform

Is there a way to index a field from a subform?

My aim is to have a user list their educational background, which should be indexed and searchable, in order to find the user by their school(s) when using the Plone's global search box.

I'm using collective.z3cform.datagridfield for the subform.

The snippets below works for rendering and saving the data but it's not showing up in the index.

# Subform
class IEducation(model.Schema):

    dexteritytextindexer.searchable('school')

    school = schema.TextLine(
        title=_(u'School'),
        required=True,
    )
    directives.widget(
        'school',
        AjaxSelectFieldWidget,
        pattern_options={
            "maximumSelectionSize": 1
        },
        vocabulary="my.package.vocabularies.schools"
    )

    from_date = schema.Date(
        title=_(u'From'),
        required=True
    )

    to_date = schema.Date(
        title=_(u'To'),
        required=True
    )
# Parent form
class IMember(model.Schema):

    education = schema.List(
        title=_(u'Education'),
        value_type=DictRow(title=u"education", schema=IEducation),
        required=False
    )
    directives.widget(
        'education',
        BlockDataGridFieldFactory
    )

Reference the index point in the `indexers.py``

@indexer(IEducation)
def school(obj):
    return obj.school

Set the adapter for the school index

  <adapter factory=".indexers.school" name="school" />

Create a dynamic vocabulary for the school index

@provider(IContextSourceBinder)
def available_schools(context):
    catalog = api.portal.get_tool('portal_catalog')
    schools = catalog.uniqueValuesFor('school')
    return SimpleVocabulary([
        SimpleTerm(value=school, title=school) for school in schools
    ])

Register the utility for the dynamic school vocabulary

  <utility
      provides="zope.schema.interfaces.IVocabularyFactory"
      component=".vocabularies.available_schools"
      name="my.package.vocabularies.schools"
      />

Values not being saved when using select2 widget inside of DataGridField.

When using RelatedItemsWidget or AjaxSelectWidget inside of a DataGridField the values added to a new row are not saved. Values from other subfields (TextLine for example) are saved.

The issue can be reproduced using the following dependencies:

plone.app.widgets = 1.x
collective.z3cform.datagridfield = 1.1

Steps to reproduce:

Install collective.z3cform.datagridfield and create a content type using this as a datagrid field:

category = ListField(title=_(uโ€™Category')
        value_type=DictRow(title=_(u'Category'), schema=ICategory),
        required=False)
form.widget(category=DataGridFieldFactory)

Create the interface schema:

class ICategory(form.Schema):
    form.widget('name', AjaxSelectFieldWidget, vocabulary=โ€œyour.product.vocabulary")
    name = schema.List(
        title=_(u'Category'),
        required=False,
        value_type=schema.TextLine(),
        missing_value=[]
    )
    notes = schema.Text(title=_(Notes'), required=False)

I noticed that the values are getting empty to the GridDataConverter.
The extract function from DataGridFieldObject also returns the new rows with empty values for the subfields that are using the select2 widgets.

IndexError after upgrade from 1.2 to 1.3.0

Hi,

I have multiple forms displaying registry records with datagrid field, like https://github.com/collective/collective.contact.plonegroup/blob/44e8011190bc2f0f027152e70430f40b5bf4be84/src/collective/contact/plonegroup/browser/settings.py#L129

After upgrade to 1.3.0, I have the following error on form view:

Module zope.tales.tales, line 696, in evaluate
   - URL: /srv/cache/eggs/plone.app.z3cform-0.7.7-py2.7.egg/plone/app/z3cform/templates/multi_input.pt
   - Line 3, Column 8
   - Expression: <PythonExpr (view.key_widgets[repeat['widget'].index()])>
   - Names:
      {'args': (),
       'context': <RecordsProxy for collective.contact.plonegroup.browser.settings.IContactPlonegroupConfig>,
       'default': <object object at 0x7f71623bcc10>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': {},
       'request': <HTTPRequest, URL=http://localhost:8089/troisponts/@@contact-plonegroup-settings>,
       'template': <zope.browserpage.viewpagetemplatefile.ViewPageTemplateFile object at 0x7f714af497d0>,
       'view': <DataGridField 'form.widgets.functions'>,
       'views': <zope.browserpage.viewpagetemplatefile.ViewMapper object at 0x7f71418d0950>}
  Module zope.tales.pythonexpr, line 59, in __call__
   - __traceback_info__: (view.key_widgets[repeat['widget'].index()])
  Module <string>, line 1, in <module>
IndexError: list index out of range

Same form is working on a new site...

Issues using a RelationChoice in a datagrid row

When a RelationChoice is added directly into a dexterity type the value is converted to a RelationValue prior to being saved into the database.

When a RelationChoice is added into a data grid row, the value is stored as the object that was selected but Plone has issues re-loading this object from a cold-start when Plone restarts.

I was able to resolve this by implementing this datagrid converter into my project, you may be able to think of a more elegant way to implement this directly into the datagrid

I will try to create a unit test for this soon which shows the issue in comparison between a regular content type's fields and when this field is inside of a data grid.

import zope.interface
import zope.schema.interfaces
from z3c.form.converter import BaseDataConverter
from z3c.relationfield.interfaces import IRelationChoice
from z3c.relationfield import RelationValue
from zope.intid.interfaces import IIntIds
from collective.z3cform.datagridfield.interfaces import IDataGridField
from zope import component


class GridDataConverter(BaseDataConverter):
    """ The usual behaviour for a RelationChoice schema field is for the
        value to be stored as a RelationValue in the the ZODB.
        The default behaviour by the z3cform datagrid is to store the item
        as-is.
        As a result a strange bug occurs where the value is saved as an object.
        When a cold-start occurs however, the item can not be loaded again as
        object's can directly be stored on a RelationChoice

        What we've done is converted the RelationChoice schema fields into
        RelationValue objects prior to persisting it into ZODB.
    """
    zope.component.adapts(zope.schema.interfaces.IList, IDataGridField)

    def toWidgetValue(self, value):
        for row in value:
            for key in row:
                if IRelationChoice.providedBy(self.field.value_type.schema[key]):
                    row[key] = row[key].to_object
        return value

    def toFieldValue(self, value):
        intids = component.queryUtility(IIntIds)
        for row in value:
            for key in row:
                if IRelationChoice.providedBy(self.field.value_type.schema[key]):
                    row[key] = RelationValue(intids.getId(row[key]))
        return value

Release 1.3.0.post1 and PyPI

Last year there was a release 1.3.0.
A couple of weeks ago there was 1.3.0.post1, which contains a lot of changes for a 'post' release.
I don't see it on PyPI either, and maybe a post release cannot be uploaded there, not sure.

Can we have a new release? I guess it should be 1.4.0.

Is it possible to upload images using NamedBlobImage in a data grid?

Is it possible to upload images into a data grid?

I'm getting this backtrace when I try

Traceback (innermost last):
Module ZPublisher.Publish, line 138, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 48, in call_object
Module plone.z3cform.layout, line 66, in call
Module plone.z3cform.layout, line 60, in update
Module z3c.form.form, line 158, in render
Module zope.browserpage.viewpagetemplatefile, line 51, in call
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 93, in call
Module z3c.pt.pagetemplate, line 149, in render
Module chameleon.zpt.template, line 258, in render
Module chameleon.template, line 170, in render
Module 2ba401494e66754dd01a4fa28c80e723.py, line 91, in render
Module dcee88d0c7d8c247e5bc3e6ec19f29a2.py, line 1808, in render_titlelessform
Module dcee88d0c7d8c247e5bc3e6ec19f29a2.py, line 451, in render_fields
Module dcee88d0c7d8c247e5bc3e6ec19f29a2.py, line 126, in render_widget_rendering
Module dcee88d0c7d8c247e5bc3e6ec19f29a2.py, line 1077, in render_field
Module five.pt.expressions, line 161, in call
Module Products.Five.browser.metaconfigure, line 479, in call
Module zope.browserpage.viewpagetemplatefile, line 83, in call
Module zope.browserpage.viewpagetemplatefile, line 51, in call
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 93, in call
Module z3c.pt.pagetemplate, line 149, in render
Module chameleon.zpt.template, line 258, in render
Module chameleon.template, line 170, in render
Module 237f5faa9981a2568a3a7717871fd934.py, line 590, in render
Module 237f5faa9981a2568a3a7717871fd934.py, line 465, in render_widget_wrapper
Module five.pt.expressions, line 161, in call
Module z3c.form.widget, line 153, in render
Module zope.browserpage.viewpagetemplatefile, line 51, in call
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 93, in call
Module z3c.pt.pagetemplate, line 149, in render
Module chameleon.zpt.template, line 258, in render
Module chameleon.template, line 170, in render
Module 7ba056c4d0306e53b2d20fb81f62142a.py, line 981, in render
Module 7ba056c4d0306e53b2d20fb81f62142a.py, line 820, in render_widget_row
Module five.pt.expressions, line 161, in call
Module z3c.form.object, line 310, in render
Module z3c.form.widget, line 153, in render
Module zope.browserpage.viewpagetemplatefile, line 51, in call
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 93, in call
Module z3c.pt.pagetemplate, line 149, in render
Module chameleon.zpt.template, line 258, in render
Module chameleon.template, line 170, in render
Module 642e3a9d917c5effeed974bd252be034.py, line 457, in render
Module five.pt.expressions, line 161, in call
Module z3c.form.widget, line 153, in render
Module zope.browserpage.viewpagetemplatefile, line 51, in call
Module zope.pagetemplate.pagetemplate, line 132, in pt_render
Module five.pt.engine, line 93, in call
Module z3c.pt.pagetemplate, line 149, in render
Module chameleon.zpt.template, line 258, in render
Module chameleon.template, line 188, in render
Module chameleon.template, line 170, in render
Module dbbbcbb6b82fef5f3fbfc72a1cb7fd26.py, line 163, in render
Module five.pt.expressions, line 154, in call
Module five.pt.expressions, line 126, in traverse
Module zope.traversing.adapters, line 136, in traversePathElement

  • traceback_info: (<NamedImageWidget 'form.widgets.images.0.widgets.image'>, 'file_icon')
    Module zope.traversing.adapters, line 50, in traverse
  • traceback_info: (<NamedImageWidget 'form.widgets.images.0.widgets.image'>, 'file_icon', ())
    LocationError: (<NamedImageWidget 'form.widgets.images.0.widgets.image'>, 'file_icon')
    • Expression: "widget/@@ploneform-render-widget"
    • Filename: ... rm-0.7.6-py2.7.egg/plone/app/z3cform/templates/macros.pt
    • Location: (line 97: col 81)
    • Source: ... place="structure widget/@@ploneform-render-widget"/>
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    • Expression: "view/file_icon"
    • Filename: ... .0.9-py2.7.egg/plone/formwidget/namedfile/image_input.pt
    • Location: (line 30: col 15)
    • Source: icon view/file_icon;">
      ^
    • Arguments: repeat: {...} (0)
      context: {...} (2)
      exists: True
      views: <ViewMapper - at 0x9cb6410>
      modules: <TraversableModuleImporter - at 0x3ca6790>
      args: <tuple - at 0x7f08a393b050>
      nothing: <NoneType - at 0x8593c0>
      target_language: <NoneType - at 0x8593c0>
      doc_type: JPEG image
      allow_nochange: True
      default: <object - at 0x7f08a38a74f0>
      request: <instance - at 0x7f08954f30e0>
      wrapped_repeat: {...} (0)
      download_url: http://127.0.0.1:8080/Site/foo/@@edit/++widget++f...
      filename: foo.jpg
      loop: {...} (0)
      template: <ViewPageTemplateFile - at 0x8a96450>
      action: nochange
      translate: <function translate at 0x7f088c458ed8>
      options: {...} (0)
      view: <NamedImageWidget image at 0x91a1710>

Multiple lines auto added when more than one datagrid present

May or may not be related to #82. I am on version 1.5.2, Plone 5.2, python 3. I am getting multiple rows added when auto completing the first row when I have multiple fields that use a datagrid widget. If it matters, I do see in the network tab that init_field.js is called again for each field that uses this widget.

I have tested with both 1.5.1 and 1.5.2 in Plone 5.2 and got the same behavior. Previously in Plone 5.1 we were on DGF version 1.3.0 and did NOT have the problem.

Not possible to add description to column

Hi @jensens @thet @tomgross

is is not possible to add a description to a column header (under title) like it was the case with Products.DataGridField.

I would like to add this (nothing changed if not description provided on field), is that OK? If so I will propose a PR...

Thank you!

Gauthier

datagridfield.js is not served

...unless I switch the resource registry to development mode. I'm testing with Plone 5.0.4 (yeah I know) and the master branch checkout of this repo, so 1.3.0.dev0.

Looks like #62 addresses this.

BlockDataGridFieldFactory - Date Widget - Error

In datagridfieldobject_input_block.pt:

<div tal:attributes="class python:'datagridwidget-block-' + widget.id + ' ' + widget.klass + ' datagridwidget-widget-' + widget.field.__name__ + ' ' + (widget.mode == 'hidden' and 'datagridwidget-hidden-data' or 'datagridwidget-block')">

Using schema.Data produces the following traceback: http://pastie.org/9939833#54,64
TypeError: cannot concatenate 'str' and 'NoneType' objects

  • Expression: "widget/@@ploneform-render-widget"
  • Filename: ... form-1.0-py2.7.egg/plone/app/z3cform/templates/macros.pt
  • Location: (98:81)
  • Source: ... place="structure widget/@@ploneform-render-widget"/>
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  • Expression: "python:'datagridwidget-block-' + widget.id + ' ' + widget.klass + ' datagridwidget-widget-' + widget.field.name + ' ' + (widget.mode == 'hidden' and 'datagridwidget-hidden-data' or 'datagridwidget-block')"
  • Filename: ... z3cform/datagridfield/datagridfieldobject_input_block.pt
  • Location: (11:39)
  • Source: ... python:'datagridwidget-block-' + widget.id + ' ' + widget.klass + ' datagridwidget-widget-' + widget.field.name + ' ' + (widget.mode == 'hidden' and 'datagridwidget-hidden-data' or 'datagridwidget-block') ...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  • Arguments: widget: <DateWidget date at 0x108506d50>
    repeat: {...} (0)
    context: <NoneType - at 0x1017b47d8>
    views: <ViewMapper - at 0x1091a6610>
    modules: <TraversableModuleImporter - at 0x103807550>
    args: <tuple - at 0x10184c050>
    nothing: <NoneType - at 0x1017b47d8>
    target_language: <NoneType - at 0x1017b47d8>
    default: <object - at 0x1018a2bc0>
    request: <instance - at 0x1068dcb00>
    wrapped_repeat: {...} (1)
    loop: {...} (1)
    template: <ViewPageTemplateFile - at 0x107f62790>
    translate: <function translate at 0x10829b488>
    options: {...} (0)
    view: <BlockDataGridFieldObject None at 0x1085068d0>

After release, Travis CI bin/buidout started bark

Hi @jaroel ,

After I made 0.13 release, looks like Travis CI is failing in bin/buildout related to pindowns

Getting distribution for 'collective.z3cform.datagridfield[test]==0.13.dev0'.

While:

Installing test.

Getting distribution for 'collective.z3cform.datagridfield[test]==0.13.dev0'.

Error: Couldn't find a distribution for 'collective.z3cform.datagridfield[test]==0.13.dev0'.

Do you know if there are any post-release actions needed to perform in order to make buildout happy again?

Demo visibility?

After I ungroked the demo code and moved it over here: Shall we enable the views always or shall we have a "switch" when to show?

If a switch is needed, what to choose? Permission? zcml condition? Only showing up in debug mode? Own GenericSetup Demo profile?

Opinions?

plone 5 release

The code has been updated to be compatible for plone 5. can a release be done?

Cannot open addform anymore

Since the newest commit 87ef06a I cannot open the addform anymore (it did work with 82a3eaa).
@jensens any idea what went wrong?
What is the intention of the commit 87ef06a ?

I'm using Plone 4.3.11 and I'm getting this traceback:

b2017-03-22 09:34:53 ERROR Zope.SiteErrorLog 1490171693.840.254497882331 http://localhost:8080/Plone/++add++ftw.book.Table
Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module plone.z3cform.layout, line 66, in __call__
  Module plone.z3cform.layout, line 50, in update
  Module plone.dexterity.browser.add, line 118, in update
  Module plone.z3cform.fieldsets.extensible, line 59, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 141, in update
  Module z3c.form.group, line 52, in update
  Module z3c.form.group, line 48, in updateWidgets
  Module z3c.form.field, line 277, in update
  Module z3c.form.browser.multi, line 63, in update
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.widget, line 496, in update
  Module z3c.form.widget, line 132, in update
  Module z3c.form.widget, line 491, in value
  Module collective.z3cform.datagridfield.datagridfield, line 170, in updateWidgets
  Module z3c.form.widget, line 432, in updateWidgets
  Module collective.z3cform.datagridfield.datagridfield, line 148, in getWidget
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.object, line 217, in update
  Module collective.z3cform.datagridfield.datagridfield, line 310, in updateWidgets
  Module z3c.form.util, line 259, in __getitem__
KeyError: 'columnId'

no bind during DictRow validation

https://github.com/collective/collective.z3cform.datagridfield/blob/master/collective/z3cform/datagridfield/row.py#L43

should be something like

        # Pass 2 - Ensure fields are valid
        for field_name, field_type in getFields(self.schema).items():
            if IChoice.providedBy(field_type):
                # Choice must be bound before validation otherwise
                # IContextSourceBinder is not iterable in validation
                bound = field_type.bind(value)
                bound.validate(value[field_name])
            else:
                field_type.validate(value[field_name])

Are Javascript events working

As explained in the readme, I have tried to use javascripts events but it doesn't work.
The showed example isn't working.
No trace in the code of the mentionned events: beforeaddrow, ...
Are the jquery events yet fired ?

error on 1.3.0 in Plone 5.1.4

This traceback looks very similar to others I've seen trying to use 1.3.0 on Plone 4, but this is in 5.1.4

Traceback (innermost last):

    Module ZPublisher.Publish, line 138, in publish
    Module ZPublisher.mapply, line 77, in mapply
    Module ZPublisher.Publish, line 48, in call_object
    Module z3c.form.form, line 239, in __call__
    Module z3c.form.form, line 162, in render
    Module Products.Five.browser.pagetemplatefile, line 59, in __call__
    Module zope.pagetemplate.pagetemplate, line 137, in pt_render
    Module five.pt.engine, line 98, in __call__
    Module z3c.pt.pagetemplate, line 163, in render
    Module chameleon.zpt.template, line 261, in render
    Module chameleon.template, line 171, in render
    Module 80465792d4dbd702d97982407c9f95e7.py, line 164, in render
    Module bd6a60b949785866ffe5207e0f34580e.py, line 1223, in render_master
    Module bd6a60b949785866ffe5207e0f34580e.py, line 458, in render_content
    Module 80465792d4dbd702d97982407c9f95e7.py, line 150, in __fill_main
    Module 6908f1bf9f2b59178f1173bc239232de.py, line 1826, in render_titlelessform
    Module 6908f1bf9f2b59178f1173bc239232de.py, line 451, in render_fields
    Module 6908f1bf9f2b59178f1173bc239232de.py, line 126, in render_widget_rendering
    Module 6908f1bf9f2b59178f1173bc239232de.py, line 1069, in render_field
    Module five.pt.expressions, line 161, in __call__
    Module Products.Five.browser.metaconfigure, line 485, in __call__
    Module zope.browserpage.viewpagetemplatefile, line 81, in __call__
    Module zope.browserpage.viewpagetemplatefile, line 49, in __call__
    Module zope.pagetemplate.pagetemplate, line 137, in pt_render
    Module five.pt.engine, line 98, in __call__
    Module z3c.pt.pagetemplate, line 163, in render
    Module chameleon.zpt.template, line 261, in render
    Module chameleon.template, line 171, in render
    Module 83eaf31cf4216f9f27bbe06c55202b5f.py, line 610, in render
    Module 83eaf31cf4216f9f27bbe06c55202b5f.py, line 481, in render_widget_wrapper
    Module five.pt.expressions, line 161, in __call__
    Module z3c.form.widget, line 154, in render
    Module zope.browserpage.viewpagetemplatefile, line 49, in __call__
    Module zope.pagetemplate.pagetemplate, line 137, in pt_render
    Module five.pt.engine, line 98, in __call__
    Module z3c.pt.pagetemplate, line 163, in render
    Module chameleon.zpt.template, line 261, in render
    Module chameleon.template, line 191, in render
    Module chameleon.template, line 171, in render
    Module 656ddca223e98e23967a8b98d0ee948f.py, line 984, in render
    Module 656ddca223e98e23967a8b98d0ee948f.py, line 139, in render_widget_row

IndexError: list index out of range

 - Expression: "widget/@@ploneform-render-widget"
 - Filename:   ... rm-3.0.6-py2.7.egg\plone\app\z3cform\templates\macros.pt
 - Location:   (line 100: col 81)
 - Source:     ... place="structure widget/@@ploneform-render-widget"/>
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Expression: "python:view.key_widgets[repeat['widget'].index()]"
 - Filename:   ... 0.6-py2.7.egg\plone\app\z3cform\templates\multi_input.pt
 - Location:   (line 7: col 33)
 - Source:     ... y_widget python:view.key_widgets[repeat['widget'].index()];
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Arguments:  widget: <DataGridFieldObject None at 0x118acda0L>
               repeat: {...} (0)
               context: <ImplicitAcquisitionWrapper sagan-carl at 0x9f8fc60L>
               views: <ViewMapper - at 0x1a23d438L>
               modules: <TraversableModuleImporter - at 0x274ba20L>
               args: <tuple - at 0x1e10048L>
               nothing: <NoneType - at 0x5395ac58L>
               target_language: <NoneType - at 0x5395ac58L>
               default: <object - at 0x1eb4b40L>
               request: <instance - at 0x1a03e188L>
               wrapped_repeat: {...} (1)
               loop: {...} (1)
               template: <ViewPageTemplateFile - at 0x18fed048L>
               translate: <function translate at 0x18c63dd8L>
               options: {...} (0)
               view: <DataGridField phones at 0x118ac940L>

Code snippets

class IPhoneSchema(model.Schema):
    phonetype = schema.Choice(
        title=_(u"Phone Type"),
        required=False,
        vocabulary=phone_options,
    )
    phonenum = schema.TextLine(title=_(u"Phone Number"), required=False)
IContact(model.Schema):
...
directives.widget(phones=DataGridFieldFactory)
    phones = schema.List(
        title=_(u"Phone Numbers"),
        value_type=DictRow(title=_(u"Phone number"), schema=IPhoneSchema),
        required=False,
    )

collective.z3cform.datagridfield 1.1 works fine.
plone.app.z3form = 3.0.6 (via http://dist.plone.org/release/5.1.4/versions.cfg)
Any other versions I can list that might give insight?

I'd really like to upgrade because this is the only package I currently have forcing grok as a dependency.

New release?

Dependency on five.grok is already removed on the master branch; is there any reason we haven't released 1.3 yet?

Broken with z3c.form > 3.3

ObjectSubForm and SubformAdapter have been removed in z3c.form so datagridfield is no more working on latest versions of z3c.form.

I don't know if it will be possible and how to fix

auto_append and empty grid

if rendering an empty datagrid and widget auto_append flag is set to false, it's not possible to add entries (no + icon at all)

cheers

p.a.registry import broken

hi,

when exporting registry via GS and reimporting the result, following error occurs

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module Products.GenericSetup.tool, line 565, in manage_importTarball
  Module Products.GenericSetup.tool, line 350, in runAllImportStepsFromProfile
  Module Products.GenericSetup.tool, line 1100, in _runImportStepsFromContext
  Module Products.GenericSetup.tool, line 1015, in _doRunImportStep
   - __traceback_info__: plone.app.registry
  Module plone.app.registry.exportimport.handler, line 49, in importRegistry
  Module plone.app.registry.exportimport.handler, line 92, in importDocument
  Module plone.app.registry.exportimport.handler, line 218, in importRecord
  Module plone.supermodel.utils, line 112, in elementToValue
  Module plone.supermodel.utils, line 123, in elementToValue
TypeError: ('Could not adapt', None, <InterfaceClass zope.schema._bootstrapinterfaces.IFromUnicode>)

exported XML looks like:

<record name="bda.plone.shop.interfaces.INotificationTextSettings.order_text" interface="bda.plone.shop.interfaces.INotificationTextSettings" field="order_text">
    <field type="plone.registry.field.List">
      <title>label_order_notification_text</title>
    </field>
    <value>
      <element>{'lang': 'de', 'text': u'lkj\xf6\xe4'}</element>
    </value>
</record>

Form schema is defined here - https://github.com/bluedynamics/bda.plone.shop/blob/master/src/bda/plone/shop/interfaces.py#L282

cheers

cross-database reference issue with collective.z3cform.datagridfield.registry.DictRow

I tried to use DictRow to set a registry record in on eof my packages. Worked great when I installed the package on the first site, but got the following error when I tried to install the same package on a different site that's on a different database (different ZODB mount points on the same "buildout")

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 161, in transaction_pubevents
  Module transaction._manager, line 252, in commit
  Module transaction._manager, line 131, in commit
  Module transaction._transaction, line 311, in commit
  Module transaction._compat, line 50, in reraise
  Module transaction._transaction, line 302, in commit
  Module transaction._transaction, line 447, in _commitResources
  Module transaction._compat, line 50, in reraise
  Module transaction._transaction, line 421, in _commitResources
  Module ZODB.Connection, line 497, in commit
  Module ZODB.Connection, line 546, in _commit
  Module ZODB.Connection, line 578, in _store_objects
  Module ZODB.serialize, line 430, in serialize
  Module ZODB.serialize, line 439, in _dump
  Module ZODB.serialize, line 348, in persistent_id
ZODB.POSException.InvalidObjectReference: ("Database 'db11' doesn't allow implicit cross-database references", <Connection at 7f0698393748>, <collective.z3cform.datagridfield.registry.DictRow object at 0x7f063c96a048 oid 0x433a43 in <Connection at `7f069a60ee80>>)

Unknown directive widgetTemplate

I ran the included buildout without issues but when I start the instance I get this error. This happens with both Python 3.7 and 2.7. I looked at the docs for the widgetTemplate directive and the ZCML looks correct...

$ instance fg
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/starter.py:202: DeprecationWarning: set_default_debug_mode is deprecated. Please import from ZServer.ZPublisher.Publish.
  ZPublisher.Publish.set_default_debug_mode(self.cfg.debug_mode)
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/starter.py:203: DeprecationWarning: set_default_authentication_realm is deprecated. Please import from ZServer.ZPublisher.Publish.
  ZPublisher.Publish.set_default_authentication_realm(
2019-12-16 20:24:40 INFO ZServer HTTP server started at Mon Dec 16 20:24:40 2019
        Hostname: 0.0.0.0
        Port: 8080
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Products.CMFUid-3.0.1-py2.7.egg/Products/CMFUid/UniqueIdHandlerTool.py:24: DeprecationWarning: InitializeClass is deprecated. Please import from AccessControl.class_init.
  from App.class_init import InitializeClass
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Products.CMFEditions-3.3.2-py2.7.egg/Products/CMFEditions/StandardModifiers.py:46: DeprecationWarning: ComponentLookupError is deprecated. Import from zope.interface.interfaces
  from zope.component.interfaces import ComponentLookupError
2019-12-16 20:24:43 WARNING Init Class Products.CMFFormController.ControllerPythonScript.ControllerPythonScript has a security declaration for nonexistent method 'ZPythonScriptHTML_changePrefs'
2019-12-16 20:24:43 WARNING Init Class Products.CMFFormController.ControllerValidator.ControllerValidator has a security declaration for nonexistent method 'ZPythonScriptHTML_changePrefs'
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Products.CMFPlacefulWorkflow-2.0.0-py2.7.egg/Products/CMFPlacefulWorkflow/permissions.py:5: DeprecationWarning: setDefaultRoles is deprecated. Please use addPermission from AccessControl.Permission.
  from Products.CMFCore.permissions import setDefaultRoles
2019-12-16 20:24:43 WARNING ZODB.FileStorage Ignoring index for /Users/kimnguyen/src/collective.z3cform.datagridfield/var/filestorage/Data.fs
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/plone.app.upgrade-2.0.27-py2.7.egg/plone/app/upgrade/__init__.py:167: DeprecationWarning: LockItem is deprecated. Please import from OFS.LockItem.
  from webdav.LockItem import LockItem
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/plone.subrequest-1.9.1-py2.7.egg/plone/subrequest/__init__.py:18: DeprecationWarning: zope.site.hooks has moved to zope.component.hooks. Import of zope.site.hooks will become unsupported in Version 5.0
  from zope.site.hooks import getSite
/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/z3c.caching-2.1-py2.7.egg/z3c/caching/interfaces.py:2: DeprecationWarning: IObjectEvent is deprecated. Import from zope.interface.interfaces
  from zope.component.interfaces import IObjectEvent
Traceback (most recent call last):
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/parts/instance/bin/interpreter", line 284, in <module>
    exec(compile(__file__f.read(), __file__, "exec"))
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/run.py", line 64, in <module>
    run()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/run.py", line 25, in run
    starter.prepare()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/starter.py", line 84, in prepare
    self.startZope()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/Startup/starter.py", line 313, in startZope
    ZServer.Zope2.startup()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/ZServer-4.0.1-py2.7.egg/ZServer/Zope2/__init__.py", line 32, in startup
    _startup()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Zope-4.1.1-py2.7.egg/Zope2/App/startup.py", line 143, in startup
    load_zcml()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Zope-4.1.1-py2.7.egg/Zope2/App/startup.py", line 58, in load_zcml
    load_site()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/Zope-4.1.1-py2.7.egg/Zope2/App/zcml.py", line 45, in load_site
    _context = xmlconfig.file(site_zcml)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 657, in file
    include(context, name, package)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 557, in include
    processxmlfile(f, context)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 407, in processxmlfile
    parser.parse(src)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 110, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 213, in feed
    self._parser.Parse(data, isFinal)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 365, in end_element_ns
    self._cont_handler.endElementNS(pair, None)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 393, in endElementNS
    self._handle_exception(ex, info)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 391, in endElementNS
    self.context.end()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 703, in end
    self.stack.pop().finish()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 868, in finish
    actions = self.handler(context, **args)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 557, in include
    processxmlfile(f, context)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 407, in processxmlfile
    parser.parse(src)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 110, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 213, in feed
    self._parser.Parse(data, isFinal)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 365, in end_element_ns
    self._cont_handler.endElementNS(pair, None)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 393, in endElementNS
    self._handle_exception(ex, info)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 391, in endElementNS
    self.context.end()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 703, in end
    self.stack.pop().finish()
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 868, in finish
    actions = self.handler(context, **args)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 557, in include
    processxmlfile(f, context)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 407, in processxmlfile
    parser.parse(src)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 110, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 213, in feed
    self._parser.Parse(data, isFinal)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/expatreader.py", line 354, in start_element_ns
    AttributesNSImpl(newattrs, qnames))
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 268, in startElementNS
    self._handle_exception(ex, info)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/xmlconfig.py", line 266, in startElementNS
    self.context.begin(name, data, info)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 700, in begin
    self.stack.append(self.stack[-1].contained(__name, __data, __info))
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 1070, in contained
    return RootStackItem.contained(self, name, data, info)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 891, in contained
    factory = self.context.factory(self.context, name)
  File "/Users/kimnguyen/src/collective.z3cform.datagridfield/eggs/zope.configuration-4.3.1-py2.7.egg/zope/configuration/config.py", line 630, in factory
    raise ConfigurationError("Unknown directive", ns, n)
zope.configuration.exceptions.ConfigurationError: ('Unknown directive', u'http://namespaces.zope.org/z3c', u'widgetTemplate')
    File "/Users/kimnguyen/src/collective.z3cform.datagridfield/parts/instance/etc/site.zcml", line 15.2-15.55
    File "/Users/kimnguyen/src/collective.z3cform.datagridfield/parts/instance/etc/package-includes/002-collective.z3cform.datagridfield-configure.zcml", line 1.0-1.76
    File "/Users/kimnguyen/src/collective.z3cform.datagridfield/src/collective/z3cform/datagridfield/configure.zcml", line 49.2

Context is not present in vocabulary factory

I have the following content type using a datagridfield. I want to use a dynamic vocabulary to compute values for a Choice field

class ITableRowSchema(form.Schema):
    attachment = schema.Choice(
        title=u"File (download)",
        source="local_files",
    )

class IMyContent(model.Schema):
    files = schema.List(
        title=u"Related files",
        value_type=DictRow(
            title=u"tablerow",
            schema=ITableRowSchema,),
    )
    form.widget(files=DataGridFieldFactory)

And the vocabulary factory:

@implementer(IVocabularyFactory)
class LocalFilesVocabulary(object):

    def __call__(self, context):
        ...

The problem is that context is NO_VALUE (<class 'z3c.form.interfaces.NO_VALUE'>), so I can't do creative things using my local context. If I put the same field directly into the my IMyContent schema, the context is the object on which the field gets called.

The answer to http://stackoverflow.com/questions/6623921/vocabulary-source-function-is-not-iterable-with-dexterity-in-plone-4-1 says: "I am not familiar enough with the datagrid widget setup to pinpoint where this goes wrong, but it appears that it generates widgets on-the-fly and I suspect it doesn't bind the fields for these correctly."
I spent some time in the debugger trying to find out where that might have to be done. I tried to be a smart-aleck with this hack:

def DataGridFieldFactory(field, request):
    """IFieldWidget factory for DataGridField."""
    bound = field.bind(request['PARENTS'][0])
    return FieldWidget(bound, DataGridField(request))

But still, the same result. And to quote Mikko from #2: "...does special things deep down with z3c.form. It's a place where nobody wants to go." Indeed!

Before I give this up as a lost case: did anybody already have the same issue and maybe found a solution for it?

Pickling error when auto_append = False

Using this awesome widget in a form. I want to disable the auto_append feature. I followed the instructions in the README file and used the form's updateWidgets() function to set the widget's auto_append = False.

If I fill out the data with a single row (i.e., DO NOT add or subtract), and I get an error:
[...]
PicklingError: Can't pickle <class 'z3c.form.interfaces.NO_VALUE'>: it's not the same object as z3c.form.interfaces.NO_VALUE

This occurs because when rendering the HTML for the widget, two rows are made: the input row and the template for the next added row (the 'TT' row). But the hidden count variable is set to 2 instead of 1 and this causes (I'm guessing) the NO_VALUE problem. Interestingly, if I add a row, then subtract it, the count goes down to 1 and the form submits correctly. I guess the JS logic fixes the problem in this case.

Debugging a bit, it seems that the function datagridfield.DataGridField.updateWidgets() will always add the "AA" and "TT" widgets because this is run before auto_append can be set to False (it is run as part of the super class' updateWidgets()). So there are always at least 3 widgets. But in the page template for the widget (datagridfield_input.pt) there is a conditional that will prevent the 'AA' widget from rendering if auto_append is False (which it is by the time the page template is rendered). So there's a timing with when self.auto_append is accessed giving inconsistent values.

I fixed the issue for this specific case by simply hacking datagridfield.py and hard-coding the default auto_append=False so everything is consistent from the get-go. But that's not a good solution. Not sure what is.

Cleaning up extra .cfg files

Hi @jaroel ,

Could it be possible remove extra .cfg files from collective.z3cform.datagridfild root?

Also for files, which are still needed, add a comment at the beginning of the file why it is needed and what it is used for.

I am not sure anymore which are relevant and which not :(

NamedImage and NamedFile widgets do not retain content when modified

Description

I have the following content type type defined:

class IImageRow(interface.Interface):
    home_image = NamedImage(
        title=_(u"Image"),
        required=False,
    )
    url = schema.TextLine(title=_(u'URL'), 
                             required=False)

class IMyContent(form.Schema):
    """My content type
    """
    form.widget(gallery=DataGridFieldFactory)
    gallery= schema.List(
            title=_(u"A simple gallery of images"),
            value_type=DictRow(schema=IImageRow),
            required=True,
        )

    (...)

I can load and store a datagrid of images, but when I edit the content and save it, asking to "Keep the existing image", the reference to the image is not kept. The "url" is kept however.

Steps to reproduce

Actions

  1. Define a datagridfield of NamedImages in code
  2. Add the content in the site
  3. Upload some images in the datagrid
  4. Edit the content again
  5. Save the content, keeping the existing images

Outcome

  • The stored images are lost

Expected result

  • The stored images should be kept

Getting a datetime widget error for BlockDataGridFieldFactory

In the example, IAdress is defined as:

class IAddress(form.Schema):
    address_type = schema.Choice(
        title=u'Address Type', required=True,
        values=[u'Work', u'Home'])
    # A Relation field within a datagrid is a tricky one to get
    # working.  Uncomment if you want to try this.
    # link = RelationChoice(
    #         title=u"Link to content",
    #         source=ObjPathSourceBinder(),
    #         required=True)
    line1 = schema.TextLine(
        title=u'Line 1', required=True)
    line2 = schema.TextLine(
        title=u'Line 2', required=False)
    city = schema.TextLine(
        title=u'City / Town', required=True)
    country = schema.TextLine(
        title=u'Country', required=True)

    # A sample integer field
    personCount = schema.Int(title=u'Persons', required=False, min=0, max=15)

    # A sample datetime field
    form.widget(dateAdded=DataGridFieldDatetimeFieldWidget)
    dateAdded = schema.Datetime(title=u"Date added")

    # A sample checkbox
    billed = schema.Bool(title=u"Billed")

and the create form is:

class EditForm9(EditForm):

    label = u'Block widgets as blocks instead of cells'

    # Because we modify fields in-place in update()
    # We need our own copy so that we don't damage other forms
    fields = field.Fields(IAddress) # I changed it to IAddress for example sake.

    grok.name('demo-collective.z3cform.datagrid-block-edit')

    def update(self):
        # Set a custom widget for a field for this form instance only
        self.fields["added"]
        self.fields['address'].widgetFactory = BlockDataGridFieldFactory
        super(EditForm9, self).update()

This is the error that was returned

TypeError: cannot concatenate 'str' and 'NoneType' objects

 - Expression: "widget/@@ploneform-render-widget"
 - Filename:   ... rm-1.1.5-py2.7.egg/plone/app/z3cform/templates/macros.pt
 - Location:   (line 98: col 81)
 - Source:     ... place="structure widget/@@ploneform-render-widget"/>
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Expression: "python:'datagridwidget-block-' + widget.id + ' ' + widget.klass + ' datagridwidget-widget-' + widget.field.__name__ + ' ' + (widget.mode == 'hidden' and 'datagridwidget-hidden-data' or 'datagridwidget-block')"
 - Filename:   ... z3cform/datagridfield/datagridfieldobject_input_block.pt
 - Location:   (line 11: col 39)
 - Source:     ... python:'datagridwidget-block-' + widget.id + ' ' + widget.klass + ' datagridwidget-widget-' + widget.field.__name__ + ' ' + (widget.mode == 'hidden' and 'datagridwidget-hidden-data' or 'datagridwidget-block') ...
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 - Arguments:  widget: <DatetimeWidget expire_on at 0x7f211bfb47d0>
               repeat: {...} (0)
               context: <NoneType - at 0x91a870>
               views: <ViewMapper - at 0x7f211d3e1990>
               modules: <TraversableModuleImporter - at 0x7f212539a190>
               args: <tuple - at 0x7f212cd61050>
               nothing: <NoneType - at 0x91a870>
               target_language: <NoneType - at 0x91a870>
               default: <object - at 0x7f212cc81500>
               request: <instance - at 0x7f211e1ff560>
               wrapped_repeat: {...} (1)
               loop: {...} (1)
               template: <ViewPageTemplateFile - at 0x7f211d9b1e10>
               translate: <function translate at 0x7f211b6bed70>
               options: {...} (0)
               view: <BlockDataGridFieldObject None at 0x7f211bfb4790>

Any ideas on how to resolve this?

Display mode template breaks if you have checkbox content which is not yet filled in (NOVALUE)

Release 0.13, collective.z3cform.datagridfield_demos, click Table and cells are read-only

  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module Products.PageTemplates.Expressions, line 218, in evaluateStructure
  Module zope.tales.tales, line 696, in evaluate
   - URL: /Users/mikko/code/buildout-cache/eggs/plone.app.z3cform-0.5.8-py2.7.egg/plone/app/z3cform/templates/macros.pt
   - Line 94, Column 46
   - Expression: <PathExpr standard:u'widget/@@ploneform-render-widget'>
   - Names:
      {'args': (),
       'container': <PloneSite at /folder_xxx/xxxngta>,
       'context': <PloneSite at /folder_xxx/xxxngta>,
       'default': <object object at 0x10ea71b20>,
       'here': <PloneSite at /folder_xxx/xxxngta>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x119551368>,
       'request': <HTTPRequest, URL=http://localhost:8080/folder_xxx/xxxngta/demo-collective.z3cform.datagrid-block-edit-display-mode>,
       'root': <Application at >,
       'static': None,
       'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x119896790>,
       'traverse_subpath': [],
       'user': <PropertiedUser 'admin2'>,
       'view': <Products.Five.metaclass.EditForm10 object at 0x11259fb10>,
       'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x11259ff10>}
  Module zope.tales.expressions, line 217, in __call__
  Module Products.PageTemplates.Expressions, line 155, in _eval
  Module Products.PageTemplates.Expressions, line 117, in render
  Module Products.Five.browser.metaconfigure, line 476, in __call__
  Module zope.browserpage.viewpagetemplatefile, line 83, in __call__
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 113, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 531, in do_optTag_tal
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module zope.tales.tales, line 696, in evaluate
   - URL: /Users/mikko/code/buildout-cache/eggs/plone.app.z3cform-0.5.8-py2.7.egg/plone/app/z3cform/templates/widget.pt
   - Line 36, Column 4
   - Expression: <PathExpr standard:u'widget/render'>
   - Names:
      {'args': (),
       'context': <MultiWidget 'form.widgets.address'>,
       'default': <object object at 0x10ea71b20>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': {},
       'request': <HTTPRequest, URL=http://localhost:8080/folder_xxx/xxxngta/demo-collective.z3cform.datagrid-block-edit-display-mode>,
       'template': <zope.browserpage.viewpagetemplatefile.ViewPageTemplateFile object at 0x112f72850>,
       'view': <Products.Five.metaclass.RenderWidget object at 0x124f9b4d0>,
       'views': <zope.browserpage.viewpagetemplatefile.ViewMapper object at 0x124f9b490>}
  Module zope.tales.expressions, line 217, in __call__
  Module zope.tales.expressions, line 211, in _eval
  Module z3c.form.widget, line 141, in render
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 113, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 531, in do_optTag_tal
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 821, in do_loop_tal
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 533, in do_optTag_tal
  Module zope.tal.talinterpreter, line 518, in do_optTag
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 852, in do_condition
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 858, in do_defineMacro
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 533, in do_optTag_tal
  Module zope.tal.talinterpreter, line 518, in do_optTag
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module zope.tales.tales, line 696, in evaluate
   - URL: /Users/mikko/code/buildout-cache/eggs/z3c.form-2.5.1-py2.7.egg/z3c/form/browser/multi_display.pt
   - Line 36, Column 10
   - Expression: <PathExpr standard:u'widget/render'>
   - Names:
      {'args': (),
       'context': {'address': [{'address_type': 'Work',
                                'city': 'Mega City',
                                'country': 'The Old Sod',
                                'dateAdded': datetime.datetime(1981, 8, 17, 6, 0),
                                'line1': 'My Office',
                                'line2': 'Big Office Block',
                                'personCount': 2},
                               {'address_type': 'Home',
                                'city': 'Burbs',
                                'country': 'The Old Sod',
                                'dateAdded': datetime.datetime(1981, 8, 17, 6, 0),
                                'line1': 'Home Sweet Home',
                                'line2': 'Easy Street',
                                'personCount': 4}],
                   'name': 'MY NAME'},
       'default': <object object at 0x10ea71b20>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': {},
       'request': <HTTPRequest, URL=http://localhost:8080/folder_xxx/xxxngta/demo-collective.z3cform.datagrid-block-edit-display-mode>,
       'template': <zope.browserpage.viewpagetemplatefile.ViewPageTemplateFile object at 0x112efec10>,
       'view': <MultiWidget 'form.widgets.address'>,
       'views': <zope.browserpage.viewpagetemplatefile.ViewMapper object at 0x124f9b710>}
  Module zope.tales.expressions, line 217, in __call__
  Module zope.tales.expressions, line 211, in _eval
  Module z3c.form.object, line 293, in render
  Module z3c.form.widget, line 141, in render
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 113, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 821, in do_loop_tal
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 533, in do_optTag_tal
  Module zope.tal.talinterpreter, line 518, in do_optTag
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module zope.tales.tales, line 696, in evaluate
   - URL: /Users/mikko/code/buildout-cache/eggs/z3c.form-2.5.1-py2.7.egg/z3c/form/browser/object_display.pt
   - Line 12, Column 8
   - Expression: <PathExpr standard:u'widget/render'>
   - Names:
      {'args': (),
       'context': None,
       'default': <object object at 0x10ea71b20>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': {},
       'request': <HTTPRequest, URL=http://localhost:8080/folder_xxx/xxxngta/demo-collective.z3cform.datagrid-block-edit-display-mode>,
       'template': <zope.browserpage.viewpagetemplatefile.ViewPageTemplateFile object at 0x112f18850>,
       'view': <ObjectWidget 'form.widgets.address.0'>,
       'views': <zope.browserpage.viewpagetemplatefile.ViewMapper object at 0x124f9ba10>}
  Module zope.tales.expressions, line 217, in __call__
  Module zope.tales.expressions, line 211, in _eval
  Module z3c.form.widget, line 141, in render
  Module zope.browserpage.viewpagetemplatefile, line 51, in __call__
  Module zope.pagetemplate.pagetemplate, line 113, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 531, in do_optTag_tal
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 819, in do_loop_tal
  Module zope.tales.tales, line 682, in setRepeat
  Module zope.tales.tales, line 696, in evaluate
   - URL: /Users/mikko/code/buildout-cache/eggs/z3c.form-2.5.1-py2.7.egg/z3c/form/browser/checkbox_display.pt
   - Line 19, Column 44
   - Expression: <PathExpr standard:u'view/displayValue'>
   - Names:
      {'args': (),
       'context': {'address_type': 'Work',
                   'billed': <NO_VALUE>,
                   'city': 'Mega City',
                   'country': 'The Old Sod',
                   'dateAdded': datetime.datetime(1981, 8, 17, 6, 0),
                   'line1': 'My Office',
                   'line2': 'Big Office Block',
                   'personCount': 2},
       'default': <object object at 0x10ea71b20>,
       'loop': {},
       'nothing': None,
       'options': {},
       'repeat': {},
       'request': <HTTPRequest, URL=http://localhost:8080/folder_xxx/xxxngta/demo-collective.z3cform.datagrid-block-edit-display-mode>,
       'template': <zope.browserpage.viewpagetemplatefile.ViewPageTemplateFile object at 0x112ef5f50>,
       'view': <SingleCheckBoxWidget 'form.widgets.address.0.widgets.billed'>,
       'views': <zope.browserpage.viewpagetemplatefile.ViewMapper object at 0x124f9bc50>}
  Module zope.tales.expressions, line 217, in __call__
  Module zope.tales.expressions, line 194, in _eval
  Module zope.tales.expressions, line 124, in _eval
  Module zope.pagetemplate.engine, line 66, in __call__
  Module zope.traversing.adapters, line 136, in traversePathElement
   - __traceback_info__: (<SingleCheckBoxWidget 'form.widgets.address.0.widgets.billed'>, 'displayValue')
  Module zope.traversing.adapters, line 42, in traverse
   - __traceback_info__: (<SingleCheckBoxWidget 'form.widgets.address.0.widgets.billed'>, 'displayValue', [])
  Module z3c.form.widget, line 177, in displayValue
TypeError: 'NO_VALUE' object is not iterable
2013-04-11 12:24:38 INFO Plone Debug: xxx_user

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.