From 3b22c9e421e352fee9e5d77464baed73f748b9ca Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sun, 28 Jul 2013 23:14:05 +0200 Subject: [PATCH 01/11] First try for bootstrap 3.0 --- .../templates/bootstrapform/field.html | 39 +++++++++---------- bootstrapform/templatetags/bootstrap.py | 19 ++++++++- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bootstrapform/templates/bootstrapform/field.html b/bootstrapform/templates/bootstrapform/field.html index 7c48984..5084629 100644 --- a/bootstrapform/templates/bootstrapform/field.html +++ b/bootstrapform/templates/bootstrapform/field.html @@ -1,24 +1,25 @@ {% load bootstrap %} -
+
{% if field|is_checkbox %} -
-
{% else %}{% if field|is_radio %} - +
{% for choice in field %} @@ -39,7 +39,7 @@
{% else %} - + {{ field }} From ce9541367b4ec47911d250561a6886a8f86d9f93 Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sun, 28 Jul 2013 23:47:08 +0200 Subject: [PATCH 03/11] Remove an help-inline --- bootstrapform/templates/bootstrapform/field.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrapform/templates/bootstrapform/field.html b/bootstrapform/templates/bootstrapform/field.html index b7c5b4d..36dfb88 100644 --- a/bootstrapform/templates/bootstrapform/field.html +++ b/bootstrapform/templates/bootstrapform/field.html @@ -44,7 +44,7 @@ {{ field }} {% for error in field.errors %} - {{ error }} + {{ error }} {% endfor %} {% if field.help_text %} From f68b77401ab6ccb1b2e6632a493c8b66c4b623af Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sat, 10 Aug 2013 18:38:50 +0200 Subject: [PATCH 04/11] Add django_horizontal templatetags --- .../templates/bootstrapform/field.html | 89 ++++++++++--------- bootstrapform/templatetags/bootstrap.py | 63 ++++++++++--- 2 files changed, 97 insertions(+), 55 deletions(-) diff --git a/bootstrapform/templates/bootstrapform/field.html b/bootstrapform/templates/bootstrapform/field.html index 36dfb88..100ff1d 100644 --- a/bootstrapform/templates/bootstrapform/field.html +++ b/bootstrapform/templates/bootstrapform/field.html @@ -1,14 +1,57 @@ {% load bootstrap %} +
{% if field|is_checkbox %} -
- +
+
+ + + {% for error in field.errors %} + {{ error }} + {% endfor %} + + {% if field.help_text %} +

+ {{ field.help_text|safe }} +

+ {% endif %} +
+
+ {% else %}{% if field|is_radio %} + + +
+
+ {% for choice in field %} + + {% endfor %} + + {% for error in field.errors %} + {{ error }} + {% endfor %} + + {% if field.help_text %} +

+ {{ field.help_text|safe }} +

+ {% endif %} +
+
+ + {% else %} + + +
+ {{ field }} {% for error in field.errors %} {{ error }} - {% endfor %} + {% endfor %} {% if field.help_text %}

@@ -16,41 +59,5 @@

{% endif %}
- {% else %}{% if field|is_radio %} - - -
- {% for choice in field %} - - {% endfor %} - - {% for error in field.errors %} - {{ error }} - {% endfor %} - - {% if field.help_text %} -

- {{ field.help_text|safe }} -

- {% endif %} -
- - {% else %} - - - {{ field }} - - {% for error in field.errors %} - {{ error }} - {% endfor %} - - {% if field.help_text %} -

- {{ field.help_text|safe }} -

