0005-move-authentic2.widgets-to-authentic2.forms.widgets-.patch
src/authentic2/attribute_kinds.py | ||
---|---|---|
15 | 15 | |
16 | 16 |
from .decorators import to_iter |
17 | 17 |
from .plugins import collect_from_plugins |
18 |
from . import app_settings, widgets |
|
18 |
from . import app_settings |
|
19 |
from .forms import widgets |
|
19 | 20 | |
20 | 21 |
capfirst = allow_lazy(capfirst, unicode) |
21 | 22 |
src/authentic2/forms/widgets.py | ||
---|---|---|
1 |
# Bootstrap django-datetime-widget is a simple and clean widget for DateField, |
|
2 |
# Timefiled and DateTimeField in Django framework. It is based on Bootstrap |
|
3 |
# datetime picker, supports Bootstrap 2 |
|
4 |
# |
|
5 |
# https://github.com/asaglimbeni/django-datetime-widget |
|
6 |
# |
|
7 |
# License: BSD |
|
8 |
# Initial Author: Alfredo Saglimbeni |
|
9 | ||
10 |
import json |
|
11 |
import re |
|
12 |
import uuid |
|
13 | ||
14 |
from django.forms.widgets import DateTimeInput, DateInput, TimeInput |
|
15 |
from django.utils.formats import get_language, get_format |
|
16 |
from django.utils.safestring import mark_safe |
|
17 |
from django.utils.translation import ugettext_lazy as _ |
|
18 | ||
19 |
from gadjo.templatetags.gadjo import xstatic |
|
20 | ||
21 |
DATE_FORMAT_JS_PY_MAPPING = { |
|
22 |
'P': '%p', |
|
23 |
'ss': '%S', |
|
24 |
'ii': '%M', |
|
25 |
'hh': '%H', |
|
26 |
'HH': '%I', |
|
27 |
'dd': '%d', |
|
28 |
'mm': '%m', |
|
29 |
'yy': '%y', |
|
30 |
'yyyy': '%Y', |
|
31 |
} |
|
32 | ||
33 |
DATE_FORMAT_TO_PYTHON_REGEX = re.compile(r'\b(' + '|'.join(DATE_FORMAT_JS_PY_MAPPING.keys()) + r')\b') |
|
34 | ||
35 | ||
36 |
DATE_FORMAT_PY_JS_MAPPING = { |
|
37 |
'%M': 'ii', |
|
38 |
'%m': 'mm', |
|
39 |
'%I': 'HH', |
|
40 |
'%H': 'hh', |
|
41 |
'%d': 'dd', |
|
42 |
'%Y': 'yyyy', |
|
43 |
'%y': 'yy', |
|
44 |
'%p': 'P', |
|
45 |
'%S': 'ss' |
|
46 |
} |
|
47 | ||
48 |
DATE_FORMAT_TO_JS_REGEX = re.compile(r'(?<!\w)(' + '|'.join(DATE_FORMAT_PY_JS_MAPPING.keys()) + r')\b') |
|
49 | ||
50 | ||
51 |
BOOTSTRAP_INPUT_TEMPLATE = """ |
|
52 |
%(rendered_widget)s |
|
53 |
%(clear_button)s |
|
54 |
<span class="add-on"><i class="icon-th"></i></span> |
|
55 |
<span class="helptext">%(help_text)s</span> |
|
56 |
<script type="text/javascript"> |
|
57 |
$("#%(id)s").datetimepicker({%(options)s}); |
|
58 |
</script> |
|
59 |
""" |
|
60 | ||
61 |
CLEAR_BTN_TEMPLATE = """<span class="add-on"><i class="icon-remove"></i></span>""" |
|
62 | ||
63 | ||
64 |
class PickerWidgetMixin(object): |
|
65 |
class Media: |
|
66 |
css = { |
|
67 |
'all': ('css/datetimepicker.css',), |
|
68 |
} |
|
69 |
js = ( |
|
70 |
xstatic('jquery', 'jquery.min.js'), |
|
71 |
xstatic('jquery_ui', 'jquery-ui.min.js'), |
|
72 |
'js/bootstrap-datetimepicker.js', |
|
73 |
'js/locales/bootstrap-datetimepicker.fr.js', |
|
74 |
) |
|
75 | ||
76 |
format_name = None |
|
77 |
glyphicon = None |
|
78 |
help_text = None |
|
79 | ||
80 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
81 | ||
82 |
if attrs is None: |
|
83 |
attrs = {} |
|
84 | ||
85 |
self.options = options |
|
86 |
self.options['language'] = get_language().split('-')[0] |
|
87 | ||
88 |
# We're not doing localisation, get the Javascript date format provided by the user, |
|
89 |
# with a default, and convert it to a Python data format for later string parsing |
|
90 |
date_format = self.options['format'] |
|
91 |
self.format = DATE_FORMAT_TO_PYTHON_REGEX.sub( |
|
92 |
lambda x: DATE_FORMAT_JS_PY_MAPPING[x.group()], |
|
93 |
date_format |
|
94 |
) |
|
95 | ||
96 |
super(PickerWidgetMixin, self).__init__(attrs, format=self.format) |
|
97 | ||
98 |
def get_format(self): |
|
99 |
format = get_format(self.format_name)[0] |
|
100 |
for py, js in DATE_FORMAT_PY_JS_MAPPING.iteritems(): |
|
101 |
format = format.replace(py, js) |
|
102 |
return format |
|
103 | ||
104 |
def render(self, name, value, attrs=None): |
|
105 |
final_attrs = self.build_attrs(attrs) |
|
106 |
final_attrs['class'] = "controls input-append date" |
|
107 |
rendered_widget = super(PickerWidgetMixin, self).render(name, value, final_attrs) |
|
108 | ||
109 |
#if not set, autoclose have to be true. |
|
110 |
self.options.setdefault('autoclose', True) |
|
111 | ||
112 |
# Build javascript options out of python dictionary |
|
113 |
options_list = [] |
|
114 |
for key, value in iter(self.options.items()): |
|
115 |
options_list.append("%s: %s" % (key, json.dumps(value))) |
|
116 | ||
117 |
js_options = ",\n".join(options_list) |
|
118 | ||
119 |
# Use provided id or generate hex to avoid collisions in document |
|
120 |
id = final_attrs.get('id', uuid.uuid4().hex) |
|
121 | ||
122 |
help_text = self.help_text |
|
123 |
if not help_text: |
|
124 |
help_text = u'%s %s' % (_('Format:'), self.options['format']) |
|
125 | ||
126 |
return mark_safe(BOOTSTRAP_INPUT_TEMPLATE % dict( |
|
127 |
id=id, |
|
128 |
rendered_widget=rendered_widget, |
|
129 |
clear_button=CLEAR_BTN_TEMPLATE if self.options.get('clearBtn') else '', |
|
130 |
glyphicon=self.glyphicon, |
|
131 |
options=js_options, |
|
132 |
help_text=help_text, |
|
133 |
) |
|
134 |
) |
|
135 | ||
136 | ||
137 |
class DateTimeWidget(PickerWidgetMixin, DateTimeInput): |
|
138 |
""" |
|
139 |
DateTimeWidget is the corresponding widget for Datetime field, it renders both the date and time |
|
140 |
sections of the datetime picker. |
|
141 |
""" |
|
142 | ||
143 |
format_name = 'DATETIME_INPUT_FORMATS' |
|
144 |
glyphicon = 'glyphicon-th' |
|
145 | ||
146 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
147 | ||
148 |
if options is None: |
|
149 |
options = {} |
|
150 | ||
151 |
# Set the default options to show only the datepicker object |
|
152 |
options['format'] = options.get('format', self.get_format()) |
|
153 | ||
154 |
super(DateTimeWidget, self).__init__(attrs, options, usel10n) |
|
155 | ||
156 | ||
157 |
class DateWidget(PickerWidgetMixin, DateInput): |
|
158 |
""" |
|
159 |
DateWidget is the corresponding widget for Date field, it renders only the date section of |
|
160 |
datetime picker. |
|
161 |
""" |
|
162 | ||
163 |
format_name = 'DATE_INPUT_FORMATS' |
|
164 |
glyphicon = 'glyphicon-calendar' |
|
165 | ||
166 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
167 | ||
168 |
if options is None: |
|
169 |
options = {} |
|
170 | ||
171 |
# Set the default options to show only the datepicker object |
|
172 |
options['startView'] = options.get('startView', 2) |
|
173 |
options['minView'] = options.get('minView', 2) |
|
174 |
options['format'] = options.get('format', self.get_format()) |
|
175 | ||
176 |
super(DateWidget, self).__init__(attrs, options, usel10n) |
|
177 | ||
178 | ||
179 |
class TimeWidget(PickerWidgetMixin, TimeInput): |
|
180 |
""" |
|
181 |
TimeWidget is the corresponding widget for Time field, it renders only the time section of |
|
182 |
datetime picker. |
|
183 |
""" |
|
184 | ||
185 |
format_name = 'TIME_INPUT_FORMATS' |
|
186 |
glyphicon = 'glyphicon-time' |
|
187 | ||
188 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
189 | ||
190 |
if options is None: |
|
191 |
options = {} |
|
192 | ||
193 |
# Set the default options to show only the timepicker object |
|
194 |
options['startView'] = options.get('startView', 1) |
|
195 |
options['minView'] = options.get('minView', 0) |
|
196 |
options['maxView'] = options.get('maxView', 1) |
|
197 |
options['format'] = options.get('format', self.get_format()) |
|
198 | ||
199 |
super(TimeWidget, self).__init__(attrs, options, usel10n) |
src/authentic2/widgets.py | ||
---|---|---|
1 |
# Bootstrap django-datetime-widget is a simple and clean widget for DateField, |
|
2 |
# Timefiled and DateTimeField in Django framework. It is based on Bootstrap |
|
3 |
# datetime picker, supports Bootstrap 2 |
|
4 |
# |
|
5 |
# https://github.com/asaglimbeni/django-datetime-widget |
|
6 |
# |
|
7 |
# License: BSD |
|
8 |
# Initial Author: Alfredo Saglimbeni |
|
9 | ||
10 |
import json |
|
11 |
import re |
|
12 |
import uuid |
|
13 | ||
14 |
from django.forms.widgets import DateTimeInput, DateInput, TimeInput |
|
15 |
from django.utils.formats import get_language, get_format |
|
16 |
from django.utils.safestring import mark_safe |
|
17 |
from django.utils.translation import ugettext_lazy as _ |
|
18 | ||
19 |
from gadjo.templatetags.gadjo import xstatic |
|
20 | ||
21 |
DATE_FORMAT_JS_PY_MAPPING = { |
|
22 |
'P': '%p', |
|
23 |
'ss': '%S', |
|
24 |
'ii': '%M', |
|
25 |
'hh': '%H', |
|
26 |
'HH': '%I', |
|
27 |
'dd': '%d', |
|
28 |
'mm': '%m', |
|
29 |
'yy': '%y', |
|
30 |
'yyyy': '%Y', |
|
31 |
} |
|
32 | ||
33 |
DATE_FORMAT_TO_PYTHON_REGEX = re.compile(r'\b(' + '|'.join(DATE_FORMAT_JS_PY_MAPPING.keys()) + r')\b') |
|
34 | ||
35 | ||
36 |
DATE_FORMAT_PY_JS_MAPPING = { |
|
37 |
'%M': 'ii', |
|
38 |
'%m': 'mm', |
|
39 |
'%I': 'HH', |
|
40 |
'%H': 'hh', |
|
41 |
'%d': 'dd', |
|
42 |
'%Y': 'yyyy', |
|
43 |
'%y': 'yy', |
|
44 |
'%p': 'P', |
|
45 |
'%S': 'ss' |
|
46 |
} |
|
47 | ||
48 |
DATE_FORMAT_TO_JS_REGEX = re.compile(r'(?<!\w)(' + '|'.join(DATE_FORMAT_PY_JS_MAPPING.keys()) + r')\b') |
|
49 | ||
50 | ||
51 |
BOOTSTRAP_INPUT_TEMPLATE = """ |
|
52 |
%(rendered_widget)s |
|
53 |
%(clear_button)s |
|
54 |
<span class="add-on"><i class="icon-th"></i></span> |
|
55 |
<span class="helptext">%(help_text)s</span> |
|
56 |
<script type="text/javascript"> |
|
57 |
$("#%(id)s").datetimepicker({%(options)s}); |
|
58 |
</script> |
|
59 |
""" |
|
60 | ||
61 |
CLEAR_BTN_TEMPLATE = """<span class="add-on"><i class="icon-remove"></i></span>""" |
|
62 | ||
63 | ||
64 |
class PickerWidgetMixin(object): |
|
65 |
class Media: |
|
66 |
css = { |
|
67 |
'all': ('css/datetimepicker.css',), |
|
68 |
} |
|
69 |
js = ( |
|
70 |
xstatic('jquery', 'jquery.min.js'), |
|
71 |
xstatic('jquery_ui', 'jquery-ui.min.js'), |
|
72 |
'js/bootstrap-datetimepicker.js', |
|
73 |
'js/locales/bootstrap-datetimepicker.fr.js', |
|
74 |
) |
|
75 | ||
76 |
format_name = None |
|
77 |
glyphicon = None |
|
78 |
help_text = None |
|
79 | ||
80 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
81 | ||
82 |
if attrs is None: |
|
83 |
attrs = {} |
|
84 | ||
85 |
self.options = options |
|
86 |
self.options['language'] = get_language().split('-')[0] |
|
87 | ||
88 |
# We're not doing localisation, get the Javascript date format provided by the user, |
|
89 |
# with a default, and convert it to a Python data format for later string parsing |
|
90 |
date_format = self.options['format'] |
|
91 |
self.format = DATE_FORMAT_TO_PYTHON_REGEX.sub( |
|
92 |
lambda x: DATE_FORMAT_JS_PY_MAPPING[x.group()], |
|
93 |
date_format |
|
94 |
) |
|
95 | ||
96 |
super(PickerWidgetMixin, self).__init__(attrs, format=self.format) |
|
97 | ||
98 |
def get_format(self): |
|
99 |
format = get_format(self.format_name)[0] |
|
100 |
for py, js in DATE_FORMAT_PY_JS_MAPPING.iteritems(): |
|
101 |
format = format.replace(py, js) |
|
102 |
return format |
|
103 | ||
104 |
def render(self, name, value, attrs=None): |
|
105 |
final_attrs = self.build_attrs(attrs) |
|
106 |
final_attrs['class'] = "controls input-append date" |
|
107 |
rendered_widget = super(PickerWidgetMixin, self).render(name, value, final_attrs) |
|
108 | ||
109 |
#if not set, autoclose have to be true. |
|
110 |
self.options.setdefault('autoclose', True) |
|
111 | ||
112 |
# Build javascript options out of python dictionary |
|
113 |
options_list = [] |
|
114 |
for key, value in iter(self.options.items()): |
|
115 |
options_list.append("%s: %s" % (key, json.dumps(value))) |
|
116 | ||
117 |
js_options = ",\n".join(options_list) |
|
118 | ||
119 |
# Use provided id or generate hex to avoid collisions in document |
|
120 |
id = final_attrs.get('id', uuid.uuid4().hex) |
|
121 | ||
122 |
help_text = self.help_text |
|
123 |
if not help_text: |
|
124 |
help_text = u'%s %s' % (_('Format:'), self.options['format']) |
|
125 | ||
126 |
return mark_safe(BOOTSTRAP_INPUT_TEMPLATE % dict( |
|
127 |
id=id, |
|
128 |
rendered_widget=rendered_widget, |
|
129 |
clear_button=CLEAR_BTN_TEMPLATE if self.options.get('clearBtn') else '', |
|
130 |
glyphicon=self.glyphicon, |
|
131 |
options=js_options, |
|
132 |
help_text=help_text, |
|
133 |
) |
|
134 |
) |
|
135 | ||
136 | ||
137 |
class DateTimeWidget(PickerWidgetMixin, DateTimeInput): |
|
138 |
""" |
|
139 |
DateTimeWidget is the corresponding widget for Datetime field, it renders both the date and time |
|
140 |
sections of the datetime picker. |
|
141 |
""" |
|
142 | ||
143 |
format_name = 'DATETIME_INPUT_FORMATS' |
|
144 |
glyphicon = 'glyphicon-th' |
|
145 | ||
146 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
147 | ||
148 |
if options is None: |
|
149 |
options = {} |
|
150 | ||
151 |
# Set the default options to show only the datepicker object |
|
152 |
options['format'] = options.get('format', self.get_format()) |
|
153 | ||
154 |
super(DateTimeWidget, self).__init__(attrs, options, usel10n) |
|
155 | ||
156 | ||
157 |
class DateWidget(PickerWidgetMixin, DateInput): |
|
158 |
""" |
|
159 |
DateWidget is the corresponding widget for Date field, it renders only the date section of |
|
160 |
datetime picker. |
|
161 |
""" |
|
162 | ||
163 |
format_name = 'DATE_INPUT_FORMATS' |
|
164 |
glyphicon = 'glyphicon-calendar' |
|
165 | ||
166 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
167 | ||
168 |
if options is None: |
|
169 |
options = {} |
|
170 | ||
171 |
# Set the default options to show only the datepicker object |
|
172 |
options['startView'] = options.get('startView', 2) |
|
173 |
options['minView'] = options.get('minView', 2) |
|
174 |
options['format'] = options.get('format', self.get_format()) |
|
175 | ||
176 |
super(DateWidget, self).__init__(attrs, options, usel10n) |
|
177 | ||
178 | ||
179 |
class TimeWidget(PickerWidgetMixin, TimeInput): |
|
180 |
""" |
|
181 |
TimeWidget is the corresponding widget for Time field, it renders only the time section of |
|
182 |
datetime picker. |
|
183 |
""" |
|
184 | ||
185 |
format_name = 'TIME_INPUT_FORMATS' |
|
186 |
glyphicon = 'glyphicon-time' |
|
187 | ||
188 |
def __init__(self, attrs=None, options=None, usel10n=None): |
|
189 | ||
190 |
if options is None: |
|
191 |
options = {} |
|
192 | ||
193 |
# Set the default options to show only the timepicker object |
|
194 |
options['startView'] = options.get('startView', 1) |
|
195 |
options['minView'] = options.get('minView', 0) |
|
196 |
options['maxView'] = options.get('maxView', 1) |
|
197 |
options['format'] = options.get('format', self.get_format()) |
|
198 | ||
199 |
super(TimeWidget, self).__init__(attrs, options, usel10n) |
|
1 |
# legacy module, please use authentic2.forms.widgets now. |
|
2 |
from .forms.widgets import * |
|
200 |
- |