From 0a5b672b72e9304c3a0c05d4073107cbfd2a31f1 Mon Sep 17 00:00:00 2001 From: legac <renaud.legac@free.fr> Date: Sat, 21 Sep 2013 23:09:11 +0200 Subject: [PATCH] first implemmentation of the dictfield widget. --- languages/fr-fr.py | 5 ++ models/db_core.py | 10 +++ models/widgets_fields.py | 8 +- modules/plugin_dbui/converter.py | 33 ++++--- modules/plugin_dbui/extjs.py | 5 ++ static/plugin_dbui/src/dictfield.js | 135 ++++++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 14 deletions(-) create mode 100644 static/plugin_dbui/src/dictfield.js diff --git a/languages/fr-fr.py b/languages/fr-fr.py index f2f7ff72..c7f28d0e 100644 --- a/languages/fr-fr.py +++ b/languages/fr-fr.py @@ -20,6 +20,7 @@ 'Country': 'Pays', 'Dates': 'Dates', 'Definition': 'Définition', +'dev': 'dev', 'Doi': 'Doi', 'domain': 'domaine', 'E Print': 'E Print', @@ -46,7 +47,10 @@ 'Help': 'Help', 'Host': 'Host', 'Id': 'Id', +'invalid json': 'invalid json', +'Json': 'Json', 'Last Page': 'Dernière Page', +'List': 'List', 'Max Records': 'Max Records', 'My Axes': 'My Axes', 'My Axis': 'My Axis', @@ -88,6 +92,7 @@ 'Speaker': 'Orateur', 'Start date': 'Date de début', 'Store': 'Store', +'String': 'String', 'Table': 'Table', 'Tables': 'Tables', 'team': 'équipe', diff --git a/models/db_core.py b/models/db_core.py index f43597a7..7f9bbfb4 100644 --- a/models/db_core.py +++ b/models/db_core.py @@ -88,6 +88,16 @@ db.define_table("teams", migrate="teams.table") db.teams.team.filter_in = dbui.CLEAN_SPACES + +db.define_table("dev", + Field("string", "string"), + Field("list", "list:string"), + Field("json", "json"), + migrate="dev.table") + +# NOTE: if we remove the json validator its seem to work ? +db.dev.json.requires = None + #------------------------------------------------------------------------------- # # Publications table diff --git a/models/widgets_fields.py b/models/widgets_fields.py index 1add4040..9ac81991 100644 --- a/models/widgets_fields.py +++ b/models/widgets_fields.py @@ -26,4 +26,10 @@ fieldsModifier.merge_fields('first_page', fieldsModifier.merge_fields('conference_start', 'conference_end', fieldLabel=T('Dates'), - defaults={'flex': 1}) \ No newline at end of file + defaults={'flex': 1}) + +# +# dev +# +fieldsModifier = dbui.FieldsModifier('dev') +fieldsModifier.configure_field('json', dictCfg={"foo": "test", "faa": False, "fii": 0}) diff --git a/modules/plugin_dbui/converter.py b/modules/plugin_dbui/converter.py index ba214f54..40ad90ec 100644 --- a/modules/plugin_dbui/converter.py +++ b/modules/plugin_dbui/converter.py @@ -19,19 +19,22 @@ from mapper import map_default # Associated gluon.dal.field type with an ExtJS widget # The dictionary contains configuration parameters of the Ext JS widget -FTYPE_TO_XTYPE = {'boolean': (CheckBox, {}),\ - 'date': (DateField, {'format': 'Y-m-d'}),\ - 'datetime': (DateField, {'format': 'Y-m-d H:i:s'}),\ - 'double': (NumberField, {'decimalPrecision':2, - 'decimalSeparator': '.'}),\ - 'id': (TextField, {}),\ - 'integer': (NumberField, {}),\ - 'password': (TextField, {'inputType': 'password'}),\ - 'reference': (ComboBox, {}),\ - 'string': (TextField, {}),\ - 'text': (TextArea, {}),\ - 'time': (TimeField, {}),\ - 'upload': (TextField, {'inputType': 'file'})} +FTYPE_TO_XTYPE = {'boolean': (CheckBox, {}),\ + 'date': (DateField, {'format': 'Y-m-d'}),\ + 'datetime': (DateField, {'format': 'Y-m-d H:i:s'}),\ + 'double': (NumberField, {'decimalPrecision':2, + 'decimalSeparator': '.'}),\ + 'id': (TextField, {}),\ + 'integer': (NumberField, {}),\ + 'json': (DictField, {}), + 'list:string': (TextArea, {}),\ + 'list:integer': (TextArea, {}),\ + 'password': (TextField, {'inputType': 'password'}),\ + 'reference': (ComboBox, {}),\ + 'string': (TextField, {}),\ + 'text': (TextArea, {}),\ + 'time': (TimeField, {}),\ + 'upload': (TextField, {'inputType': 'file'})} # constant defining a ExtJS store @@ -365,6 +368,10 @@ def to_gridColumn(field, **kwargs): if (not field.readable) and (not field.writable): cfg["hidden"] = True + # dedicated column render fo json field + if field.type == "json": + cfg["xtype"] = "jsoncolumn" + # Hide fields request by the grid modifiers modifier_grids = PluginManager('dbui').dbui.modifier_grids if tablename in modifier_grids: diff --git a/modules/plugin_dbui/extjs.py b/modules/plugin_dbui/extjs.py index 95ef3cbd..f4db72d9 100644 --- a/modules/plugin_dbui/extjs.py +++ b/modules/plugin_dbui/extjs.py @@ -91,6 +91,11 @@ class DateField(Base): xtype = 'datefield' +class DictField(Base): + """Configurator for C{App.form.DictField}.""" + xtype = 'xdictfield' + + class DirectStore(Base): """Configurator for C{App.data.DirectStore}.""" xtype = 'xdirectstore' diff --git a/static/plugin_dbui/src/dictfield.js b/static/plugin_dbui/src/dictfield.js new file mode 100644 index 00000000..4a02b1a2 --- /dev/null +++ b/static/plugin_dbui/src/dictfield.js @@ -0,0 +1,135 @@ +/** + * The DictField is an Ext.grid.PropertyGrid with which is ran as a form.Field. + * + * NOTE: see Ect.form.SliderField a good example to understand + * how to build a custom field. + * + * The type of this component is xdictfield. + * + * @extends Ext.form.Field + * @version + * + */ +Ext.namespace('App.form'); + +/** + * Extend the predefined renders of the Ext.grid.column by adding jsoncolumn. + * It render properly json object in the grid and well adapted for a DictField. + * + */ +Ext.grid.JsonColumn = Ext.extend(Ext.grid.Column, { + + constructor: function (cfg) { + + "use strict"; + + Ext.grid.JsonColumn.superclass.constructor.call(this, cfg); + this.renderer = JSON.stringify; + } +}); + +Ext.grid.Column.types.jsoncolumn = Ext.grid.JsonColumn; + +/** + * @class App.form.DictField + * + */ +App.form.DictField = Ext.extend(Ext.form.Field, { + + /** + * default configuration of the dictionary + */ + dictCfg: {}, + + /** + * private attributes + */ + grid: null, + store: null, + + /** + * private method requests by the component model of ExtJS + */ + initComponent: function () { + + "use strict"; + + // create the property grid + this.grid = new Ext.grid.PropertyGrid({ + autoHeight: true, + hideHeaders: true, + source: Ext.apply({}, this.dictCfg), + viewConfig : { + forceFit: true, + scrollOffset: 2 // the grid will never have scrollbars + } + }); + + // inhibit the contextmenu in the PropertyGrid + this.grid.on('contextmenu', function (e) {e.stopEvent(); }); + + // instantiate the underlying class + App.form.DictField.superclass.initComponent.call(this); + }, + + /** + * private method requests by the component model of ExtJS + */ + beforeDestroy: function () { + + "use strict"; + + App.form.DictField.superclass.beforeDestroy.call(this); + }, + + /** + * Return the value of this field + */ + getValue: function () { + + "use strict"; + return Ext.apply({}, this.grid.getSource()); + }, + + /** + * private + * supersede the base class method to render the grid + * + * @param {Ext.Element} ct The container to render to. + * @param {Object} position The position in the container to render to. + */ + onRender: function (ct, position) { + + "use strict"; + + // hide the default input field + this.autoCreate = { + id: this.id, + name: this.name, + type: 'hidden', + tag: 'input' + }; + + App.form.DictField.superclass.onRender.call(this, ct, position); + + this.wrap = this.el.wrap({cls: 'x-form-field'}); + this.resizeEl = this.positionEl = this.wrap; + this.grid.render(this.wrap); + }, + + /** + * Set the value for this field + * @param {Object} value + */ + setValue: function (value) { + + "use strict"; + + var source = Ext.apply({}, value || this.dictCfg); + this.grid.setSource(source); + + return App.form.DictField.superclass.setValue.call(this, source); + } +}); + +Ext.reg('xdictfield', App.form.DictField); \ No newline at end of file -- GitLab