- {% endif %} {% endif %}{% endif %}
diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index 4efc1c0..d0b6af8 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -4,41 +4,76 @@ from django import template register = template.Library() - @register.filter def bootstrap(element): + markup_classes = {'label': '', 'value': '', 'single_value': ''} + + render(element, markup_classes) + +@register.filter +def bootstrap_horizontal(element, label_cols={}): + if not label_cols: + label_cols = 'col-sm-2 col-lg-2' + + markup_classes = {'label': label_cols, + 'value': '', + 'single_value': ''} + + for cl in label_cols.split(' '): + splited_class = cl.split('-') + + try: + value_nb_cols = int(splited_class[-1]) + except ValueError: + value_nb_cols = 12 + + if value_nb_cols >= 12: + splited_class[-1] = 12 + else: + offset_class = cl.split('-') + offset_class[-1] = 'offset-' + str(value_nb_cols) + splited_class[-1] = str(12 - value_nb_cols) + markup_classes['single_value'] += ' ' + '-'.join(offset_class) + markup_classes['single_value'] += ' ' + '-'.join(splited_class) + + markup_classes['value'] += ' ' + '-'.join(splited_class) + + return render(element, markup_classes) + +import sys + +def render(element, markup_classes): element_type = element.__class__.__name__.lower() if element_type == 'boundfield': - classes = element.field.widget.attrs.get('class', '') - classes += ' form-control' - element.field.widget.attrs['class'] = classes + field_classes = element.field.widget.attrs.get('class', '') + field_classes += ' form-control' + element.field.widget.attrs['class'] = field_classes template = get_template("bootstrapform/field.html") - context = Context({'field': element}) + context = Context({'field': element, 'classes': markup_classes}) else: has_management = getattr(element, 'management_form', None) if has_management: for form in element.forms: for field in form.visible_fields(): - classes = field.field.widget.attrs.get('class', '') - classes += ' form-control' - field.field.widget.attrs['class'] = classes + field_classes = field.field.widget.attrs.get('class', '') + field_classes += ' form-control' + field.field.widget.attrs['class'] = field_classes template = get_template("bootstrapform/formset.html") - context = Context({'formset': element}) + context = Context({'formset': element, 'classes': markup_classes}) else: for field in element.visible_fields(): - classes = field.field.widget.attrs.get('class', '') - classes += ' form-control' - field.field.widget.attrs['class'] = classes + field_classes = field.field.widget.attrs.get('class', '') + field_classes += ' form-control' + field.field.widget.attrs['class'] = field_classes template = get_template("bootstrapform/form.html") - context = Context({'form': element}) + context = Context({'form': element, 'classes': markup_classes}) return template.render(context) - @register.filter def is_checkbox(field): return field.field.widget.__class__.__name__.lower() == "checkboxinput" From c714ad77138bccdb8fb68f350fe81eed9c1031e3 Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sat, 10 Aug 2013 18:46:20 +0200 Subject: [PATCH 05/11] Fix checkbox --- bootstrapform/templatetags/bootstrap.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index d0b6af8..3ae2e93 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -7,9 +7,9 @@ register = template.Library() @register.filter def bootstrap(element): markup_classes = {'label': '', 'value': '', 'single_value': ''} - render(element, markup_classes) + @register.filter def bootstrap_horizontal(element, label_cols={}): if not label_cols: @@ -40,16 +40,19 @@ def bootstrap_horizontal(element, label_cols={}): return render(element, markup_classes) -import sys + +def add_input_classes(field): + if not is_checkbox(field): + field_classes = field.field.widget.attrs.get('class', '') + field_classes += ' form-control' + field.field.widget.attrs['class'] = field_classes + def render(element, markup_classes): element_type = element.__class__.__name__.lower() if element_type == 'boundfield': - field_classes = element.field.widget.attrs.get('class', '') - field_classes += ' form-control' - element.field.widget.attrs['class'] = field_classes - + add_input_classes(element) template = get_template("bootstrapform/field.html") context = Context({'field': element, 'classes': markup_classes}) else: @@ -57,17 +60,13 @@ def render(element, markup_classes): if has_management: for form in element.forms: for field in form.visible_fields(): - field_classes = field.field.widget.attrs.get('class', '') - field_classes += ' form-control' - field.field.widget.attrs['class'] = field_classes + add_input_classes(field) template = get_template("bootstrapform/formset.html") context = Context({'formset': element, 'classes': markup_classes}) else: for field in element.visible_fields(): - field_classes = field.field.widget.attrs.get('class', '') - field_classes += ' form-control' - field.field.widget.attrs['class'] = field_classes + add_input_classes(field) template = get_template("bootstrapform/form.html") context = Context({'form': element, 'classes': markup_classes}) From 808ae07ca328bba83b92129006631198610e24ea Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sat, 10 Aug 2013 19:07:50 +0200 Subject: [PATCH 06/11] Fix bootstrap templatetag --- bootstrapform/templatetags/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index 3ae2e93..960fb3e 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -7,7 +7,7 @@ register = template.Library() @register.filter def bootstrap(element): markup_classes = {'label': '', 'value': '', 'single_value': ''} - render(element, markup_classes) + return render(element, markup_classes) @register.filter From 0f92783a357c3b0413ff73d722859a3130fd30f3 Mon Sep 17 00:00:00 2001 From: Melvin Date: Sat, 10 Aug 2013 19:21:08 +0200 Subject: [PATCH 07/11] Add bootstrap_horizontal to the doc --- docs/install.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/install.rst b/docs/install.rst index c07331f..9ed7b2d 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -50,9 +50,14 @@ Usage {{ form|bootstrap }} # or use with individual field - {{ form.|bootstrap }} - To output individual fields + # For horizontal forms + {{ form|bootstrap_horizontal }} + + # Or with custom size (default is 'col-lg-2 col-sm-2') + {{ form|bootstrap_horizontal:'col-lg-4' }} + CHANGELOG --------- From ac106c2a834f8e12d359c8577646ef3c48d42f86 Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sun, 11 Aug 2013 22:28:39 +0200 Subject: [PATCH 08/11] Handle checkboxselectmultiple fields --- bootstrapform/templatetags/bootstrap.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index 960fb3e..123969b 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -42,7 +42,7 @@ def bootstrap_horizontal(element, label_cols={}): def add_input_classes(field): - if not is_checkbox(field): + if not is_checkbox(field) and not is_multiple_checkbox(field): field_classes = field.field.widget.attrs.get('class', '') field_classes += ' form-control' field.field.widget.attrs['class'] = field_classes @@ -73,11 +73,17 @@ def render(element, markup_classes): return template.render(context) + @register.filter def is_checkbox(field): return field.field.widget.__class__.__name__.lower() == "checkboxinput" +@register.filter +def is_multiple_checkbox(field): + return field.field.widget.__class__.__name__.lower() == "checkboxselectmultiple" + + @register.filter def is_radio(field): return field.field.widget.__class__.__name__.lower() == "radioselect" From aeedb1c8a1f05b10baebca8b8450874b8076576e Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Fri, 16 Aug 2013 00:53:00 +0200 Subject: [PATCH 09/11] Add bootstrap_inline filter --- bootstrapform/templatetags/bootstrap.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index 123969b..a9d8e33 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -10,6 +10,12 @@ def bootstrap(element): return render(element, markup_classes) +@register.filter +def bootstrap_inline(element): + markup_classes = {'label': 'sr-only', 'value': '', 'single_value': ''} + return render(element, markup_classes) + + @register.filter def bootstrap_horizontal(element, label_cols={}): if not label_cols: From f62b0d8be7f2f68a72d7c0f1a42ece3a8e4c0962 Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sat, 24 Aug 2013 16:12:26 +0200 Subject: [PATCH 10/11] Fix radio --- .../templates/bootstrapform/field.html | 26 +++++++++---------- bootstrapform/templatetags/bootstrap.py | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bootstrapform/templates/bootstrapform/field.html b/bootstrapform/templates/bootstrapform/field.html index 100ff1d..e59fa6e 100644 --- a/bootstrapform/templates/bootstrapform/field.html +++ b/bootstrapform/templates/bootstrapform/field.html @@ -23,24 +23,24 @@
-
- {% for choice in field %} -
+ {% if field.help_text %} +

