DataGridField

Version 0.3

 

Description

User-fillable table component for Plone. The user interface uses JavaScript to create a dynamic table that adds rows on demand.

Purpose

A component for a need where user has to enter table / key-value pair data. For example, in CV, this could be employer, year, title table.

Features

Requirements

About tab key usage

I went to great depths to add a proper tab key support for DataGridField. Basically you should be able to move from a cell to next by pressing a tab key.

Problem 1: By default, Plone main_template gives each element fixed tab index and increases running index by one. DataGridWidget cannot dynamically add new tab indexes between indexes generated by main_template, since there is no room (tabindex must be integer).

Solution: I created a custom class StepIterator which increases tab indexes by one hundred between each input field. This required changes to main template, though. DataGridField ships with Modified Plone 2.1.2 main_template which is automatically used. If you use some other Plone versions or custom skins, you might need to override tabindex mechanism yourself. Relevant part:

tal:define="tabindex python:Iterator(pos=0);"

Change to

tal:define="tabindex python:modules['Products.DataGridField'].StepIterator(pos=0, step=100);"

There are 100 empty tab indexes between input fields. It should be enough for adding new rows dynamically (unless users adds many rows...)

Problem 2: Internet Explorer 6.0 (and probably other versions too) doesn't seem to care about dynamically added tab indexes or handles them incorrectly

Solution: No solution. Make code to degenerate gracefully for IE.

Todo

Usage examples

Simple example with three free text columns

   schema = BaseSchema + Schema((

        DataGridField('DemoField',
                widget = DataGridWidget(),
                columns=('column1','column2','The third')
                ),
        ))

Complex example with different column types and user friendly labels

# Plone imports
from Products.Archetypes.public import DisplayList
from Products.Archetypes.public import *

# Local imports
from Products.DataGridField import DataGridField, DataGridWidget
from Products.DataGridField.Column import Column
from Products.DataGridField.SelectColumn import SelectColumn

class DataGridDemoType(BaseContent):
    """A simple archetype
   
    """

    schema = BaseSchema + Schema((
        DataGridField('DemoField',
                searchable = True,
                columns=("column1", "column2", "select_sample"),
                widget = DataGridWidget(
                    columns={
                        'column1' : Column("Toholampi city rox"),
                        'column2' : Column("My friendly name"),
                        'select_sample' : SelectColumn("Friendly name", vocabulary="getSampleVocabulary")
                    },
                 ),
         ),
                
        ))

    def getSampleVocabulary(self):
        """
        """
        """ Get list of possible taggable features from ATVocabularyManager """  
        return DisplayList(
    
            (("sample", "Sample value 1",),
            ("sample2", "Sample value 2",),))
        

 

For more examples, see unit test code.

Known bugs

Quality assurance

Tested with

History

This DataGridField code was branched from PloneSolution's orignal code by Mikko Ohtamaa to add SelectColumn support. A lot of other enhancements ended up there too.

Internals

A demo type is included. Set INSTALL_DEMO_TYPES = True in config.py to enable it. It is disabled by default. This type is neither pretty, nor very functional, but demonstrates how a data grid should be used. Also, to run unit tests, you need to set this variable. I couldn't come up with a nice hack which would tell config.py whether it's imported from unit testing framework or not.

Copyright

Mikko Ohtamaa <snaapy@gmail.com>

PloneSolutions AS <info@plonesolutions.com>

Paul Everitt, Zope Europe Association

Development was helped by Vincent Bonamy

Release management and additional documentation by Martin Aspeli

Licence

GPL

Changes

For 0.3