Skip to content
Permalink
Browse files

http://docs.lino-framework.org/blog/2014/0429.html

  • Loading branch information...
lsaffre committed Apr 29, 2014
1 parent ec24294 commit 3748768ed9d8b3e0f4e616d4378562cb7d787078
Showing with 90 additions and 51 deletions.
  1. +31 −0 docs/blog/2014/0429.rst
  2. +14 −1 lino/modlib/iban/config/iban/uppercasetextfield.js
  3. +29 −3 lino/modlib/iban/fields.py
  4. +16 −47 lino/ui/elems.py
@@ -0,0 +1,31 @@
=======================
Tuesday, April 29, 2014
=======================

Formatting IBAN numbers
-----------------------

Lino now renders IBAN numbers as it should:
"EE87 2200 2210 1206 7904" instead of "EE872200221012067904".

The first challenge was a decision: should we store the spaces in the
database or not? My current answer is: we don't store the spaces, we
use a renderer to insert them dynamically.

The second challenge was how to implement this. I made changes in
:mod:`lino.modlib.iban.fields`, :mod:`lino.ui.elems` and
:srcref:`lino/modlib/iban/config/uppercasetextfield.js`. Thanks to
`How to insert space every 4 characters for IBAN registering?
<http://stackoverflow.com/questions/17260238/how-to-insert-space-every-4-characters-for-iban-registering>`_
asked in March 2014 by `Jackyto
<http://stackoverflow.com/users/2354926/jackyto>`_ and answered by
`David Thomas <http://stackoverflow.com/users/82548/david-thomas>`_

The current solution has some drawbacks:

- Works only in a grid (IBAN fields in a Detail window are not
formatted. Which is not a problem since we currently have no
occurence of this case).
- Pressing F2 to start editing causes the formatting to disappear
(waiting for user feedback on this).
- We will also need a renderer for plain HTML and plain text.
@@ -2,9 +2,22 @@ Lino.UppercaseTextField = Ext.extend(Ext.form.TextField,{
style: 'text-transform:uppercase;',
listeners:{
change: function(field, newValue, oldValue){
console.log("20140403 UppercaseTextField",newValue, newValue.toUpperCase());
// console.log("20140403 UppercaseTextField",newValue, newValue.toUpperCase());
field.setRawValue(newValue.toUpperCase());
}
}
});


Lino.iban_renderer = function(
value, metaData, record, rowIndex, colIndex, store)
{
var reg = new RegExp(".{4}", "g");
if(value) {
return value.replace(reg, function (a) { return a + ' '; });
}
return value;
}



@@ -23,6 +23,7 @@

from lino import dd

from lino.utils.jsgen import js_code
from lino.ui.elems import CharFieldElement


@@ -32,6 +33,19 @@ class UppercaseTextFieldElement(CharFieldElement):
value_template = "new Lino.UppercaseTextField(%s)"


class IBANFieldElement(UppercaseTextFieldElement):
def get_column_options(self, **kw):
"""Return a string to be used as
`ext.grid.Column.renderer
<http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.grid.Column-cfg-renderer>`.
"""
kw = super(
UppercaseTextFieldElement, self).get_column_options(**kw)
kw.update(renderer=js_code('Lino.iban_renderer'))
return kw


class UppercaseTextField(models.CharField, dd.CustomField):
"""A custom CharField that accepts only uppercase caracters."""
def create_layout_elem(self, *args, **kw):
@@ -40,12 +54,24 @@ def create_layout_elem(self, *args, **kw):
def to_python(self, value):
if isinstance(value, basestring):
return value.upper()
return value


class IBANField(iban_fields.IBANField, UppercaseTextField):
class BICField(iban_fields.SWIFTBICField, UppercaseTextField):
pass


class BICField(iban_fields.SWIFTBICField, UppercaseTextField):
pass
class IBANField(iban_fields.IBANField, dd.CustomField):

def create_layout_elem(self, *args, **kw):
return IBANFieldElement(*args, **kw)

def to_python(self, value):
if isinstance(value, basestring):
return value.upper().replace(' ', '')
return value

# def get_column_renderer(self):
# return 'Lino.iban_renderer'


@@ -158,26 +158,11 @@ class GridColumn(jsgen.Component):
declare_type = jsgen.DECLARE_INLINE

def __init__(self, layout_handle, index, editor, **kw):
"""
"""
#~ print 20100515, editor.name, editor.__class__
#~ assert isinstance(editor,FieldElement), \
#~ "%s.%s is a %r (expected FieldElement instance)" % (cm.grid.report,editor.name,editor)
#~ if isinstance(editor,BooleanFieldElement):
#~ self.editor = None
#~ else:
#~ if editor.field.__class__.__name__ == "DcAmountField":
#~ print 20130911, editor.editable
self.editor = editor
if editor.grid_column_template is not None:
self.value_template = editor.grid_column_template
kw.update(sortable=True)
# ~ kw.update(submitValue=False) # 20110406
kw.update(colIndex=index)
kw.update(editor.get_column_options())
# ~ kw.update(style='overflow:hidden') # 20130319
# ~ kw.update(style='height:18px') # 20130319
#~ kw.update(hidden=editor.hidden)
if editor.hidden:
kw.update(hidden=True)
if settings.SITE.use_filterRow:
@@ -199,20 +184,19 @@ def __init__(self, layout_handle, index, editor, **kw):
])

if settings.SITE.use_gridfilters and editor.gridfilters_settings:
# 20121120 last minute
if isinstance(editor, FieldElement) and not isinstance(editor.field, fields.VirtualField):
if isinstance(editor, FieldElement) \
and not isinstance(editor.field, fields.VirtualField):
kw.update(filter=editor.gridfilters_settings)
#~ if isinstance(editor,FieldElement) and editor.field.primary_key:
if isinstance(editor, FieldElement):
if settings.SITE.use_quicktips:
#~ if jsgen._for_user_profile.expert:
if settings.SITE.show_internal_field_names:
ttt = "(%s.%s) " % (layout_handle.layout._datasource,
self.editor.field.name)
#~ ttt = "(%s) " % self.editor.field.name
else:
ttt = ''
if self.editor.field.help_text and not "<" in self.editor.field.help_text:
if self.editor.field.help_text and \
not "<" in self.editor.field.help_text:
#~ GridColumn tooltips don't support html
ttt = string_concat(ttt, self.editor.field.help_text)
if ttt:
@@ -224,53 +208,38 @@ def fk_renderer(fld, name):
"""
rpt = fld.rel.to.get_default_table()
if rpt.detail_action is not None:
if rpt.detail_action.get_view_permission(jsgen._for_user_profile):
if rpt.detail_action.get_view_permission(
jsgen._for_user_profile):
return "Lino.fk_renderer('%s','Lino.%s')" % (
name + constants.CHOICES_HIDDEN_SUFFIX,
rpt.detail_action.full_name())

rend = None
if isinstance(editor.field, models.AutoField):
rend = 'Lino.id_renderer'
elif isinstance(editor.field, dd.DisplayField):
rend = 'Lino.raw_renderer'
elif isinstance(editor.field, models.TextField):
rend = 'Lino.text_renderer'
#~ elif isinstance(editor.field,models.DecimalField):
#~ rend = 'Lino.hide_zero_renderer'
#~ elif isinstance(editor.field,dd.LinkedForeignKey):
#~ rend = "Lino.lfk_renderer(this,'%s')" % \
#~ (editor.field.name + constants.CHOICES_HIDDEN_SUFFIX)
#~ elif isinstance(editor.field,models.ForeignKey):
elif has_fk_renderer(editor.field):
# if isinstance(editor.field, models.AutoField):
# rend = 'Lino.id_renderer'
# elif isinstance(editor.field, dd.DisplayField):
# rend = 'Lino.raw_renderer'
# elif isinstance(editor.field, models.TextField):
# rend = 'Lino.text_renderer'
# if isinstance(editor.field, fields.CustomField):
# rend = editor.field.get_column_renderer()
if has_fk_renderer(editor.field):
rend = fk_renderer(editor.field, editor.field.name)
elif isinstance(editor.field, fields.VirtualField):
kw.update(sortable=False)
if has_fk_renderer(editor.field.return_type):
rend = fk_renderer(
editor.field.return_type, editor.field.name)
#~ elif isinstance(editor.field.return_type,models.DecimalField):
#~ print "20120510 Lino.hide_zero_renderer", editor.field.name
#~ rend = 'Lino.hide_zero_renderer'
#~ elif isinstance(editor.field,dd.GenericForeignKeyIdField):
#~ rend = "Lino.gfk_renderer()"
if rend:
kw.update(renderer=js_code(rend))
kw.update(editable=editor.editable)
#~ if editor.editable:
if editor.editable and not isinstance(editor, BooleanFieldElement):
kw.update(editor=editor)
#~ if str(editor.layout_handle.layout._datasource) == 'pcsw.CoachingsByProject':
#~ if editor.name == 'user':
#~ print 20120919, editor.field.__class__, editor.field.editable
#~ print 20120919, editor.field.model, kw['editable']

else:
kw.update(editable=False)
kw.update(editor.get_column_options())
jsgen.Component.__init__(self, editor.name, **kw)

#~ if self.editable:
#~ editor = self.get_field_options()
def ext_options(self, **kw):
kw = jsgen.Component.ext_options(self, **kw)
if self.editor.field is not None:

0 comments on commit 3748768

Please sign in to comment.
You can’t perform that action at this time.