Commit 638e150c authored by iCaiCai's avatar iCaiCai

Add Form grid and Input group

parent 58c384d4
......@@ -359,6 +359,157 @@ class FieldSet(NestedRule):
super(FieldSet, self).__init__(rule_set, separator=separator)
class Row(NestedRule):
def __init__(self, *columns, **kw):
super(Row, self).__init__()
self.rules = columns
def __call__(self, form, form_opts=None, field_args={}):
cols = []
for col in self.rules:
if col.visible_fields:
w_args = form_opts.widget_args.setdefault(col.visible_fields[0], {})
w_args.setdefault('column_class', 'col')
cols.append(col(form, form_opts, field_args))
return Markup('<div class="form-row">%s</div>' % ''.join(cols))
class Group(Macro):
def __init__(self, field_name, *args, prepend=None, append=None, **kwargs):
'''
Bootstrap Input group.
'''
render_field = kwargs.get('render_field', 'lib.render_field')
super(Group, self).__init__(render_field)
self.field_name = field_name
self._addons = []
for cnf in args:
if isinstance(cnf, str):
self._addons.append({
'pos': 'append',
'type': 'text',
'text': cnf
})
continue
if cnf['type'] in ('field', 'html', 'text'):
cnf.setdefault('pos', 'append')
self._addons.append(cnf)
if prepend:
if not isinstance(prepend, (tuple, list)):
prepend = [prepend]
for cnf in prepend:
if isinstance(cnf, str):
self._addons.append({
'pos': 'prepend',
'type': 'text',
'text': cnf
})
continue
if cnf['type'] in ('field', 'html', 'text'):
cnf['pos'] = 'prepend'
self._addons.append(cnf)
if append:
if not isinstance(append, (tuple, list)):
append = [append]
for cnf in append:
if isinstance(cnf, str):
self._addons.append({
'pos': 'append',
'type': 'text',
'text': cnf
})
continue
if cnf['type'] in ('field', 'html', 'text'):
cnf['pos'] = 'append'
self._addons.append(cnf)
print(self._addons)
@property
def visible_fields(self):
fields = [self.field_name]
for cnf in self._addons:
if cnf['type'] == 'field':
fields.append(cnf['name'])
return fields
def __call__(self, form, form_opts=None, field_args={}):
"""
Render field.
:param form:
Form object
:param form_opts:
Form options
:param field_args:
Optional arguments that should be passed to template or the field
"""
field = getattr(form, self.field_name, None)
if field is None:
raise ValueError('Form %s does not have field %s' % (form, self.field_name))
if form_opts:
widget_args = form_opts.widget_args
else:
widget_args = {}
opts = {}
prepend = []
append = []
for cnf in self._addons:
ctn = None
typ = cnf['type']
if typ == 'field':
name = cnf['name']
fld = form._fields.get(name, None)
if fld:
w_args = widget_args.setdefault(name, {})
if fld.type in ('BooleanField', 'RadioField'):
w_args.setdefault('class', 'form-check-input')
else:
w_args.setdefault('class', 'form-control')
ctn = fld(**w_args)
elif typ == 'text':
ctn = '<span class="input-group-text">%s</span>' % cnf['text']
elif typ == 'html':
ctn = cnf['html']
if ctn:
if cnf['pos'] == 'prepend':
prepend.append(ctn)
else:
append.append(ctn)
if prepend:
opts['prepend'] = Markup(''.join(prepend))
if append:
opts['append'] = Markup(''.join(append))
opts.update(widget_args.get(self.field_name, {}))
opts.update(field_args)
params = {
'form': form,
'field': field,
'kwargs': opts
}
return super(Group, self).__call__(form, form_opts, params)
class RuleSet(object):
"""
Rule set.
......@@ -406,6 +557,9 @@ class RuleSet(object):
for r in rules:
if isinstance(r, string_types):
result.append(self.convert_string(r).configure(self, parent))
elif isinstance(r, (tuple, list)):
row = Row(*r)
result.append(row.configure(self, parent))
else:
try:
result.append(r.configure(self, parent))
......
......@@ -100,7 +100,7 @@
{# ---------------------- Modal Window ------------------- #}
{% macro add_modal_window(modal_window_id='fa_modal_window', modal_label_id='fa_modal_label') %}
<div class="modal fade" id="{{ modal_window_id }}" tabindex="-1" role="dialog" aria-labelledby="{{ modal_label_id }}">
<div class="modal-dialog" role="document">
<div class="modal-dialog modal-xl" role="document">
{# bootstrap version > 3.1.0 required for this to work #}
<div class="modal-content">
</div>
......@@ -117,28 +117,46 @@
{# ---------------------- Forms -------------------------- #}
{% macro render_field(form, field, kwargs={}, caller=None) %}
{% set direct_error = h.is_field_error(field.errors) %}
<div class="form-group{{ ' has-error' if direct_error else '' }}">
<label for="{{ field.id }}" class="col-md-2 control-label">{{ field.label.text }}
{% set prepend = kwargs.pop('prepend', None) %}
{% set append = kwargs.pop('append', None) %}
<div class="form-group {{ kwargs.get('column_class', '') }}">
<label for="{{ field.id }}" class="control-label">{{ field.label.text }}
{% if h.is_required_form_field(field) %}
<strong style="color: red">&#42;</strong>
{%- else -%}
&nbsp;
{%- endif %}
</label>
<div class="{{ kwargs.get('column_class', 'col-md-10') }}">
{% set _dummy = kwargs.setdefault('class', 'form-control') %}
{{ field(**kwargs)|safe }}
{% if field.description %}
<p class="help-block">{{ field.description|safe }}</p>
{% if prepend or append %}
<div class="input-group">
{%- if prepend -%}
<div class="input-group-prepend">
{{ prepend }}
</div>
{%- endif -%}
{% endif %}
{% set _class = kwargs.setdefault('class', 'form-control') %}
{%- if direct_error %} {% set _ = kwargs.update({'class': kwargs['class'] ~ ' is-invalid'}) %} {% endif -%}
{{ field(**kwargs) | safe }}
{%- if append -%}
<div class="input-group-append">
{{ append }}
</div>
{%- endif -%}
{% if direct_error %}
<ul class="help-block input-errors">
<div class="invalid-feedback">
<ul class="help-block">
{% for e in field.errors if e is string %}
<li>{{ e }}</li>
{% endfor %}
</ul>
</div>
{% elif field.description %}
<div class="help-block">{{ field.description|safe }}</div>
{% endif %}
{% if prepend or append %}
</div>
{% endif %}
{% if caller %}
{{ caller(form, field, direct_error, kwargs) }}
{% endif %}
......@@ -178,7 +196,7 @@
{% endmacro %}
{% macro form_tag(form=None, action=None) %}
<form action="{{ action or '' }}" method="POST" role="form" class="admin-form form-horizontal" enctype="multipart/form-data">
<form action="{{ action or '' }}" method="POST" role="form" class="admin-form" enctype="multipart/form-data">
<fieldset>
{{ caller() }}
</fieldset>
......@@ -186,6 +204,15 @@
{% endmacro %}
{% macro render_form_buttons(cancel_url, extra=None, is_modal=False) %}
{% if is_modal %}
<input type="submit" class="btn btn-primary" value="{{ _gettext('Save') }}" />
{% if extra %}
{{ extra }}
{% endif %}
{% if cancel_url %}
<a href="{{ cancel_url }}" class="btn btn-danger" role="button" {% if is_modal %}data-dismiss="modal"{% endif %}>{{ _gettext('Cancel') }}</a>
{% endif %}
{% else %}
<hr>
<div class="form-group">
<div class="col-md-offset-2 col-md-10 submit-row">
......@@ -198,6 +225,7 @@
{% endif %}
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_form(form, cancel_url, extra=None, form_opts=None, action=None, is_modal=False) -%}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment