From: Maurits v. R. <svn...@pl...> - 2009-10-31 16:30:56
|
Author: maurits Date: Sat Oct 31 16:30:44 2009 New Revision: 11570 Modified: Products.DataGridField/trunk/Products/DataGridField/CheckboxColumn.py Products.DataGridField/trunk/Products/DataGridField/Column.py Products.DataGridField/trunk/Products/DataGridField/DataGridField.py Products.DataGridField/trunk/Products/DataGridField/DataGridWidget.py Products.DataGridField/trunk/Products/DataGridField/FixedColumn.py Products.DataGridField/trunk/Products/DataGridField/HelpColumn.py Products.DataGridField/trunk/Products/DataGridField/LinesColumn.py Products.DataGridField/trunk/Products/DataGridField/LinkColumn.py Products.DataGridField/trunk/Products/DataGridField/RadioColumn.py Products.DataGridField/trunk/Products/DataGridField/__init__.py Products.DataGridField/trunk/Products/DataGridField/examples/DataGridDemoType.py Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType.xml Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType2.xml Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/FixedRowsDemoType.xml Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/InvalidDataGridDemoType.xml Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_checkbox_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_fixed_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_help_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_lines_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_link_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_radio_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_select_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_text_cell.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagridwidget.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagridwidget_edit_row.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagridwidget_manipulators.pt Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagridwidget_view_row.pt Products.DataGridField/trunk/Products/DataGridField/utils.py Log: Nuke trailing white space Modified: Products.DataGridField/trunk/Products/DataGridField/CheckboxColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/CheckboxColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/CheckboxColumn.py Sat Oct 31 16:30:44 2009 @@ -1,9 +1,9 @@ """ - Checkbox column + Checkbox column Copyright 2006, 2007 Radim Novotny - + Licensed under GPL. """ @@ -20,14 +20,14 @@ """ Allow user select one from on/off options using check buttons. Implementation based on RadioColumn. - - WARNING - Please note, the current implementation does not work when - some field on the form raises validation error. In this case all checkboxes + + WARNING - Please note, the current implementation does not work when + some field on the form raises validation error. In this case all checkboxes are cleared. Do not use CheckboxColumn if your form has some required fields or validators active. - + There are no on/off values. Widget view displays HTML character with code - ✔ (checkmark) or - + ✔ (checkmark) or - """ security = ClassSecurityInfo() @@ -40,18 +40,18 @@ def processCellData(self, form, value, context, field, columnId): """ Read cell values from raw form data """ - + newValue = [] - + for row in value: - + # we must clone row since # row is readonly ZPublished.HTTPRequest.record object newRow = {} for key in row.keys(): newRow[key] = row[key] - - orderIndex = row["orderindex_"] + + orderIndex = row["orderindex_"] cellId = "%s.%s.%s" % (field.getName(), columnId, orderIndex) if form.has_key(cellId): # If check button is set in HTML form @@ -61,13 +61,13 @@ else: # if item is not in form, user did not check it. newRow[columnId] = '' - + newValue.append(newRow) - + return newValue - - - + + + # Initializes class security InitializeClass(CheckboxColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/Column.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/Column.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/Column.py Sat Oct 31 16:30:44 2009 @@ -24,7 +24,7 @@ def __init__(self, label, default=None, default_method=None, label_msgid=None): """ Create a column - + @param label User visible name @param default Default value for new rows @param default_value Default function to generate the default value for new rows @@ -32,27 +32,27 @@ self.label = label self.default = default self.default_method = default_method - + if label_msgid is None: label_msgid = label self.label_msgid = label_msgid security.declarePublic('getLabel') def getLabel(self, context, widget): - """ User friendly name for the columnt - + """ User friendly name for the columnt + @param context Context where translation happens @param widget The parent widget of this column """ - - + + # TODO: translation support disabled - + #if HAS_PLONE25: # No translation support yet # return zope.i18n.translate( - # _(self.label_msgid, - # self.label), + # _(self.label_msgid, + # self.label), # context=context) #else: # context.translate( @@ -60,8 +60,8 @@ # domain = widget.i18n_domain, # default = self.label) return self.label - - + + security.declarePublic('getDefault') def getDefault(self, context): """ Default value for new rows """ @@ -72,28 +72,28 @@ raise AttributeError, "Class %s has no default_method %s" % (str(context), self.default_method) return func() - - + + return self.default security.declarePublic('getMacro') def getMacro(self): """ Return macro used to render this column in view/edit """ return "datagrid_text_cell" - + security.declarePublic('processCellData') def processCellData(self, form, value, context, field, columnId): """ Read cell values from raw form data - + Column processing in forms may need special preparations for data if widgets use other than <input value> for storing their values in fields. - + @param form Submitted form, contains HTML fields @param context Archetypes item instance for the submitted form @param field Assigned field for this widget @param columnId Column what we are operating - + @return new values which are constructed by processing data """ return value Modified: Products.DataGridField/trunk/Products/DataGridField/DataGridField.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/DataGridField.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/DataGridField.py Sat Oct 31 16:30:44 2009 @@ -1,6 +1,6 @@ """ DataGridField field class - + Copyright 2006 DataGridField authors, see documentation for details """ @@ -43,36 +43,36 @@ 'mode' : 'rw', # inital data of the field in form sequence of dicts 'default' : ({},), - + 'widget' : DataGridWidget, - + # Column id list (sequence of strings) 'columns' : ('default',), # sequence of FixedRow instances. - # See FixedRow class documentation + # See FixedRow class documentation 'fixed_rows' : [], - - # User can append new rows. Currently UI feature. This is not yet checked - # at application level in set(). + + # User can append new rows. Currently UI feature. This is not yet checked + # at application level in set(). 'allow_insert' : True, - + # User can delete rows. This is currently UI feature (red delete button). # This is not yet checked at application level in set(). 'allow_delete' : True, - + # User can reorder rows. This is currently UI feature (ordering buttons). - # This is not yet checked at application level in set(). + # This is not yet checked at application level in set(). 'allow_reorder' : True, - + # If true all the contents of the DataGridField is concatenated # to searchable text and given to text indexer 'searchable' : False, - + # Set to false to allow empty rows in the data. # Needed for auto insert feature 'allow_empty_rows' : True, - + # Set to true to hifhligh odd/even rows in edit/view form 'allow_oddeven' : False, }) @@ -90,37 +90,37 @@ def getColumnIds(self): """ Return list of column ids """ return self.columns - + security.declarePrivate('set') def set(self, instance, value, **kwargs): """ The passed in object should be a records object, or a sequence of dictionaries """ - + # Help to localize problems in Zope trace back __traceback_info__ = value, type(value) # we sanitize the values cleaned = [] doSort = False - + logging.debug("Setting DGF value to " + str(value)) - + if value == ({},): # With some Plone versions, it looks like that AT init # causes DGF to get one empty dictionary as the base value - # and later, it will be appended as a cleaned row below if - # we don't filter out it here. + # and later, it will be appended as a cleaned row below if + # we don't filter out it here. value = [] - - + + if isinstance(value, basestring): # In the field mutator (set) the # passed value is not always a record, but sometimes a string. - # In fact the RFC822Marshaller passes a string. - + # In fact the RFC822Marshaller passes a string. + logging.debug("Doing string marshalling") - + records = [] dict = {} rows = value.strip("{}").split(',') @@ -137,31 +137,31 @@ if len(dict) > 0: records.append(dict) - value = records + value = records else: - + # Passed in value is a HTML form data # from DataGridWidget. Value is Python array, # each item being a dictionary with column_name : value mappins # + orderinder which is used in JS reordering - + for row in value: order = row.get('orderindex_', None) - + empty = True - + if order != "template_row_marker": # don't process hidden template row as - # input data - + # input data + val = {} for col in self.getColumnIds(): val[col] = (row.get(col,'')).strip() - + if val[col] != '': empty = False - - if order is not None: + + if order is not None: try: order = int(order) doSort = True @@ -202,7 +202,7 @@ value = ObjectField.get(self, instance, **kwargs) or () value = self.resetFixedRows(instance, value) - + for row in value: for col in self.getColumnIds(): buffer.write(row.get(col,'')) @@ -216,9 +216,9 @@ # Return list containing all encoded rows value = ObjectField.get(self, instance, **kwargs) or () value = self.resetFixedRows(instance, value) - + data = [encode(v, instance, **kwargs) for v in value] - + return tuple(data) security.declarePrivate('getRaw') @@ -329,82 +329,82 @@ for r in data: rows.append(tuple([r[c] for c in self.getColumnIds()])) return tuple(rows) - + def resetFixedRows(self, instance, data): """ See that fixed rows exists. - + Go through data (list of rows/dict) and add fixed rows if they are missing. - + 1. Go through all fixed rows - 2. See if the key column of the fixed row has value in user data + 2. See if the key column of the fixed row has value in user data 3. If the row is missing, (re)append it - + @param data user set data @return modified data w/fixed rows present """ - + # is fixed row property used if hasattr(self, "fixed_rows") and self.fixed_rows != None: - + if isinstance(self.fixed_rows, basestring): # fixed rows is a name of a member function - + try: func = getattr(instance, self.fixed_rows) except AttributeError: raise AttributeError, "Class %s is missing fixed row data function %s" % (str(instance), self.fixed_rows) - + fixedRowsData = func() - - else: + + else: # fixed rows is a direct value - + fixedRowsData = self.fixed_rows - + newRows = list(data[:]) - - for fixedRow in fixedRowsData: + + for fixedRow in fixedRowsData: # go through data set and see if the fixed key value exists keyValue = fixedRow.initialData[fixedRow.keyColumn] - + exist = False - + for row in data: if row.has_key(fixedRow.keyColumn): if row[fixedRow.keyColumn] == keyValue: # row exists and has user set value exist = True break - + if not exist: # initialize fixed data newRows.append(fixedRow.initialData) - + return tuple(newRows) else: # fixed rows behavior is disabled return data - - -class FixedRow: + + +class FixedRow: """ Row which is always present at DataGridField data. - + This is a useful use case for situations where user must be - forced to fill in some rows containing pre-set data. An example could + forced to fill in some rows containing pre-set data. An example could be the filling of programming language knowledge in CV. Languages are preset - and user fills in his/her experience. User can also add some weird languages outside + and user fills in his/her experience. User can also add some weird languages outside pre-set languages. - + Instead of going with normal field.default behavior, fixed rows allow some flexibility when changing the fixed data set after item initialization. For example, the set of programming languages can be updated and user refills missing values to his/her CV. """ - + def __init__(self, keyColumn, initialData): """ @param initialData Dictionary for the row when user has deleted the fiexd row/item is initialized - @param keyColumn Column which existence of value determines the need for a fixed row + @param keyColumn Column which existence of value determines the need for a fixed row """ self.keyColumn = keyColumn self.initialData = initialData Modified: Products.DataGridField/trunk/Products/DataGridField/DataGridWidget.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/DataGridWidget.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/DataGridWidget.py Sat Oct 31 16:30:44 2009 @@ -1,8 +1,8 @@ """ Data grid UI component - + Copyright 2006-2007 DataGridField authors - + """ __author__ = 'Mikko Ohtamaa <mi...@re...>' @@ -24,11 +24,11 @@ - helper_js: - Javascript used with the widget - helper_css: - - CSS file used with the widget + - CSS file used with the widget - auto_insert - Automatically add new rows when the last row is being edited. - This doesn't work if the - + This doesn't work if the + """ _properties = TypesWidget._properties.copy() @@ -39,7 +39,7 @@ 'helper_js': ('datagridwidget.js',), 'show_header' : True, 'auto_insert': False, - 'columns' : {}, # Sequence of Column instances + 'columns' : {}, # Sequence of Column instances }) @@ -50,7 +50,7 @@ """ Get user friendly names of all columns """ columnDefinitions = getattr(self, 'columns', {}) - + if len(columnDefinitions) == 0: # old way of getting column names columnNames = getattr(self, 'column_names', []) @@ -86,7 +86,7 @@ if columnNames and len(columnNames) == len(field.columns): idx = list(field.columns).index(id) label = columnNames[idx] - + return Column(label) raise KeyError, "Tried to look up missing column definition for: " + str(id) @@ -94,16 +94,16 @@ security.declarePublic('getColumnDefs') def getColumnDefs(self, field, instance): """ Get all column definitions for a DataGridField. - - @param field Field definition + + @param field Field definition @param instance Context object who has the field - + @return formatted column definitions as dict of { id, label, visible } """ result = [] - + columns = getattr(self, 'columns', {}) - + for id in field.columns: c = self.getColumnDefinition(field, id) if c is None: @@ -113,7 +113,7 @@ item['visible'] = visible item['label'] = c.getLabel(instance, self) result.append(item) - + return result def getUserFriendlySelectionItem(self, context, item, vocab): @@ -123,73 +123,73 @@ if item == None or item == '': return "" return vocab.getValue(item) - - + + security.declarePublic('isAutoInsertEnabled') - def isAutoInsertEnabled(self): + def isAutoInsertEnabled(self): return self.auto_insert security.declarePublic('isDeleteEnabled') def isDeleteEnabled(self, context, field): - """ Can user delete rows from DGW - + """ Can user delete rows from DGW + Called by template """ return field.allow_delete - + security.declarePublic('isInsertEnabled') def isInsertEnabled(self, context, field): - """ Can user insert new rows to DGW - + """ Can user insert new rows to DGW + Called by template """ return field.allow_insert security.declarePublic('isReorderingEnabled') def isReorderEnabled(self, context, field): - """ Can user reorder rows in DGW - + """ Can user reorder rows in DGW + Called by template """ return field.allow_reorder - - security.declarePublic('hasAddButton') + + security.declarePublic('hasAddButton') def hasAddButton(self, context, field): """ Show explict Add row button in DGW """ return self.show_add_button - - security.declarePublic('hasHeader') + + security.declarePublic('hasHeader') def hasHeader(self, context, field): """ Render columns names in view mode""" return self.show_header - + security.declarePublic('process_form') def process_form(self, instance, field, form, empty_marker=None, emptyReturnsMarker=False): - """ Manipulate form input data - - Data coming from widget code goes through process_form + """ Manipulate form input data + + Data coming from widget code goes through process_form before stored to field. - + For example, radio button cells need to be propeply changed from checked values to one chosen id for saving. """ - + value = TypesWidget.process_form(self, instance, field, form, empty_marker, emptyReturnsMarker) - + if value == None or len(value) == 0: return value - + newData = value[0] - + # Column code hook to form data and manipulate # it propeply where TypesWidget.process_form doesn't # have required functionality for columnId in getattr(self, 'columns', {}).keys(): columnDefinition = self.getColumnDefinition(field, columnId) - newData = columnDefinition.processCellData(form, newData, instance, field, columnId) - + newData = columnDefinition.processCellData(form, newData, instance, field, columnId) + # Clean up the last empty row (automatically inseted) # if auto_insert is enabled if self.isAutoInsertEnabled() and len(newData) > 1: @@ -198,33 +198,33 @@ for val in lastRow.values(): if val != None and val != "": hasContent = True - + if not hasContent: newData = newData[:-1] - - + + return (newData, value[1]) - - + + def savePostbackData(self, REQUEST, context, field, formData): """ Gets the value of a cell - - We cannot solely rely DataGridField.get which + + We cannot solely rely DataGridField.get which does ObjectField.get(), since form postback data can contain custom fields which are not directly mapped - like Zope expects (e.g. fields with more than one <input>) - + like Zope expects (e.g. fields with more than one <input>) + XXX Need refactoring/clean up - """ - - + """ + + # Column code hook to form data and manipulate # it propeply where TypesWidget.process_form doesn't # have required functionality for columnId in getattr(self, 'columns', {}).keys(): columnDefinition = self.getColumnDefinition(field, columnId) formData = columnDefinition.processCellData(REQUEST, formData, context, field, columnId) - + __all__ = ('DataGridWidget') Modified: Products.DataGridField/trunk/Products/DataGridField/FixedColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/FixedColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/FixedColumn.py Sat Oct 31 16:30:44 2009 @@ -1,9 +1,9 @@ """ - Fixed text column + Fixed text column Copyright 2006 Red Innovation - + Licensed under GPL. """ @@ -18,14 +18,14 @@ class FixedColumn(Column): """ Column with non-changeable text - + Useful with DataGridField.fixed_row property in some use cases. """ security = ClassSecurityInfo() def __init__(self, label, default=None, label_msgid=None, visible=True): """ Create a column - + @param hide Hide column from displaying """ Column.__init__(self, label, default, label_msgid) @@ -36,6 +36,6 @@ """ Return macro used to render this column in view/edit """ return "datagrid_fixed_cell" - + # Initializes class security InitializeClass(FixedColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/HelpColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/HelpColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/HelpColumn.py Sat Oct 31 16:30:44 2009 @@ -1,9 +1,9 @@ """ - Column with help for DataGridField + Column with help for DataGridField Written by Juan Grigera <ju...@gr...>. - + """ from __future__ import nested_scopes @@ -17,23 +17,23 @@ class HelpColumn(Column): - """ Help column support. - + """ Help column support. + Behaves like normal text cell, but has a help pop-up icon next to it. """ - + security = ClassSecurityInfo() - + def __init__(self, title, helper_text, script, icon): """ Create a HelpColumn - + """ Column.__init__(self, title) self.helper_text = helper_text self.helper_url = script self.icon = icon - - + + security.declareProtected(View, 'getVocabulary') def getVocabulary(self, instance): """ Gets this column vocabulary for specific Archetypes instance @@ -42,28 +42,28 @@ func = getattr(instance, self.vocabulary) except AttributeError: raise AttributeError, "Class %s is missing vocabulary function %s" % (str(instance), self.vocabulary) - + return func() - - + + security.declarePublic('getMacro') def getMacro(self): """ Return macro used to render this column in view/edit """ return "datagrid_help_cell" - + security.declarePublic('getHelperUrl') def getHelperUrl(self): """ Return url to open""" return self.helper_url - + security.declarePublic('getHelperText') def getHelperText(self): """ Return help text""" return self.helper_text - + security.declarePublic('getIcon') def getIcon(self): return self.icon - -# Initializes class security + +# Initializes class security InitializeClass(HelpColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/LinesColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/LinesColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/LinesColumn.py Sat Oct 31 16:30:44 2009 @@ -1,7 +1,7 @@ """ Lines column - used for list of values - + Licensed under GPL. """ @@ -12,7 +12,7 @@ class LinesColumn(Column): """ Textarea which returns list of lines - + Used eg. as vocabulary definition in PFGDataGrid """ security = ClassSecurityInfo() @@ -25,22 +25,22 @@ security.declarePublic('processCellData') def processCellData(self, form, value, context, field, columnId): """ Read cell values from raw form data - + Column processing in forms may need special preparations for data if widgets use other than <input value> for storing their values in fields. - + @param form Submitted form, contains HTML fields @param context Archetypes item instance for the submitted form @param field Assigned field for this widget @param columnId Column what we are operating - + @return new values which are constructed by processing data """ # scan all rows and build list of lines for fields newValue = [] for row in value: - + # we must clone row since # row is readonly ZPublished.HTTPRequest.record object newRow = {} @@ -53,8 +53,8 @@ if newRow[columnId] and newRow[columnId][-1]=='': newRow[columnId] = newRow[columnId][:-1] newValue.append(newRow) - + return newValue - + # Initializes class security InitializeClass(LinesColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/LinkColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/LinkColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/LinkColumn.py Sat Oct 31 16:30:44 2009 @@ -1,7 +1,7 @@ """ - + Copyright 2006 Red Innovation - + """ __author__ = 'Mikko Ohtamaa <mi...@re...>' @@ -14,27 +14,27 @@ class LinkColumn(Column): """ Defines DataGridField column with link descriptions and targets - + Description and link is stored as one text entry, in of form which is used by many Wikis. - + Format: - "description" "|" "link" - + "description" "|" "link" + If links begin with http:// they are absolute. Otherwise - links are relative to the portal root. + links are relative to the portal root. Managing absolute and relative links are done through utils module functions. """ security = ClassSecurityInfo() - - + + def __init__(self, title, linkClass=""): """ Create a Links - + @param linkClass CSS class for <a> links in view mode - + """ Column.__init__(self, title) self.linkClass = linkClass @@ -47,87 +47,87 @@ security.declarePublic('getLinkClass') def getLinkClass(self): return self.linkClass - + security.declarePublic('getLink') def getLink(self, instance, cell): """ Extract link address from cell data """ - + if cell == None: return "" - + splitted = cell.split("|") if len(splitted) >= 2: return makeAbsoluteLink(splitted[1], instance) return "" - + security.declarePublic('getRelativeLink') def getRelativeLink(self, instance, cell): """ Extract link address from cell data """ - + if cell == None: return "" - + splitted = cell.split("|") if len(splitted) >= 2: return makeRelativeLink(splitted[1], instance) - return "" - + return "" + security.declarePublic("getDescription") def getDescription(self, cell): """ Extract link description from cell data """ - + if cell == None: return "" - + splitted = cell.split("|") if len(splitted) >= 1: return splitted[0] return "" - - + + security.declarePublic('processCellData') def processCellData(self, form, value, context, field, columnId): """ Read cell values from raw form data - + Read form fields xxx_link and xx_desc and form one description from them. """ - + # scan all rows and build desc|link string pair for # fields newValue = [] for row in value: - + # we must clone row since # row is readonly ZPublished.HTTPRequest.record object newRow = {} for key in row.keys(): newRow[key] = row[key] - + if newRow.has_key(columnId + "_desc"): desc = newRow[columnId + "_desc"] else: desc = "" - + if newRow.has_key(columnId + "_link"): link = newRow[columnId + "_link"] else: link = "" - + link = makeRelativeLink(link, context) - + if desc or link: newRow[columnId] = "%s|%s" % (desc,link) else: # don't add | character alone # causes extra new row to appear newRow[columnId] = "" - + newValue.append(newRow) - - return newValue - - + + return newValue + + # Initializes class security InitializeClass(LinkColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/RadioColumn.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/RadioColumn.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/RadioColumn.py Sat Oct 31 16:30:44 2009 @@ -1,9 +1,9 @@ """ - Radio button column + Radio button column Copyright 2006 Red Innovation - + Licensed under GPL. """ @@ -18,32 +18,32 @@ class RadioColumn(SelectColumn): """ Allow user select one from many options using radio buttons. - + WARNING: Does not work with validation. All field values will be cleared when validation fails on the edit page submit. This is a limitation in the current architecture (Archetypes / ZPublisher / DataGridField). - + Some explanation hints: - + In:: <input type="radio" name="" - name must be unique among radio button group. - - This is problematic. ZPublisher cannot associate radio buttons to :records + name must be unique among radio button group. + + This is problematic. ZPublisher cannot associate radio buttons to :records groups since :records groups are formed as:: - + name string:${fieldName}.${column}:records; - + ZPublisher's :records naming convention doesn't allow different per row radio button groups. Instead, we assign an unique name for reach radio button cell using:: - + name string:${fieldName}.${column}.${repeat/rows/number}; - - Column.processCellData parses form data and propeply combines field value + + Column.processCellData parses form data and propeply combines field value from radio buttons so that Archetypes' field framework correctly understand the set value. - + """ security = ClassSecurityInfo() @@ -55,36 +55,36 @@ security.declarePublic('processCellData') def processCellData(self, form, value, context, field, columnId): """ Read cell values from raw form data - + Read special table for radio button columns from form data. The selected radio button cell id is placed as a cell value. """ - + newValue = [] - + #print "form value:" + str(form) - + for row in value: - + # we must clone row since # row is readonly ZPublished.HTTPRequest.record object newRow = {} for key in row.keys(): newRow[key] = row[key] - - orderIndex = row["orderindex_"] + + orderIndex = row["orderindex_"] cellId = "%s.%s.%s" % (field.getName(), columnId, orderIndex) if form.has_key(cellId): # If radio button is set in HTML form # it's id appears in form of field.column.orderIndex newRow[columnId] = form[cellId] - + newValue.append(newRow) - + return newValue - - - + + + # Initializes class security InitializeClass(RadioColumn) Modified: Products.DataGridField/trunk/Products/DataGridField/__init__.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/__init__.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/__init__.py Sat Oct 31 16:30:44 2009 @@ -3,7 +3,7 @@ DataGridField initialzer. Copyright 2006-2007 DataGridField authors. - + Load all submodules and perform Zope security initialize for them. """ Modified: Products.DataGridField/trunk/Products/DataGridField/examples/DataGridDemoType.py ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/examples/DataGridDemoType.py (original) +++ Products.DataGridField/trunk/Products/DataGridField/examples/DataGridDemoType.py Sat Oct 31 16:30:44 2009 @@ -1,6 +1,6 @@ """ Archetypes items used in DataGridField unit testing and examples - + """ # Zope imports from AccessControl import ClassSecurityInfo @@ -22,55 +22,55 @@ class DataGridDemoType(BaseContent): """ Very simple DataGridField demo. - - This class is used in unit testing, mainly to check old interface compatibility + + This class is used in unit testing, mainly to check old interface compatibility (without widget column definitions). Please see the more complex examples below. """ security = ClassSecurityInfo() - + schema = BaseSchema + Schema(( DataGridField('DemoField', searchable=True, # One unit tests checks whether text search works widget = DataGridWidget(), - columns=('column1','column2','The third'), + columns=('column1','column2','The third'), default=[ {'column1':'a', 'column2':'b', 'The third':'c'}, {'column1':'d', 'column2':'e', 'The third':'f'} ] ), - ), + ), ) - + meta_type = portal_type = archetype_name = 'DataGridDemoType' - + registerType(DataGridDemoType, PKG_NAME) class DataGridDemoType2(BaseContent): """ Demo for different DataGridWidget columns - + This class is used in unit testing - + Check manual that: - Rows are inserted automatically when a value is filled in - - Select column has sample 2 as a default value + - Select column has sample 2 as a default value """ security = ClassSecurityInfo() - + schema = BaseSchema + Schema(( - + DataGridField('AutoInsertDemoField', - searchable=True, # One unit tests checks whether text search works + searchable=True, # One unit tests checks whether text search works columns=("column1", "column2", "column3"), allow_empty_rows = False, # Must be false to make auto insert feature perform correctly widget = DataGridWidget( - auto_insert = True, + auto_insert = True, description="Automatically insert new rows when the last row is being filled. When you edit the last row, a new row is created automatically.", columns={ }, - ), + ), ), - + DataGridField('DemoField2', searchable=True, # One unit tests checks whether text search works columns=("column1", "column2", "select_sample"), @@ -81,19 +81,19 @@ 'column2' : Column("My friendly name", default="Some default text"), 'select_sample' : SelectColumn("Friendly name", vocabulary="getSampleVocabulary", default="sample2") }, - ), - ), - + ), + ), + DataGridField('DemoField3', columns=("column1", "column2"), widget = DataGridWidget( description="Test radio and checkbox columns", columns={ 'column1' : RadioColumn("Radio column", vocabulary="getSampleVocabulary"), - 'column2' : CheckboxColumn("Checkbox column") + 'column2' : CheckboxColumn("Checkbox column") }, - ), - ), + ), + ), DataGridField('DemoField4', columns=("text_column", "help_column"), @@ -104,19 +104,19 @@ # Help is help.pt 'help_column' : HelpColumn("Help", "See help here", "help", "info.gif") }, - ), - ), + ), + ), + - )) - + meta_type = portal_type = archetype_name = 'DataGridDemoType2' - + def getSampleVocabulary(self): """Get a sample vocabulary """ return DisplayList( - + (("sample", "Sample value 1",), ("sample2", "Sample value 2",),)) @@ -124,13 +124,13 @@ class InvalidDataGridDemoType(BaseContent): """ DataGridField declaration with errors - + Errors should be detected run-time, with helpful error messages. - - This class is missing column definition select_sample in DataGridWidget + + This class is missing column definition select_sample in DataGridWidget """ security = ClassSecurityInfo() - + schema = BaseSchema + Schema(( DataGridField('DemoField', searchable = True, @@ -139,23 +139,23 @@ columns={ 'column1' : Column("Toholampi city rox"), 'column2' : Column("My friendly name"), - }, + }, ),), - + )) - - meta_type = portal_type = archetype_name = 'InvalidDataGridDemoType' - + + meta_type = portal_type = archetype_name = 'InvalidDataGridDemoType' + registerType(InvalidDataGridDemoType, PKG_NAME) - - + + class FixedRowsDemoType(BaseContent): """ Demostrate fixed rows usage - + This class is used in unit testing """ security = ClassSecurityInfo() - + schema = BaseSchema + Schema(( DataGridField('DemoField', @@ -166,17 +166,17 @@ FixedRow(keyColumn="column2", initialData = { "column1" : "ddd", "column2" : "must-exist-2" }), ] ), - + DataGridField('RestrictedField', widget = DataGridWidget(), columns=('column1','column2','The third'), allow_insert=False, allow_delete=False, allow_reorder=False, - ), - + ), + DataGridField('predefinedSkills', - searchable=True, + searchable=True, columns=('skill', 'level'), fixed_rows = "getPredefinedSkillsData", allow_delete = False, @@ -189,30 +189,30 @@ "skill" : FixedColumn("Skill"), "level" : RadioColumn("Level", vocabulary="getSkillLevels") } - ), - ), + ), + ), )) - + meta_type = portal_type = archetype_name = 'FixedRowsDemoType' - + def getSkillLevels(self): - return DisplayList( + return DisplayList( (("bad", "Bad",), ("good", "Good",), )) - - def getPredefinedSkillsData(self): + + def getPredefinedSkillsData(self): """ Generate fixed row key information """ skills = [ "Python", "Perl", "XML", "Java", "Plone" ] rows = [] - for skill in skills: + for skill in skills: rows.append(FixedRow(keyColumn="skill", initialData={"skill" : skill, "level" : "bad"})) - + return rows - - + + registerType(FixedRowsDemoType, PKG_NAME) - + Modified: Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType.xml ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType.xml (original) +++ Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType.xml Sat Oct 31 16:30:44 2009 @@ -3,8 +3,8 @@ xmlns:i18n="http://xml.zope.org/namespaces/i18n"> <property name="title">DataGridDemoType</property> <property name="description"> Very simple DataGridField demo. - - This class is used in unit testing, mainly to check old interface compatibility + + This class is used in unit testing, mainly to check old interface compatibility (without widget column definitions). Please see the more complex examples below. </property> <property name="content_icon">document_icon.gif</property> Modified: Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType2.xml ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType2.xml (original) +++ Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/DataGridDemoType2.xml Sat Oct 31 16:30:44 2009 @@ -3,12 +3,12 @@ xmlns:i18n="http://xml.zope.org/namespaces/i18n"> <property name="title">DataGridDemoType2</property> <property name="description"> Demo for different DataGridWidget columns - + This class is used in unit testing - + Check manual that: - Rows are inserted automatically when a value is filled in - - Select column has sample 2 as a default value + - Select column has sample 2 as a default value </property> <property name="content_icon">document_icon.gif</property> <property name="content_meta_type">DataGridDemoType2</property> Modified: Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/FixedRowsDemoType.xml ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/FixedRowsDemoType.xml (original) +++ Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/FixedRowsDemoType.xml Sat Oct 31 16:30:44 2009 @@ -3,7 +3,7 @@ xmlns:i18n="http://xml.zope.org/namespaces/i18n"> <property name="title">FixedRowsDemoType</property> <property name="description"> Demostrate fixed rows usage - + This class is used in unit testing </property> <property name="content_icon">document_icon.gif</property> Modified: Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/InvalidDataGridDemoType.xml ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/InvalidDataGridDemoType.xml (original) +++ Products.DataGridField/trunk/Products/DataGridField/profiles/example/types/InvalidDataGridDemoType.xml Sat Oct 31 16:30:44 2009 @@ -4,10 +4,10 @@ xmlns:i18n="http://xml.zope.org/namespaces/i18n"> <property name="title">InvalidDataGridDemoType</property> <property name="description"> DataGridField declaration with errors - + Errors should be detected run-time, with helpful error messages. - - This class is missing column definition select_sample in DataGridWidget + + This class is missing column definition select_sample in DataGridWidget </property> <property name="content_icon">document_icon.gif</property> <property name="content_meta_type">InvalidDataGridDemoType</property> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_checkbox_cell.pt ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_checkbox_cell.pt (original) +++ Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_checkbox_cell.pt Sat Oct 31 16:30:44 2009 @@ -3,8 +3,8 @@ xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone"> - - + + <!-- View/edit radio button choice cells --> <body> @@ -15,13 +15,13 @@ </metal:view_cell_macro> <!-- EDIT --> - <metal:edit_cell_macro define-macro="edit_cell"> + <metal:edit_cell_macro define-macro="edit_cell"> <input class="noborder" type="checkbox" value="1" tal:attributes="checked python:rows.get(column) == '1'; name string:${fieldName}.${column}.${repeat/rows/number}; - id string:${column}_${fieldId}; + id string:${column}_${fieldId}; "/> </metal:edit_cell_macro> @@ -36,7 +36,7 @@ /> </tal:block> </metal:edit_cell_macro> - + </body> </html> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_fixed_cell.pt ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_fixed_cell.pt (original) +++ Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_fixed_cell.pt Sat Oct 31 16:30:44 2009 @@ -3,14 +3,14 @@ xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone"> - - + + <!-- View/edit fixed text cells. User cannot edit anything. --> <body> <!-- VIEW --> <metal:view_cell_macro define-macro="view_cell"> - <div tal:content="cell_value" /> + <div tal:content="cell_value" /> </metal:view_cell_macro> <!-- EDIT --> @@ -21,7 +21,7 @@ id string:${column}_${fieldId}; value cell_value;" type="hidden" /> - + </metal:edit_cell_macro> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_help_cell.pt ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_help_cell.pt (original) +++ Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_help_cell.pt Sat Oct 31 16:30:44 2009 @@ -3,22 +3,22 @@ xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone"> - - -<!-- View/edit free text columns - + + +<!-- View/edit free text columns + --> <body> <!-- VIEW --> - <metal:view_cell_macro define-macro="view_cell"> + <metal:view_cell_macro define-macro="view_cell"> <div tal:content="cell_value" /> </metal:view_cell_macro> <!-- EDIT --> <metal:edit_cell_macro define-macro="edit_cell"> - <input style="width: 100%" name="myfield.name:records" + <input style="width: 100%" name="myfield.name:records" onkeypress="handleKeyPress(event);" tal:attributes="name string:${fieldName}.${column}:records; value cell_value; @@ -26,10 +26,10 @@ " type="text" /> </metal:edit_cell_macro> - + <!-- EMPTY EDIT --> <metal:edit_empty_cell_macro define-macro="edit_empty_cell"> - <input style="width: 100%" name="myfield.name:records" + <input style="width: 100%" name="myfield.name:records" onkeypress="handleKeyPress(event);" tal:attributes=" name string:${fieldName}.${column}:records; @@ -43,18 +43,18 @@ icon python:column_definition.getIcon(); at_url python:'/'.join(here.getPhysicalPath()); url python:startup_url + '/' + helper_url + '?at_url=' + at_url"> - <img style="cursor: pointer" - src="" + <img style="cursor: pointer" + src="" alt="" tal:attributes="onClick string:javascript:openPopup('${url}', 500, 550); src string:${portal_url}/${icon}; - alt python:helper_text" + alt python:helper_text" /> </tal:popup> </metal:edit_empty_cell_macro> - - + + </body> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_lines_cell.pt ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_lines_cell.pt (original) +++ Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_lines_cell.pt Sat Oct 31 16:30:44 2009 @@ -3,8 +3,8 @@ xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone"> - - + + <!-- View/edit link cells --> <body> @@ -12,26 +12,26 @@ <metal:view_cell_macro define-macro="view_cell"> <div tal:content="cell_value" /> </metal:view_cell_macro> - + <!-- EDIT --> <metal:edit_cell_macro define-macro="edit_cell"> - <textarea style="width: 100%" name="myfield.name:records" + <textarea style="width: 100%" name="myfield.name:records" tal:attributes="name string:${fieldName}.${column}:records; id string:${column}_${fieldId}; onchange eventHandler;" tal:content="python:'\n'.join(cell_value or [])"></textarea> </metal:edit_cell_macro> - + <!-- EMPTY EDIT --> <metal:edit_empty_cell_macro define-macro="edit_empty_cell"> - <textarea style="width: 100%" name="myfield.name:records" + <textarea style="width: 100%" name="myfield.name:records" tal:attributes="name string:${fieldName}.${column}:records; - id string:${column}_${fieldId}; + id string:${column}_${fieldId}; onchange eventHandler;" tal:content="python:column_definition.getDefault(here)"></textarea> </metal:edit_empty_cell_macro> - + </body> </html> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_link_cell.pt ============================================================================== --- Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_link_cell.pt (original) +++ Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_link_cell.pt Sat Oct 31 16:30:44 2009 @@ -3,18 +3,18 @@ xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone"> - - + + <!-- View/edit link cells --> <body> <!-- VIEW --> <metal:view_cell_macro define-macro="view_cell" tal:define="desc python: column_definition.getDescription(cell_value); - link python: column_definition.getLink(here, cell_value)"> - - - <a + link python: column_definition.getLink(here, cell_value)"> + + + <a tal:condition="python: link != ''" tal:attributes="href link; class python:column_definition.getLinkClass()" @@ -22,16 +22,16 @@ <span tal:condition="python: link == ''" tal:content="desc" /> - + </metal:view_cell_macro> - + <!-- EDIT --> - <metal:edit_cell_macro define-macro="edit_cell"> - + <metal:edit_cell_macro define-macro="edit_cell"> + <tal:block tal:define="desc python: column_definition.getDescription(cell_value); - link python: column_definition.getRelativeLink(here, cell_value)"> - + link python: column_definition.getRelativeLink(here, cell_value)"> + <table class="link-cell" style="width: 100%"> <tr> <td> @@ -47,7 +47,7 @@ </tr> <tr> <td> - <span class="discreet">Link:</span> + <span class="discreet">Link:</span> </td> <td tal:define="name string:${fieldName}.${column}_link:records;"> <input class="link-cell-link" tal:attributes=" @@ -57,16 +57,16 @@ "/> </td> </tr> - </table> + </table> </tal:block> - + </metal:edit_cell_macro> <!-- EMPTY EDIT --> <metal:edit_cell_macro define-macro="edit_empty_cell"> - <tal:block> - + <tal:block> + <table class="link-cell" style="width: 100%"> <tr> <td> @@ -80,7 +80,7 @@ </tr> <tr> <td> - <span class="discreet">Link:</span> + <span class="discreet">Link:</span> </td> <td> <input class="link-cell-link" tal:attributes="name string:${fieldName}.${column}_link:records; @@ -88,10 +88,10 @@ "/> </td> </tr> - </table> + </table> </tal:block> </metal:edit_cell_macro> - + </body> </html> Modified: Products.DataGridField/trunk/Products/DataGridField/skins/DataGridWidget/datagrid_radio_cell.pt ===========================... [truncated message content] |