Commit 3c32720d authored by Serge S. Koval's avatar Serge S. Koval

Use proper bootstrap 3 compatible date picker

parent 78a66cda
...@@ -5,6 +5,12 @@ from flask.ext.admin import helpers as h ...@@ -5,6 +5,12 @@ from flask.ext.admin import helpers as h
__all__ = ['Select2Widget', 'DatePickerWidget', 'DateTimePickerWidget', 'RenderTemplateWidget', 'Select2TagsWidget', ] __all__ = ['Select2Widget', 'DatePickerWidget', 'DateTimePickerWidget', 'RenderTemplateWidget', 'Select2TagsWidget', ]
def _is_bootstrap3():
view = h.get_current_view()
return view and view.admin.template_mode == 'bootstrap3'
class Select2Widget(widgets.Select): class Select2Widget(widgets.Select):
""" """
`Select2 <https://github.com/ivaynberg/select2>`_ styled select widget. `Select2 <https://github.com/ivaynberg/select2>`_ styled select widget.
...@@ -14,7 +20,7 @@ class Select2Widget(widgets.Select): ...@@ -14,7 +20,7 @@ class Select2Widget(widgets.Select):
""" """
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('data-role', u'select2') kwargs.setdefault('data-role', u'select2')
allow_blank = getattr(field, 'allow_blank', False) allow_blank = getattr(field, 'allow_blank', False)
if allow_blank and not self.multiple: if allow_blank and not self.multiple:
kwargs['data-allow-blank'] = u'1' kwargs['data-allow-blank'] = u'1'
...@@ -41,7 +47,12 @@ class DatePickerWidget(widgets.TextInput): ...@@ -41,7 +47,12 @@ class DatePickerWidget(widgets.TextInput):
""" """
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('data-role', u'datepicker') kwargs.setdefault('data-role', u'datepicker')
kwargs.setdefault('data-date-format', u'yyyy-mm-dd')
if _is_bootstrap3():
kwargs.setdefault('data-date-format', u'YYYY-MM-DD')
else:
kwargs.setdefault('data-date-format', u'yyyy-mm-dd')
kwargs.setdefault('data-date-autoclose', u'true') kwargs.setdefault('data-date-autoclose', u'true')
self.date_format = kwargs['data-date-format'] self.date_format = kwargs['data-date-format']
return super(DatePickerWidget, self).__call__(field, **kwargs) return super(DatePickerWidget, self).__call__(field, **kwargs)
...@@ -55,10 +66,15 @@ class DateTimePickerWidget(widgets.TextInput): ...@@ -55,10 +66,15 @@ class DateTimePickerWidget(widgets.TextInput):
""" """
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('data-role', u'datetimepicker') kwargs.setdefault('data-role', u'datetimepicker')
kwargs.setdefault('data-date-format', u'yyyy-mm-dd hh:ii:ss')
if _is_bootstrap3():
kwargs.setdefault('data-date-format', u'YYYY-MM-DD hh:mm:ss')
else:
kwargs.setdefault('data-date-format', u'yyyy-mm-dd hh:ii:ss')
kwargs.setdefault('data-date-today-btn', u'linked')
kwargs.setdefault('data-date-today-highlight', u'true')
kwargs.setdefault('data-date-autoclose', u'true') kwargs.setdefault('data-date-autoclose', u'true')
kwargs.setdefault('data-date-today-btn', u'linked')
kwargs.setdefault('data-date-today-highlight', u'true')
return super(DateTimePickerWidget, self).__call__(field, **kwargs) return super(DateTimePickerWidget, self).__call__(field, **kwargs)
...@@ -70,7 +86,12 @@ class TimePickerWidget(widgets.TextInput): ...@@ -70,7 +86,12 @@ class TimePickerWidget(widgets.TextInput):
""" """
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('data-role', u'timepicker') kwargs.setdefault('data-role', u'timepicker')
kwargs.setdefault('data-date-format', u'hh:ii:ss')
if _is_bootstrap3():
kwargs.setdefault('data-date-format', u'hh:mm:ss')
else:
kwargs.setdefault('data-date-format', u'hh:ii:ss')
kwargs.setdefault('data-date-autoclose', u'true') kwargs.setdefault('data-date-autoclose', u'true')
return super(TimePickerWidget, self).__call__(field, **kwargs) return super(TimePickerWidget, self).__call__(field, **kwargs)
......
...@@ -107,17 +107,25 @@ ...@@ -107,17 +107,25 @@
return true; return true;
case 'datepicker': case 'datepicker':
$el.datetimepicker({ $el.datetimepicker({
minView: 'month' // TODO: Have separate converters for bs2 and bs3
// Bootstrap 2 option
minView: 'month',
// Bootstrap 3 option
pickTime: false
}); });
return true; return true;
case 'datetimepicker': case 'datetimepicker':
$el.datetimepicker(); $el.datetimepicker({
});
return true; return true;
case 'timepicker': case 'timepicker':
$el.datetimepicker({ $el.datetimepicker({
// Bootstrap 2 option
startView: 'day', startView: 'day',
maxView: 'day', maxView: 'day',
formatViewType: 'time' formatViewType: 'time',
// Bootstrap 3 option
pickDate: false
}); });
return true; return true;
} }
......
/*!
* Datetimepicker for Bootstrap v3
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
.bootstrap-datetimepicker-widget{top:0;left:0;width:250px;padding:4px;margin-top:1px;z-index:99999!important;border-radius:4px}.bootstrap-datetimepicker-widget.timepicker-sbs{width:600px}.bootstrap-datetimepicker-widget.bottom:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:7px}.bootstrap-datetimepicker-widget.bottom:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:8px}.bootstrap-datetimepicker-widget.top:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.top:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;position:absolute;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget .dow{width:14.2857%}.bootstrap-datetimepicker-widget.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget>ul{list-style-type:none;margin:0}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:100%;font-weight:bold;font-size:1.2em}.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator{width:4px;padding:0;margin:0}.bootstrap-datetimepicker-widget .datepicker>div{display:none}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget td,.bootstrap-datetimepicker-widget th{text-align:center;width:20px;height:20px;border-radius:4px}.bootstrap-datetimepicker-widget td.day:hover,.bootstrap-datetimepicker-widget td.hour:hover,.bootstrap-datetimepicker-widget td.minute:hover,.bootstrap-datetimepicker-widget td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget td.old,.bootstrap-datetimepicker-widget td.new{color:#999}.bootstrap-datetimepicker-widget td.today{position:relative}.bootstrap-datetimepicker-widget td.today:before{content:'';display:inline-block;border-left:7px solid transparent;border-bottom:7px solid #428bca;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget td.active,.bootstrap-datetimepicker-widget td.active:hover{background-color:#428bca;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget td.disabled,.bootstrap-datetimepicker-widget td.disabled:hover{background:none;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget td span{display:block;width:47px;height:54px;line-height:54px;float:left;margin:2px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget td span:hover{background:#eee}.bootstrap-datetimepicker-widget td span.active{background-color:#428bca;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget td span.old{color:#999}.bootstrap-datetimepicker-widget td span.disabled,.bootstrap-datetimepicker-widget td span.disabled:hover{background:none;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget th.switch{width:145px}.bootstrap-datetimepicker-widget th.next,.bootstrap-datetimepicker-widget th.prev{font-size:21px}.bootstrap-datetimepicker-widget th.disabled,.bootstrap-datetimepicker-widget th.disabled:hover{background:none;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget thead tr:first-child th:hover{background:#eee}.input-group.date .input-group-addon span{display:block;cursor:pointer;width:16px;height:16px}.bootstrap-datetimepicker-widget.left-oriented:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.left-oriented:after{left:auto;right:7px}.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody>tr>td{padding:0!important}
\ No newline at end of file
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
{% block head_css %} {% block head_css %}
<link href="{{ admin_static.url(filename='bootstrap/bootstrap2/css/bootstrap.css') }}" rel="stylesheet"> <link href="{{ admin_static.url(filename='bootstrap/bootstrap2/css/bootstrap.css') }}" rel="stylesheet">
<link href="{{ admin_static.url(filename='bootstrap/bootstrap2/css/bootstrap-responsive.css') }}" rel="stylesheet"> <link href="{{ admin_static.url(filename='bootstrap/bootstrap2/css/bootstrap-responsive.css') }}" rel="stylesheet">
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
<link href="{{ admin_static.url(filename='admin/css/bootstrap2/admin.css') }}" rel="stylesheet"> <link href="{{ admin_static.url(filename='admin/css/bootstrap2/admin.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block head %} {% block head %}
...@@ -56,7 +55,8 @@ ...@@ -56,7 +55,8 @@
{% block tail_js %} {% block tail_js %}
<script src="{{ admin_static.url(filename='vendor/jquery-2.0.3.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='vendor/jquery-2.0.3.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='bootstrap/bootstrap2/js/bootstrap.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='bootstrap/bootstrap2/js/bootstrap.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='select2/select2.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='vendor/moment-2.7.0.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='vendor/select2/select2.min.js') }}" type="text/javascript"></script>
{% endblock %} {% endblock %}
{% block tail %} {% block tail %}
......
{% import 'admin/static.html' as admin_static with context %}
{# ---------------------- Pager -------------------------- #} {# ---------------------- Pager -------------------------- #}
{% macro pager(page, pages, generator) -%} {% macro pager(page, pages, generator) -%}
{% if pages > 1 %} {% if pages > 1 %}
...@@ -165,3 +167,13 @@ ...@@ -165,3 +167,13 @@
{{ render_form_buttons(cancel_url, extra) }} {{ render_form_buttons(cancel_url, extra) }}
{% endcall %} {% endcall %}
{% endmacro %} {% endmacro %}
{% macro form_css() %}
<link href="{{ admin_static.url(filename='vendor/select2/select2.css') }}" rel="stylesheet">
<link href="{{ admin_static.url(filename='vendor/datetimepicker-bs2/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endmacro %}
{% macro form_js() %}
<script src="{{ admin_static.url(filename='vendor/datetimepicker-bs2/bootstrap-datetimepicker.js') }}"></script>
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endmacro %}
{% extends 'admin/master.html' %} {% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib with context %} {% import 'admin/lib.html' as lib with context %}
{% import 'admin/static.html' as admin_static with context %}
{% macro extra() %} {% macro extra() %}
<input name="_add_another" type="submit" class="btn btn-large" value="{{ _gettext('Save and Add') }}" /> <input name="_add_another" type="submit" class="btn btn-large" value="{{ _gettext('Save and Add') }}" />
...@@ -8,8 +7,7 @@ ...@@ -8,8 +7,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -30,6 +28,5 @@ ...@@ -30,6 +28,5 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endblock %} {% endblock %}
{% extends 'admin/master.html' %} {% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib with context %} {% import 'admin/lib.html' as lib with context %}
{% import 'admin/static.html' as admin_static with context %}
{% macro extra() %} {% macro extra() %}
<input name="_continue_editing" type="submit" class="btn btn-large" value="{{ _gettext('Save and Continue') }}" /> <input name="_continue_editing" type="submit" class="btn btn-large" value="{{ _gettext('Save and Continue') }}" />
...@@ -8,8 +7,7 @@ ...@@ -8,8 +7,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -21,6 +19,5 @@ ...@@ -21,6 +19,5 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endblock %} {% endblock %}
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -145,8 +144,7 @@ ...@@ -145,8 +144,7 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
<script src="{{ admin_static.url(filename='admin/js/filters.js') }}"></script> <script src="{{ admin_static.url(filename='admin/js/filters.js') }}"></script>
{{ actionlib.script(_gettext('Please select at least one model.'), {{ actionlib.script(_gettext('Please select at least one model.'),
......
...@@ -66,7 +66,8 @@ ...@@ -66,7 +66,8 @@
{% block tail_js %} {% block tail_js %}
<script src="{{ admin_static.url(filename='vendor/jquery-2.0.3.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='vendor/jquery-2.0.3.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='bootstrap/bootstrap3/js/bootstrap.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='bootstrap/bootstrap3/js/bootstrap.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='select2/select2.min.js') }}" type="text/javascript"></script> <script src="{{ admin_static.url(filename='vendor/moment-2.7.0.min.js') }}" type="text/javascript"></script>
<script src="{{ admin_static.url(filename='vendor/select2/select2.min.js') }}" type="text/javascript"></script>
{% endblock %} {% endblock %}
{% block tail %} {% block tail %}
......
{% import 'admin/static.html' as admin_static with context %}
{# ---------------------- Pager -------------------------- #} {# ---------------------- Pager -------------------------- #}
{% macro pager(page, pages, generator) -%} {% macro pager(page, pages, generator) -%}
{% if pages > 1 %} {% if pages > 1 %}
...@@ -158,3 +160,13 @@ ...@@ -158,3 +160,13 @@
{{ render_form_buttons(cancel_url, extra) }} {{ render_form_buttons(cancel_url, extra) }}
{% endcall %} {% endcall %}
{% endmacro %} {% endmacro %}
{% macro form_css() %}
<link href="{{ admin_static.url(filename='vendor/select2/select2.css') }}" rel="stylesheet">
<link href="{{ admin_static.url(filename='vendor/datetimepicker-bs3/bootstrap-datetimepicker.min.css') }}" rel="stylesheet">
{% endmacro %}
{% macro form_js() %}
<script src="{{ admin_static.url(filename='vendor/datetimepicker-bs3/bootstrap-datetimepicker.min.js') }}"></script>
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endmacro %}
{% extends 'admin/master.html' %} {% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib with context %} {% import 'admin/lib.html' as lib with context %}
{% import 'admin/static.html' as admin_static with context %}
{% macro extra() %} {% macro extra() %}
<input name="_add_another" type="submit" class="btn btn-large" value="{{ _gettext('Save and Add') }}" /> <input name="_add_another" type="submit" class="btn btn-large" value="{{ _gettext('Save and Add') }}" />
...@@ -8,8 +7,7 @@ ...@@ -8,8 +7,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -32,6 +30,5 @@ ...@@ -32,6 +30,5 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endblock %} {% endblock %}
{% extends 'admin/master.html' %} {% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib with context %} {% import 'admin/lib.html' as lib with context %}
{% import 'admin/static.html' as admin_static with context %}
{% macro extra() %} {% macro extra() %}
<input name="_continue_editing" type="submit" class="btn" value="{{ _gettext('Save and Continue') }}" /> <input name="_continue_editing" type="submit" class="btn" value="{{ _gettext('Save and Continue') }}" />
...@@ -8,8 +7,7 @@ ...@@ -8,8 +7,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -21,6 +19,5 @@ ...@@ -21,6 +19,5 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
{% endblock %} {% endblock %}
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ admin_static.url(filename='select2/select2.css') }}" rel="stylesheet"> {{ lib.form_css() }}
<link href="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
{% block body %} {% block body %}
...@@ -145,8 +144,7 @@ ...@@ -145,8 +144,7 @@
{% block tail %} {% block tail %}
{{ super() }} {{ super() }}
<script src="{{ admin_static.url(filename='datetimepicker/bootstrap-datetimepicker.js') }}"></script> {{ lib.form_js() }}
<script src="{{ admin_static.url(filename='admin/js/form.js') }}"></script>
<script src="{{ admin_static.url(filename='admin/js/filters.js') }}"></script> <script src="{{ admin_static.url(filename='admin/js/filters.js') }}"></script>
{{ actionlib.script(_gettext('Please select at least one model.'), {{ actionlib.script(_gettext('Please select at least one model.'),
......
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