Exemple #1
0
def render_form(form,
                layout='',
                field_class='',
                label_class='',
                show_help=True,
                exclude=''):
    if not isinstance(form, BaseForm):
        raise BootstrapError(
            'Parameter "form" should contain a valid Django Form.')
    html = ''
    errors = []
    fields = []
    for field in form:
        fields.append(
            render_field(
                field,
                layout=layout,
                field_class=field_class,
                label_class=label_class,
                show_help=show_help,
                exclude=exclude,
            ))
        if field.is_hidden and field.errors:
            errors += field.errors
    errors += form.non_field_errors()
    if errors:
        html += '<div class="alert alert-danger">%s</div>\n' % '\n'.join(
            ['<p>%s</p>' % e for e in errors])
    return html + '\n'.join(fields)
Exemple #2
0
def url_to_attrs_dict(url, url_attr):
    """Sanitize url dict as used in django-bootstrap3 settings."""
    result = dict()
    # If url is not a string, it should be a dict
    if isinstance(url, str):
        url_value = url
    else:
        try:
            url_value = url["url"]
        except TypeError:
            raise BootstrapError('Function "url_to_attrs_dict" expects a string or a dict with key "url".')
        crossorigin = url.get("crossorigin", None)
        integrity = url.get("integrity", None)
        if crossorigin:
            result["crossorigin"] = crossorigin
        if integrity:
            result["integrity"] = integrity
    result[url_attr] = url_value
    return result
def render_field(field, inline=False, horizontal=False, field_class=None, label_class=None, show_label=True, show_help=True):
    if not isinstance(field, BoundField):
        raise BootstrapError('Parameter "field" should contain a valid Django BoundField.' + field)
    # Hidden input required no special treatment
    if field.is_hidden:
        return force_text(field)

    # Read widgets attributes
    widget_attr_class = field.field.widget.attrs.get('class', '')
    widget_attr_placeholder = field.field.widget.attrs.get('placeholder', '')
    widget_attr_title = field.field.widget.attrs.get('title', '')

    # Class to add to field element
    if isinstance(field.field.widget, widgets.FileInput):
        form_control_class = ''
    else:
        form_control_class = 'form-control'
        # Convert this widget from HTML list to a wrapped class?
    list_to_class = False
    # Wrap rendered field in its own label?
    put_inside_label = False
    # Wrapper for the final result (should contain %s if not empty)
    wrapper = ''

    # Adjust workings for various widget types
    if isinstance(field.field.widget, widgets.CheckboxInput):
        form_control_class = ''
        put_inside_label = True
        wrapper = '<div class="checkbox">%s</div>'
    elif isinstance(field.field.widget, widgets.RadioSelect):
        form_control_class = ''
        list_to_class = 'radio'
    elif isinstance(field.field.widget, widgets.CheckboxSelectMultiple):
        form_control_class = ''
        list_to_class = 'checkbox'

    # Temporarily adjust to widget class and placeholder attributes if necessary
    if form_control_class:
        field.field.widget.attrs['class'] = add_css_class(widget_attr_class, form_control_class)
    if field.label and not put_inside_label and not widget_attr_placeholder:
        field.field.widget.attrs['placeholder'] = field.label
    if show_help and not put_inside_label and not widget_attr_title:
        field.field.widget.attrs['title'] = field.help_text

    # Render the field
    rendered_field = force_text(field)

    # Return class and placeholder attributes to original settings
    field.field.widget.attrs['class'] = widget_attr_class
    field.field.widget.attrs['placeholder'] = widget_attr_placeholder
    field.field.widget.attrs['title'] = widget_attr_title

    # Handle widgets that are rendered as lists
    if list_to_class:
        mapping = [
            ('<ul', '<div'),
            ('</ul>', '</div>'),
            ('<li', '<div class="%s"' % list_to_class),
            ('</li>', '</div>'),
        ]
        for k, v in mapping:
            rendered_field = rendered_field.replace(k, v)

    # Wrap the rendered field in its label if necessary
    if put_inside_label:
        rendered_field = render_label('%s %s' % (rendered_field, field.label,),
                                      label_title=field.help_text)

    # Add any help text and/or errors
    if not inline:
        help_text_and_errors = []
        if show_help and field.help_text:
            help_text_and_errors.append(field.help_text)
        if field.errors:
            help_text_and_errors += field.errors
        if help_text_and_errors:
            rendered_field += '<span class="help-block">%s</span>' % ' '.join(
                force_text(s) for s in help_text_and_errors
            )

    # Wrap the rendered field
    if wrapper:
        rendered_field = wrapper % rendered_field

    # Prepare label, horizontal forms require a small trick
    label = field.label
    if put_inside_label:
        label = None
    if inline or not show_label:
        label_class = add_css_class(label_class, 'sr-only')

    # Render label and field
    content = render_field_and_label(
        field=rendered_field,
        label=label,
        field_class=field_class,
        label_class=label_class,
        horizontal=horizontal,
    )

    # Return combined content, wrapped in form control
    form_group_class = ''
    if field.errors:
        form_group_class = 'has-error'
    elif field.form.is_bound:
        form_group_class = 'has-success'
    return render_form_group(content, form_group_class)
def render_formset(formset, **kwargs):
    if not isinstance(formset, BaseFormSet):
        raise BootstrapError('Parameter "formset" should contain a valid Django FormSet.')
    forms = [render_form(f, **kwargs) for f in formset]
    return force_text(formset.management_form) + '\n' + '\n'.join(forms)