def form_helper(button=None, form=None, formset=None, form_tag=False, label_size=4, label_offset=0, field_size=8): helper = FormHelper() helper.form_tag = form_tag if label_size: helper.label_class = "col-md-{}".format(label_size) helper.field_class = "col-md-{}".format(field_size) if label_offset: helper.label_size = ' col-md-offset-{}'.format(label_offset) if form: helper.add_layout(helper.build_default_layout(form)) if formset: helper.template = "bootstrap/table_inline_formset.html" if form and button: helper.layout.fields.append( Div(Div(StrictButton(button, css_class="btn btn-default", type="submit"), css_class="col-md-{} col-md-offset-{}".format( field_size, (label_size + label_offset))), css_class="form-group")) return helper
class CashInvoicePaymentForm(Form): receipt_number = fields.IntegerField() amount = fields.DecimalField(max_digits=8, decimal_places=2, validators=[validators.MinValueValidator(0)]) def __init__(self, *args, instance, **kwargs): super().__init__(*args, **kwargs) self.instance = instance self.helper = FormHelper() self.helper.include_media = False layout = self.helper.build_default_layout(self) layout.fields.append( ButtonHolder( Submit('pay', 'Record Payment'), HTML( '<a href="{}" class="btn btn-secondary">Cancel</a>'.format( reverse( 'front_desk.check_in', kwargs={ 'username': self.instance.recipient.username }, ))))) self.helper.add_layout(layout) def clean_amount(self): amount = self.cleaned_data['amount'] expected_amount = self.instance.total if amount != expected_amount: raise ValidationError( 'The invoice was for USD {}'.format(expected_amount)) return amount
class RegisterOnSiteForm(Form): name = fields.CharField() username = fields.CharField(validators=[ validators.RegexValidator( r'^[\w.@+-]+$', 'Enter a valid username. This value may contain only letters, ' 'numbers and @/./+/-/_ characters.', 'invalid') ]) email = fields.EmailField() departure = fields.DateTimeField() coc_ack = fields.BooleanField(label='Agrees to abide by CoC') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.include_media = False layout = self.helper.build_default_layout(self) layout.fields.append( ButtonHolder( Submit('register', 'Register'), HTML( '<a href="{}" class="btn btn-secondary">Cancel</a>'.format( reverse('front_desk'))), )) self.helper.add_layout(layout) def clean_username(self): username = self.cleaned_data['username'] if get_user_model().objects.filter(username=username).exists(): raise ValidationError('User with this username already exists') return username def clean_email(self): email = self.cleaned_data['email'] if get_user_model().objects.filter(email=email).exists(): raise ValidationError('User with this email already exists') return email
def get_render(context, form, helper, template_pack, is_subform): is_formset = isinstance(form, BaseFormSet) if helper is None: helper = 'helper' # Resolve actual helper. # If we have a helper we use it, for the form or the formset's forms actual_helper = None layout = None if isinstance(helper, FormHelper): actual_helper = helper elif isinstance(helper, six.string_types): helper, _, layout = helper.partition('.') if not helper: helper = 'helper' # If the user names the helper within the form `helper` (standard), we use it # This allows us to have simplified tag syntax: {% crispy form %} try: _helper = getattr(form, helper, None) or form.helper if _helper is not None: actual_helper = _helper except AttributeError: pass # Use formset's helper from above, if any, otherwise fallback # to formset's form's helper. if is_formset and not actual_helper: try: actual_formset = form.form() _helper = getattr(actual_formset, helper, None) or actual_formset.helper if _helper is not None: actual_helper = _helper except AttributeError: pass if not isinstance(actual_helper, FormHelper): actual_helper = FormHelper(form=form) if not layout: layout = 'layout' # Resolve actual layout. actual_layout = getattr(actual_helper, layout, None) or actual_helper.layout # print # print 'form', form.__module__, repr(form) # print 'helper', '(%s)' % helper, actual_helper.__module__, repr(actual_helper) # print 'layout', '(%s)' % layout, actual_layout.__module__, repr(actual_layout) if actual_layout is None: actual_layout = actual_helper.build_default_layout(form) # We get the response dictionary response_dict = get_response_dict(context, actual_helper, actual_layout, is_formset, template_pack, is_subform) context.update(response_dict) if actual_layout: # FIXME: THESE CHANGE HELPER'S STATE (SHOULD NEVER DO THIS DURING RENDER): if is_formset: forloop = ForLoopSimulator(form) actual_helper.render_hidden_fields = True for _form in form: context.update({'forloop': forloop}) _form.form_html = actual_layout.render_layout(_form, context, template_pack=template_pack) forloop.iterate() else: form.form_html = actual_layout.render_layout(form, context, template_pack=template_pack) # Add rendered inputs. if response_dict['inputs'] and response_dict['form_tag']: response_dict['inputs'] = [i.render(form, response_dict['form_style'], context, template_pack=template_pack) for i in response_dict['inputs']] else: response_dict['inputs'] = None # Add form or formset. if is_formset: response_dict['formset'] = form else: response_dict['form'] = form # Add template. _template = getattr(actual_helper, 'template', None) if not _template: if is_formset: _template = '%s/whole_crispy_formset.html' % template_pack else: _template = '%s/whole_crispy_form.html' % template_pack response_dict['template'] = _template return Context(response_dict)