From f2b0f8ea0fc5849801a2aeb71f2db106e5655aea Mon Sep 17 00:00:00 2001
From: Ramiro Morales <cramm0@gmail.com>
Date: Sat, 5 Feb 2011 18:16:27 +0000
Subject: [PATCH] Fixed #15226 - Made SelectDateWidget render the label tag
 associated with the correct dropdown sub-widget when USE_L10N is active and
 non-English locale is in use.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15427 bcc190cf-cafb-0310-a4f2-bffc1f526a37
---
 django/forms/extras/widgets.py             | 44 ++++++++++++++++------
 tests/regressiontests/forms/tests/extra.py |  9 +++++
 2 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py
index 0cd88b8170..e8bacf2b1e 100644
--- a/django/forms/extras/widgets.py
+++ b/django/forms/extras/widgets.py
@@ -17,6 +17,26 @@ __all__ = ('SelectDateWidget',)
 
 RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
 
+def _parse_date_fmt():
+    fmt = get_format('DATE_FORMAT')
+    escaped = False
+    output = []
+    for char in fmt:
+        if escaped:
+            escaped = False
+        elif char == '\\':
+            escaped = True
+        elif char in 'Yy':
+            output.append('year')
+            #if not self.first_select: self.first_select = 'year'
+        elif char in 'bEFMmNn':
+            output.append('month')
+            #if not self.first_select: self.first_select = 'month'
+        elif char in 'dj':
+            output.append('day')
+            #if not self.first_select: self.first_select = 'day'
+    return output
+
 class SelectDateWidget(Widget):
     """
     A Widget that splits date input into three <select> boxes.
@@ -67,24 +87,25 @@ class SelectDateWidget(Widget):
         choices = [(i, i) for i in range(1, 32)]
         day_html = self.create_select(name, self.day_field, value, day_val,  choices)
 
-        format = get_format('DATE_FORMAT')
-        escaped = False
         output = []
-        for char in format:
-            if escaped:
-                escaped = False
-            elif char == '\\':
-                escaped = True
-            elif char in 'Yy':
+        for field in _parse_date_fmt():
+            if field == 'year':
                 output.append(year_html)
-            elif char in 'bEFMmNn':
+            elif field == 'month':
                 output.append(month_html)
-            elif char in 'dj':
+            elif field == 'day':
                 output.append(day_html)
         return mark_safe(u'\n'.join(output))
 
     def id_for_label(self, id_):
-        return '%s_month' % id_
+        first_select = None
+        field_list = _parse_date_fmt()
+        if field_list:
+            first_select = field_list[0]
+        if first_select is not None:
+            return '%s_%s' % (id_, first_select)
+        else:
+            return '%s_month' % id_
     id_for_label = classmethod(id_for_label)
 
     def value_from_datadict(self, data, files, name):
@@ -118,4 +139,3 @@ class SelectDateWidget(Widget):
         s = Select(choices=choices)
         select_html = s.render(field % name, val, local_attrs)
         return select_html
-
diff --git a/tests/regressiontests/forms/tests/extra.py b/tests/regressiontests/forms/tests/extra.py
index 787a129338..927362a71f 100644
--- a/tests/regressiontests/forms/tests/extra.py
+++ b/tests/regressiontests/forms/tests/extra.py
@@ -356,6 +356,10 @@ class FormsExtraTestCase(unittest.TestCase, AssertFormErrorsMixin):
         self.assertFalse(c.is_valid())
         self.assertEqual(c.errors, {'mydate': [u'Enter a valid date.']})
 
+        # label tag is correctly associated with month dropdown
+        d = GetDate({'mydate_month':'1', 'mydate_day':'1', 'mydate_year':'2010'})
+        self.assertTrue('<label for="id_mydate_month">' in d.as_p())
+
     def test_multiwidget(self):
         # MultiWidget and MultiValueField #############################################
         # MultiWidgets are widgets composed of other widgets. They are usually
@@ -616,3 +620,8 @@ class FormsExtraL10NTestCase(unittest.TestCase):
         self.assertFalse(a.is_valid())
         # 'Geef een geldige datum op.' = 'Enter a valid date.'
         self.assertEqual(a.errors, {'mydate': [u'Geef een geldige datum op.']})
+
+    def test_form_label_association(self):
+        # label tag is correctly associated with first rendered dropdown
+        a = GetDate({'mydate_month':'1', 'mydate_day':'1', 'mydate_year':'2010'})
+        self.assertTrue('<label for="id_mydate_day">' in a.as_p())