From f14a5868ad6986686e41bc92361de2c62f753b5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sat, 4 Apr 2020 20:45:46 +0200
Subject: [PATCH] forms: use native date widget if available (#11109)

---
 wcs/qommon/form.py                            | 35 +++++++++----------
 wcs/qommon/static/js/qommon.forms.js          |  1 +
 .../templates/qommon/forms/widgets/date.html  | 12 +++++--
 3 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/wcs/qommon/form.py b/wcs/qommon/form.py
index bf1018437..f229557f0 100644
--- a/wcs/qommon/form.py
+++ b/wcs/qommon/form.py
@@ -1017,20 +1017,20 @@ class DateWidget(StringWidget):
     def __init__(self, name, value=None, **kwargs):
         minimum_date = kwargs.pop('minimum_date', None)
         if minimum_date:
-            self.minimum_date = misc.get_as_datetime(minimum_date).timetuple()[:3]
+            self.minimum_date = misc.get_as_datetime(minimum_date)
         maximum_date = kwargs.pop('maximum_date', None)
         if maximum_date:
-            self.maximum_date = misc.get_as_datetime(maximum_date).timetuple()[:3]
+            self.maximum_date = misc.get_as_datetime(maximum_date)
         if kwargs.pop('minimum_is_future', False):
             if kwargs.get('date_can_be_today'):
-                self.minimum_date = time.localtime()
+                self.minimum_date = datetime.date.today()
             else:
-                self.minimum_date = (datetime.datetime.today() + datetime.timedelta(1)).timetuple()
+                self.minimum_date = (datetime.datetime.today() + datetime.timedelta(1))
         if kwargs.pop('date_in_the_past', False):
             if kwargs.get('date_can_be_today'):
-                self.maximum_date = time.localtime()
+                self.maximum_date = datetime.date.today()
             else:
-                self.maximum_date = (datetime.datetime.today() - datetime.timedelta(1)).timetuple()
+                self.maximum_date = (datetime.datetime.today() - datetime.timedelta(1))
 
         if 'date_can_be_today' in kwargs:
             del kwargs['date_can_be_today']
@@ -1063,13 +1063,12 @@ class DateWidget(StringWidget):
             if value[0] < 1800 or value[0] > 2099:
                 self.error = _('invalid date')
                 self.value = None
-            elif self.minimum_date and value[:3] < self.minimum_date[:3]:
+            elif self.minimum_date and value[:3] < self.minimum_date.timetuple()[:3]:
                 self.error = _('invalid date: date must be on or after %s') % strftime(
-                        misc.date_format(), datetime.datetime(*self.minimum_date[:6]))
-            elif self.maximum_date and value[:3] > self.maximum_date[:3]:
-                format_string = misc.date_format()
+                        misc.date_format(), self.minimum_date)
+            elif self.maximum_date and value[:3] > self.maximum_date.timetuple()[:3]:
                 self.error = _('invalid date; date must be on or before %s') % strftime(
-                        misc.date_format(), datetime.datetime(*self.maximum_date[:6]))
+                        misc.date_format(), self.maximum_date)
 
     def add_media(self):
         self.prepare_javascript()
@@ -1087,20 +1086,20 @@ class DateWidget(StringWidget):
     def date_format(self):
         return self.get_format_string().replace('%Y', 'yyyy').replace(
                 '%m', 'mm').replace('%d', 'dd').replace('%H', 'hh').replace(
-                '%M',  'ii').replace('%S', 'ss')
+                '%M', 'ii').replace('%S', 'ss')
 
     def start_date(self):
         return self.date_format().replace(
-                    'yyyy', '%04d' % self.minimum_date[0]).replace(
-                    'mm', '%02d' % self.minimum_date[1]).replace(
-                    'dd', '%02d' % self.minimum_date[2]).replace(
+                    'yyyy', '%04d' % self.minimum_date.year).replace(
+                    'mm', '%02d' % self.minimum_date.month).replace(
+                    'dd', '%02d' % self.minimum_date.day).replace(
                     'hh', '00').replace('ii', '00').replace('ss', '00')
 
     def end_date(self):
         return self.date_format().replace(
-                    'yyyy', '%04d' % self.maximum_date[0]).replace(
-                    'mm', '%02d' % self.maximum_date[1]).replace(
-                    'dd', '%02d' % self.maximum_date[2]).replace(
+                    'yyyy', '%04d' % self.maximum_date.year).replace(
+                    'mm', '%02d' % self.maximum_date.month).replace(
+                    'dd', '%02d' % self.maximum_date.day).replace(
                     'hh', '00').replace('ii', '00').replace('ss', '00')
 
 
diff --git a/wcs/qommon/static/js/qommon.forms.js b/wcs/qommon/static/js/qommon.forms.js
index 72514ca6c..032d05b9e 100644
--- a/wcs/qommon/static/js/qommon.forms.js
+++ b/wcs/qommon/static/js/qommon.forms.js
@@ -31,6 +31,7 @@ $(function() {
     });
   }
   $('.date-pick').each(function() {
+    if (this.type == "date") return;  // prefer native date widget
     var $date_input = $(this);
     var options = Object();
     options.autoclose = true;
diff --git a/wcs/qommon/templates/qommon/forms/widgets/date.html b/wcs/qommon/templates/qommon/forms/widgets/date.html
index b11f0d2a7..6a94bd1d0 100644
--- a/wcs/qommon/templates/qommon/forms/widgets/date.html
+++ b/wcs/qommon/templates/qommon/forms/widgets/date.html
@@ -1,7 +1,7 @@
 {% extends "qommon/forms/widget.html" %}
 
 {% block widget-control %}
-<input id="form_{{widget.name}}" name="{{widget.name}}" type="text"
+<input id="form_{{widget.name}}" name="{{widget.name}}" type="date"
   {% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
   {% if widget.required %}aria-required="true"{% endif %}
   {% if widget.value %}value="{{ widget.value }}"{% endif %}
@@ -17,8 +17,14 @@
   {# it is more appropriate to select a far away date. #}
   data-start-view="{% if widget.value %}2{% else %}4{% endif %}"
 
-  {% if widget.minimum_date %}data-start-date="{{ widget.start_date }}"{% endif %}
-  {% if widget.maximum_date %}data-end-date="{{ widget.end_date }}"{% endif %}
+  {% if widget.minimum_date %}
+  data-start-date="{{ widget.start_date }}"
+  min="{{widget.minimum_date|date:"Y-m-d"}}"
+  {% endif %}
+  {% if widget.maximum_date %}
+  data-end-date="{{ widget.end_date }}"
+  max="{{widget.maximum_date|date:"Y-m-d"}}"
+  {% endif %}
   {% endif %}
   >
 {% endblock %}
-- 
2.26.0

