Skip to content

Commit

Permalink
Fix widget render. Close #60
Browse files Browse the repository at this point in the history
  • Loading branch information
kmmbvnr committed Jul 21, 2014
1 parent b3c1868 commit c0930f8
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 28 deletions.
2 changes: 2 additions & 0 deletions tests/examples/helloworld/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@


class HelloWorldFlowTests(TestCase):
fixtures = ['helloworld/default_data.json']

def test_normal_flow_succeed(self):
with FlowTest(HelloWorldFlow) as flow:
# The `employee` starts process
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from datetime import datetime
from django import forms
from django.conf import settings

Expand All @@ -10,8 +11,8 @@ class AllElementsForm(forms.Form):
choices_field = forms.ChoiceField(choices=((('1', 'One'), ('2', 'Two'), ('3', 'Three'))))
choices_radio_field = forms.ChoiceField(choices=((('1', 'One'), ('2', 'Two'), ('3', 'Three'))),
widget=forms.RadioSelect)
date_field = forms.DateField(input_formats=['%d.%m.%Y'])
datetime_field = forms.DateTimeField(input_formats=['%Y-%m-%d %H:%M:%S'])
date_field = forms.DateField(input_formats=['%d.%m.%Y'], initial=datetime.now())
datetime_field = forms.DateTimeField(input_formats=['%d.%m.%Y %H:%M'], initial=datetime.now())
decimal_field = forms.DecimalField(max_value=100, min_value=10, max_digits=5, decimal_places=2)
email_field = forms.EmailField(min_length=5, max_length=50)
file_field = forms.FileField(max_length=250, help_text='Attach any file here')
Expand All @@ -26,7 +27,7 @@ class AllElementsForm(forms.Form):
nullboolean_field = forms.NullBooleanField()
regex_field = forms.RegexField(regex='[a-zA-Z]+')
slug_field = forms.SlugField()
time_field = forms.TimeField(input_formats=['%H:%M'])
time_field = forms.TimeField(input_formats=['%H:%M'], initial=datetime.now())
url_field = forms.URLField(min_length=10, max_length=100)
combo_field = forms.ComboField(fields=[forms.CharField(max_length=20), forms.EmailField()])
splitdatetime_field = forms.SplitDateTimeField(input_date_formats=['%d.%m.%Y'], input_time_formats=['%H:%M'])
11 changes: 7 additions & 4 deletions tests/unit/templates/unit/form.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% extends 'viewflow/base_site.html' %}
{% load viewflow %}
{% load viewform %}

