forms.py 4.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from functools import partial
  2. import itertools
  3. from flask.ext.wtf import Form
  4. from wtforms import Form as InsecureForm
  5. from wtforms import TextField, DateField, DecimalField, SelectField, SelectMultipleField, FieldList, FormField
  6. from wtforms.widgets import TextInput, ListWidget, html_params, HTMLString, CheckboxInput, Select
  7. from wtforms.validators import DataRequired, Optional, URL, Email, Length, NumberRange, ValidationError
  8. from flask.ext.babel import Babel, gettext as _
  9. from .constants import STEPS
  10. from .models import ISP
  11. class InputListWidget(ListWidget):
  12. def __call__(self, field, **kwargs):
  13. kwargs.setdefault('id', field.id)
  14. html = ['<%s %s>' % (self.html_tag, html_params(**kwargs))]
  15. for subfield in field:
  16. html.append('<li>%s</li>' % (subfield()))
  17. html.append('</%s>' % self.html_tag)
  18. return HTMLString(''.join(html))
  19. class MultiCheckboxField(SelectMultipleField):
  20. """
  21. A multiple-select, except displays a list of checkboxes.
  22. Iterating the field will produce subfields, allowing custom rendering of
  23. the enclosed checkbox fields.
  24. """
  25. widget = ListWidget(prefix_label=False)
  26. option_widget = CheckboxInput()
  27. class MyFormField(FormField):
  28. @property
  29. def flattened_errors(self):
  30. return list(itertools.chain.from_iterable(self.errors.values()))
  31. class Unique(object):
  32. """ validator that checks field uniqueness """
  33. def __init__(self, model, field, message=None):
  34. self.model = model
  35. self.field = field
  36. if not message:
  37. message = u'this element already exists'
  38. self.message = message
  39. def __call__(self, form, field):
  40. check = self.model.query.filter(self.field == field.data).first()
  41. print "lol", check, self.field, field.data
  42. if check:
  43. raise ValidationError(self.message)
  44. TECHNOLOGIES_CHOICES=(
  45. ('ftth', _('FTTH')),
  46. ('dsl', _('DSL')),
  47. ('wifi', _('Wi-Fi')),
  48. )
  49. class CoveredArea(InsecureForm):
  50. area_name = TextField(_(u'name'), widget=partial(TextInput(), class_='input-medium', placeholder=_(u'Area')))
  51. technologies = SelectMultipleField(_(u'technologies'), choices=TECHNOLOGIES_CHOICES,
  52. widget=partial(Select(True), **{'class': 'selectpicker', 'data-title': _(u'Technologies deployed')}))
  53. # area =
  54. class ProjectForm(Form):
  55. name = TextField(_(u'full name'), description=[_(u'E.g. French Data Network')],
  56. validators=[DataRequired(), Length(min=2), Unique(ISP, ISP.name)])
  57. shortname = TextField(_(u'short name'), description=[_(u'E.g. FDN')],
  58. validators=[Optional(), Length(min=2, max=15), Unique(ISP, ISP.shortname)])
  59. description = TextField(_(u'description'), description=[None, _(u'Short text describing the project')])
  60. logo_url = TextField(_(u'logo url'), validators=[Optional(), URL(require_tld=True)])
  61. website = TextField(_(u'website'), validators=[Optional(), URL(require_tld=True)])
  62. contact_email = TextField(_(u'contact email'), validators=[Optional(), Email()],
  63. description=[None, _(u'General contact email address')])
  64. main_ml = TextField(_(u'main mailing list'), validators=[Optional(), Email()],
  65. description=[None, u'Address of your main <b>public</b> mailing list'])
  66. creation_date = DateField(_(u'creation date'), validators=[Optional()],
  67. description=[None, u'Date at which the legal structure for your project was created'])
  68. chatrooms = FieldList(TextField(_(u'chatrooms')), min_entries=1, widget=InputListWidget(),
  69. description=[None, _(u'In URI form, e.g. <code>irc://irc.isp.net/#isp</code> or '+
  70. '<code>xmpp:isp@chat.isp.net?join</code>')])
  71. covered_areas = FieldList(MyFormField(CoveredArea, widget=partial(InputListWidget(), class_='formfield')), min_entries=1, widget=InputListWidget(),
  72. description=[None, _(u'Descriptive name of the covered areas and technologies deployed')])
  73. latitude = DecimalField(_(u'latitude'), validators=[Optional()],
  74. description=[None, _(u'Geographical coordinates of your registered office or usual meeting location.')])
  75. longitude = DecimalField(_(u'longitude'), validators=[Optional()])
  76. step = SelectField(_(u'step'), choices=[(k, u'%u - %s' % (k, STEPS[k])) for k in STEPS], coerce=int)
  77. member_count = DecimalField(_(u'Members'), validators=[Optional(), NumberRange(min=0)],
  78. description=[None, _('Number of members')])
  79. subscriber_count = DecimalField(_(u'Subscribers'), validators=[Optional(), NumberRange(min=0)],
  80. description=[None, _('Number of subscribers to an internet access')])