+ {{ field.help_text|safe }} +

+ {% endif %}
{% else %} diff --git a/bootstrapform/templatetags/bootstrap.py b/bootstrapform/templatetags/bootstrap.py index a9d8e33..3ab5aac 100644 --- a/bootstrapform/templatetags/bootstrap.py +++ b/bootstrapform/templatetags/bootstrap.py @@ -48,7 +48,7 @@ def bootstrap_horizontal(element, label_cols={}): def add_input_classes(field): - if not is_checkbox(field) and not is_multiple_checkbox(field): + if not is_checkbox(field) and not is_multiple_checkbox(field) and not is_radio(field): field_classes = field.field.widget.attrs.get('class', '') field_classes += ' form-control' field.field.widget.attrs['class'] = field_classes From 13dac42a5398c46ad5f23bf521f434fe3c4afd66 Mon Sep 17 00:00:00 2001 From: Melvin Laplanche Date: Sat, 24 Aug 2013 16:15:04 +0200 Subject: [PATCH 11/11] Fix old class name --- bootstrapform/templates/bootstrapform/form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrapform/templates/bootstrapform/form.html b/bootstrapform/templates/bootstrapform/form.html index 2efee91..37661ae 100644 --- a/bootstrapform/templates/bootstrapform/form.html +++ b/bootstrapform/templates/bootstrapform/form.html @@ -1,5 +1,5 @@ {% if form.non_field_errors %} -
+
× {% for non_field_error in form.non_field_errors %} {{ non_field_error }}