{% block content %}
<div class="page-header">
<h1> Form rendering example</h1>
</div>
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" role="tablist">
<li class="active">
Expand All @@ -13,10 +17,9 @@
<div class="tab-content">
<div class="tab-pane active" id="viewflow_tab">
<form method="POST" enctype="multipart/form-data">
{% viewform 'viewflow/form/layout.html' %}
{% viewform 'viewflow/form/bootstrap3/form.html' form=form layout=view.layout %}
{# Add pencil icon on text_input field #}
{% viewpart field_group_class_add 'text_input' %}has-feedback{% endviewpart %}
{% viewpart field_icon 'text_input' %}<span class="glyphicon glyphicon glyphicon-pencil form-control-feedback"></span>{% endviewpart %}
{% viewpart form.text_input.field append %}<span class="glyphicon glyphicon glyphicon-pencil input-group-addon"></span>{% endviewpart %}
{% endviewform %}
</form>
</div>
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/tests/test_datepicker_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.test import TestCase
from django.forms.fields import DateTimeField
from viewflow.site.templatetags import viewform


class TestDatePickerFormatFilter(TestCase):
def test_format_translation(self):
translations = {
'%Y-%m-%d': 'yyyy-mm-dd',
'%m/%d/%Y': 'mm/dd/yyyy',
'%m/%d/%y': 'mm/dd/yy',
'%b %d %Y': 'M dd yyyy',
'%b %d, %Y': 'M dd, yyyy',
'%d %b %Y': 'dd M yyyy',
'%d %b, %Y': 'dd M, yyyy',
'%B %d %Y': 'MM dd yyyy',
'%B %d, %Y': 'MM dd, yyyy',
'%d %B %Y': 'dd MM yyyy',
'%d %B, %Y': 'dd MM, yyyy',
'%Y-%m-%d %H:%M:%S': 'yyyy-mm-dd hh:ii:ss',
'%Y-%m-%d %H:%M': 'yyyy-mm-dd hh:ii',
'%m/%d/%Y %H:%M:%S': 'mm/dd/yyyy hh:ii:ss',
'%m/%d/%Y %H:%M': 'mm/dd/yyyy hh:ii',
'%m/%d/%y %H:%M:%S': 'mm/dd/yy hh:ii:ss',
'%m/%d/%y %H:%M': 'mm/dd/yy hh:ii',
}

for input_format, output_format in translations.items():
field = DateTimeField(input_formats=[input_format])
result = viewform.datepicker_format(field)
self.assertEquals(output_format, result)
8 changes: 4 additions & 4 deletions tests/unit/tests/test_render_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

class TestRenderTag(TestCase):
DEFAULT_RENDER_TEMPLATE = """
{% load viewflow %}
{% viewform 'viewflow/form/layout.html' %}
{% viewpart field 'text_input' %}
REDEFINED
{% load viewform %}
{% viewform 'viewflow/form/bootstrap3/form.html' form=form layout=view.layout %}
{% viewpart form.text_input.field %}
REDEFINED
{% endviewpart %}
{% endviewform %}
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
<div class="form-group">
<label for="dtp_input2" class="control-label">Date Picking</label>
<div class="input-group date" data-date="" data-date-format="dd/mm/yyyy" data-min-view="2" data-viewform-control="date">
<input class="form-control" size="16" type="text" value="">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
{% load viewform %}
<div {% tagattrs %}
class="{% viewpart field group_class %}
form-group
{% if field.required%}required{% endif %}
{% if bound_field.errors %}has-error{% endif %}
{% viewpart field add_group_class %}{% endviewpart %}
{% endviewpart %}"{% endtagattrs %}>
{% viewpart field label %}
<label for="{{ bound_field.id_for_label }}" class="control-label">{{ bound_field.label }}</label>
{% endviewpart %}
<div class="input-group" style="width:100%">
<div {% tagattrs %}
class="input-group date"
data-date-format="{{ field|datepicker_format }}"
data-min-view="2"
data-viewform-control="date"{% endtagattrs %}{% if bound_field.value %} data_date="{{ bound_field|datepicker_value }}"{% endif %}>
{% viewpart field prepend %}{% endviewpart %}{% viewpart field control %}
<input {% tagattrs %}
type="{{ field.widget.input_type }}"
class="form-control"
name="{{ bound_field.html_name }}"
id="id_{{ bound_field.html_name }}"{% endtagattrs %}{% if bound_field.value %} value="{{ bound_field|datepicker_value }}"{% endif %}>
{% endviewpart %}{% viewpart field append %}
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
{% endviewpart %}
</div>
</div>
{% viewpart field errors %}
{% if bound_field.errors %}
{% include 'viewflow/form/bootstrap3/field_errors.html' %}
{% endif %}
{% endviewpart %}{% viewpart field help_text %}
{% if field.help_text %}
<span class="help-block">{{ bound_field.help_text }}</span>
{% endif %}
{% endviewpart %}{{ hidden_initial }}
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
<div class="form-group">
<label for="dtp_input2" class="control-label">DateTime Picking</label>
<div class="input-group date" data-date="" data-date-format="dd/mm/yyyy hh:ii" data-min-view="0" data-viewform-control="datetime">
<input class="form-control" size="16" type="text" value="">
<span class="input-group-addon"> <span class="glyphicon glyphicon-time"></span> </span>
{% load viewform %}
<div {% tagattrs %}
class="{% viewpart field group_class %}
form-group
{% if field.required%}required{% endif %}
{% if bound_field.errors %}has-error{% endif %}
{% viewpart field add_group_class %}{% endviewpart %}
{% endviewpart %}"{% endtagattrs %}>
{% viewpart field label %}
<label for="{{ bound_field.id_for_label }}" class="control-label">{{ bound_field.label }}</label>
{% endviewpart %}
<div class="input-group" style="width:100%">
<div {% tagattrs %}
class="input-group date"
data-date-format="{{ field|datepicker_format }}"
data-min-view="0"
data-viewform-control="datetime"{% endtagattrs %}{% if bound_field|datepicker_value %} data_date="{{ bound_field.value }}"{% endif %}>
{% viewpart field prepend %}{% endviewpart %}{% viewpart field control %}
<input {% tagattrs %}
type="{{ field.widget.input_type }}"
class="form-control"
name="{{ bound_field.html_name }}"
id="id_{{ bound_field.html_name }}"{% endtagattrs %}{% if bound_field.value %} value="{{ bound_field|datepicker_value }}"{% endif %}>
{% endviewpart %}{% viewpart field append %}
<span class="input-group-addon"><span class="glyphicon glyphicon-time" style="font-weight:bold"></span></span>
{% endviewpart %}
</div>
</div>
{% viewpart field errors %}
{% if bound_field.errors %}
{% include 'viewflow/form/bootstrap3/field_errors.html' %}
{% endif %}
{% endviewpart %}{% viewpart field help_text %}
{% if field.help_text %}
<span class="help-block">{{ bound_field.help_text }}</span>
{% endif %}
{% endviewpart %}{{ hidden_initial }}
</div>
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
fileinput
{% load viewform %}
<div {% tagattrs %}
class="{% viewpart field group_class %}
form-group
{% if field.required%}required{% endif %}
{% if bound_field.errors %}has-error{% endif %}
{% viewpart field add_group_class %}{% endviewpart %}
{% endviewpart %}"{% endtagattrs %}>
{% viewpart field label %}
<label for="{{ bound_field.id_for_label }}" class="control-label">{{ bound_field.label }}</label>
{% endviewpart %}
<div class="input-group" style="width:100%">
{% viewpart field prepend %}{% endviewpart %}{% viewpart field control %}
{{ bound_field }}
{% endviewpart %}{% viewpart field append %}{% endviewpart %}
</div>
{% viewpart field errors %}
{% if bound_field.errors %}
{% include 'viewflow/form/bootstrap3/field_errors.html' %}
{% endif %}
{% endviewpart %}{% viewpart field help_text %}
{% if field.help_text %}
<span class="help-block">{{ bound_field.help_text }}</span>
{% endif %}
{% endviewpart %}{{ hidden_initial }}
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
<div class="form-group">
<label for="dtp_input2" class="control-label">Time Picking</label>
<div class="input-group date" data-date="" data-date-format="hh:ii" data-start-view="1" data-viewform-control="time">
<input class="form-control" size="16" type="text" value="">
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
{% load viewform %}
<div {% tagattrs %}
class="{% viewpart field group_class %}
form-group
{% if field.required%}required{% endif %}
{% if bound_field.errors %}has-error{% endif %}
{% viewpart field add_group_class %}{% endviewpart %}
{% endviewpart %}"{% endtagattrs %}>
{% viewpart field label %}
<label for="{{ bound_field.id_for_label }}" class="control-label">{{ bound_field.label }}</label>
{% endviewpart %}
<div class="input-group" style="width:100%">
<div {% tagattrs %}
class="input-group date"
data-date-format="{{ field|datepicker_format }}"
data-start-view="1"
data-viewform-control="time"{% endtagattrs %}{% if bound_field.value %} data_date="{{ bound_field|datepicker_value }}"{% endif %}>
{% viewpart field prepend %}{% endviewpart %}{% viewpart field control %}
<input {% tagattrs %}
type="{{ field.widget.input_type }}"
class="form-control"
name="{{ bound_field.html_name }}"
id="id_{{ bound_field.html_name }}"{% endtagattrs %}{% if bound_field.value %} value="{{ bound_field|datepicker_value }}"{% endif %}>
{% endviewpart %}{% viewpart field append %}
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
{% endviewpart %}
</div>
</div>
{% viewpart field errors %}
{% if bound_field.errors %}
{% include 'viewflow/form/bootstrap3/field_errors.html' %}
{% endif %}
{% endviewpart %}{% viewpart field help_text %}
{% if field.help_text %}
<span class="help-block">{{ bound_field.help_text }}</span>
{% endif %}
{% endviewpart %}{{ hidden_initial }}
</div>
33 changes: 32 additions & 1 deletion viewflow/site/templatetags/viewform.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from django import template
from django.template.loader import get_template
from django.utils import formats

from tag_parser import template_tag
from tag_parser.basetags import BaseNode
Expand Down Expand Up @@ -128,7 +129,37 @@ def render_tag(self, context, field, template=None):


@template_tag(register, 'tagattrs')
class CssClassNode(BaseContainerNode):
class TagAttrsNode(BaseContainerNode):
def render_tag(self, context):
value = self.nodelist.render(context)
return re.sub('[\n ]+', ' ', value).strip()


@register.filter
def datepicker_format(field):
input_format = field.input_formats[0]

# %a, %A, %z, %f %Z %j %U %W %c %x %X unsupported

subst = {
'%d': 'dd', # Day of the month as a zero-padded decimal number
'%b': 'M', # Month as locale’s abbreviated name
'%B': 'MM', # Month as locale’s full name
'%m': 'mm', # Month as a zero-padded decimal number
'%y': 'yy', # Year without century as a zero-padded decimal number
'%Y': 'yyyy', # Year with century as a decimal number
'%H': 'hh', # Hour (24-hour clock) as a zero-padded decimal number
'%I': 'HH', # Hour (12-hour clock) as a zero-padded decimal number
'%p': 'P', # Locale’s equivalent of either AM or PM
'%M': 'ii', # Minute as a zero-padded decimal number
'%S': 'ss', # Second as a zero-padded decimal number
'%%': '%' # A literal '%' character
}

return re.sub('|'.join(re.escape(key) for key in subst.keys()),
lambda k: subst[k.group(0)], input_format)


@register.filter
def datepicker_value(bound_field):
return formats.localize_input(bound_field.value(), bound_field.field.input_formats[0])

0 comments on commit c0930f8

Please sign in to comment.