Add a custom widget for address
This commit is contained in:
parent
5bf5e3364b
commit
853befcdb2
|
@ -0,0 +1,77 @@
|
|||
from zope.interface import Interface
|
||||
from zope import schema
|
||||
from zope.schema import Object, Field
|
||||
from zope.schema.interfaces import IObject, IField, IFromUnicode
|
||||
from zope.interface import implements, implementer
|
||||
from zope.component import adapts, adapter, provideAdapter
|
||||
|
||||
from z3c.form.interfaces import IFormLayer, IFieldWidget, NOVALUE
|
||||
from z3c.form.widget import Widget, FieldWidget
|
||||
from z3c.form.interfaces import IWidget
|
||||
from z3c.form.converter import BaseDataConverter
|
||||
|
||||
from themis.datatypes.interfaces import MessageFactory as _
|
||||
|
||||
class IAddress(IField):
|
||||
title = schema.TextLine(title=_(u'Title'), required=False)
|
||||
street = schema.TextLine(title=_(u'Street'), required=False)
|
||||
zipcode = schema.TextLine(title=_(u'Zip'), required=False)
|
||||
city = schema.TextLine(title=_(u'City'), required=False)
|
||||
phone1 = schema.TextLine(title=_(u'Phone'), required=False)
|
||||
phone2 = schema.TextLine(title=_(u'Phone 2'), required=False)
|
||||
fax = schema.TextLine(title=_(u'Fax'), required=False)
|
||||
email = schema.TextLine(title=_(u'Email'), required=False)
|
||||
|
||||
class Address(Field):
|
||||
implements(IAddress, IFromUnicode)
|
||||
|
||||
title = None
|
||||
street = None
|
||||
zipcode = None
|
||||
city = None
|
||||
phone1 = None
|
||||
phone2 = None
|
||||
fax = None
|
||||
email = None
|
||||
|
||||
class IAddressWidget(IWidget):
|
||||
pass
|
||||
|
||||
class AddressWidget(Widget):
|
||||
implements(IAddressWidget)
|
||||
|
||||
def update(self):
|
||||
super(AddressWidget, self).update()
|
||||
|
||||
def extract(self, default=NOVALUE):
|
||||
if not (self.name + '.street') in self.request.form:
|
||||
return NOVALUE
|
||||
address = Address()
|
||||
has_value = None
|
||||
for attr in ('title', 'street', 'zipcode', 'city', 'phone1', 'phone2',
|
||||
'fax', 'email'):
|
||||
setattr(address, attr, self.request.get(self.name + '.' + attr))
|
||||
has_value = has_value or getattr(address, attr)
|
||||
if not has_value:
|
||||
return NOVALUE
|
||||
return address
|
||||
|
||||
|
||||
@adapter(IAddress, IFormLayer)
|
||||
@implementer(IFieldWidget)
|
||||
def AddressFieldWidget(field, request):
|
||||
"""IFieldWidget factory for Address."""
|
||||
return FieldWidget(field, AddressWidget(request))
|
||||
|
||||
|
||||
class AddressConverter(BaseDataConverter):
|
||||
adapts(IAddress, IAddressWidget)
|
||||
|
||||
def toWidgetValue(self, value):
|
||||
if value is None:
|
||||
return Address()
|
||||
return value
|
||||
|
||||
def toFieldValue(self, value):
|
||||
return value
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<div lang="en"
|
||||
xml:lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
||||
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
|
||||
i18n:domain="plone.app.textfield"
|
||||
tal:attributes="id view/id">
|
||||
|
||||
<tal:define define="fieldName view/name">
|
||||
TODO
|
||||
</tal:define>
|
||||
</div>
|
|
@ -0,0 +1,61 @@
|
|||
<div lang="en"
|
||||
xml:lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
||||
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
|
||||
i18n:domain="plone.app.textfield"
|
||||
tal:attributes="id view/id">
|
||||
|
||||
<tal:define define="fieldName view/name">
|
||||
<style type="text/css">
|
||||
.address { margin-left: 2em; }
|
||||
</style>
|
||||
<div class="address">
|
||||
<div class="fieldTitle">
|
||||
<label>Title</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_title;
|
||||
name string:${fieldName}.title;
|
||||
value view/value/title"/>
|
||||
</div>
|
||||
<div class="fieldStreet">
|
||||
<label>Street</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_street;
|
||||
name string:${fieldName}.street;
|
||||
value view/value/street"/>
|
||||
</div>
|
||||
|
||||
<div class="fieldZipCode">
|
||||
<label>Zip Code</label>
|
||||
<input type="text" size="6" tal:attributes="id string:${fieldName}_zipcode;
|
||||
name string:${fieldName}.zipcode;
|
||||
value view/value/zipcode"/>
|
||||
|
||||
<label>City</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_city;
|
||||
name string:${fieldName}.city;
|
||||
value view/value/city"/>
|
||||
</div>
|
||||
|
||||
<div class="fieldContacts">
|
||||
<label>Phone</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_phone1;
|
||||
name string:${fieldName}.phone1;
|
||||
value view/value/phone1"/>
|
||||
<label>Phone (2)</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_phone2;
|
||||
name string:${fieldName}.phone2;
|
||||
value view/value/phone2"/>
|
||||
<br/>
|
||||
<label>Fax</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_fax;
|
||||
name string:${fieldName}.fax;
|
||||
value view/value/fax"/>
|
||||
<label>Email</label>
|
||||
<input type="text" tal:attributes="id string:${fieldName}_email;
|
||||
name string:${fieldName}.email;
|
||||
value view/value/email"/>
|
||||
</div>
|
||||
</div>
|
||||
</tal:define>
|
||||
</div>
|
|
@ -2,6 +2,8 @@
|
|||
xmlns="http://namespaces.zope.org/zope"
|
||||
xmlns:grok="http://namespaces.zope.org/grok"
|
||||
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
||||
xmlns:z3c="http://namespaces.zope.org/z3c"
|
||||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
i18n_domain="themis.datatypes">
|
||||
|
||||
<!-- Include configuration for dependencies listed in setup.py -->
|
||||
|
@ -27,6 +29,19 @@
|
|||
provides="themis.datatypes.deputy.INameFromPersonNames"
|
||||
factory="themis.datatypes.deputy.NameFromPersonNames" />
|
||||
|
||||
<adapter factory=".deputy.AddressFieldWidget"/>
|
||||
<adapter factory=".address.AddressFieldWidget"/>
|
||||
<adapter factory=".address.AddressConverter"/>
|
||||
|
||||
<z3c:widgetTemplate
|
||||
mode="display"
|
||||
widget=".address.IAddressWidget"
|
||||
layer="z3c.form.interfaces.IFormLayer"
|
||||
template="address_display.pt"/>
|
||||
|
||||
<z3c:widgetTemplate
|
||||
mode="input"
|
||||
widget=".address.IAddressWidget"
|
||||
layer="z3c.form.interfaces.IFormLayer"
|
||||
template="address_input.pt"/>
|
||||
|
||||
</configure>
|
||||
|
|
|
@ -21,36 +21,11 @@ from z3c.form.browser.text import TextWidget
|
|||
from z3c.form.interfaces import IFormLayer, IFieldWidget
|
||||
from z3c.form.widget import FieldWidget
|
||||
|
||||
|
||||
from themis.datatypes.interfaces import MessageFactory as _
|
||||
|
||||
from themis.datatypes.polgroup import IPolGroup
|
||||
|
||||
class IAddress(IField):
|
||||
title = schema.TextLine(title=_(u'Title'), required=False)
|
||||
street = schema.TextLine(title=_(u'Street'), required=False)
|
||||
zipcode = schema.TextLine(title=_(u'Zip'), required=False)
|
||||
city = schema.TextLine(title=_(u'City'), required=False)
|
||||
phone1 = schema.TextLine(title=_(u'Phone'), required=False)
|
||||
phone2 = schema.TextLine(title=_(u'Phone 2'), required=False)
|
||||
fax = schema.TextLine(title=_(u'Fax'), required=False)
|
||||
email = schema.TextLine(title=_(u'Email'), required=False)
|
||||
|
||||
class Address(Field):
|
||||
implements(IAddress, IFromUnicode)
|
||||
|
||||
def fromUnicode(self, str):
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return u'/'.join([x for x in (self.title, self.street, self.zipcode, self.city) if x])
|
||||
|
||||
@adapter(IAddress, IFormLayer)
|
||||
@implementer(IFieldWidget)
|
||||
def AddressFieldWidget(field, request):
|
||||
"""IFieldWidget factory for Address."""
|
||||
return FieldWidget(field, TextWidget(request))
|
||||
|
||||
from address import Address
|
||||
|
||||
class IDeputy(form.Schema):
|
||||
firstname = schema.TextLine(title=_(u'First Name'))
|
||||
|
|
Reference in New Issue