Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SplitDateTimeWidget bug #66

Open
riparian-imakedonsky opened this issue May 6, 2018 · 2 comments
Open

SplitDateTimeWidget bug #66

riparian-imakedonsky opened this issue May 6, 2018 · 2 comments

Comments

@riparian-imakedonsky
Copy link

riparian-imakedonsky commented May 6, 2018

Widget tweaks cuts off initial classes provided to subwidgets.

Used both directly(not through custom widget, and with custom widget). Result is same.

Consider following usage:

Template:
{% render_field field class+='validate' %}

Form:

class MySparEditForm(forms.ModelForm):
    posting_start = forms.SplitDateTimeField(widget=SplitDateTimeWidget(time_attrs={'class': 'datepicker'}, date_attrs={'class': 'timepicker'}))

    class Meta:
        model = Spar
        widgets = {
            'posting_end':  DateTimePicker(),
            'main_text': TextArea(),
            'image': forms.FileInput(),
            'active': CheckBox()
        }
        fields = [
            'active',
            'name',
            'type',
            'description',
            'main_text',
            'image',
            'participants',
            'posting_start',
            'posting_end',
        ]

And DateTimePicker widget code:

def add_classes(attrs, classes):
    if 'class' in attrs:
        attrs['class'] += f' {classes}'
    else:
        attrs['class'] = classes


class DateTimePicker(SplitDateTimeWidget):
    datepicker_classes = 'datepicker'
    timepicker_classes = 'timepicker'

    def __init__(self, attrs=None, date_format=None, time_format=None, date_attrs=None, time_attrs=None):
        date_attrs, time_attrs = date_attrs or {}, time_attrs or {}
        add_classes(date_attrs, self.datepicker_classes)
        add_classes(time_attrs, self.timepicker_classes)
        super().__init__(attrs, date_format, time_format, date_attrs, time_attrs)

Then result is:
http://joxi.ru/MAjBv7I40kDdAe.png

It replaces initial classes on subwidgets with provided via += instead of concatenating them.

@zodman
Copy link
Member

zodman commented May 24, 2019

i can reproduce with this:


diff --git a/widget_tweaks/tests.py b/widget_tweaks/tests.py
index ee210a2..a944afe 100644
--- a/widget_tweaks/tests.py
+++ b/widget_tweaks/tests.py
@@ -7,7 +7,7 @@ except ImportError:
 
 from django import VERSION
 from django import forms
-from django.forms import Form, CharField, TextInput
+from django.forms import Form, CharField, TextInput, SplitDateTimeField, SplitDateTimeWidget
 from django.template import Template, Context
 
 try:
@@ -15,6 +15,14 @@ try:
 except ImportError:
     from django.forms.extras.widgets import SelectDateWidget  # django < 2.0
 
+if VERSION[0] == 2:
+    date_time_params = dict(
+        time_attrs={'class': 'datepicker'}, date_attrs={'class': 'timepicker'}
+    )
+else:
+    date_time_params = {}
+
+
 
 # ==============================
 #       Testing helpers
@@ -33,6 +41,7 @@ class MyForm(Form):
     }))
     with_cls = CharField(widget=TextInput(attrs={'class': 'class0'}))
     date = forms.DateField(widget=SelectDateWidget(attrs={'egg': 'spam'}))
+    date_time = forms.SplitDateTimeField(widget=SplitDateTimeWidget(**date_time_params))
 
 
 def render_form(text, form=None, **context_args):
@@ -119,6 +128,12 @@ class SimpleAttrTest(TestCase):
         res = render_field('simple', 'set_data', 'key:value')
         assertIn('data-key="value"', res)
 
+    def test_widget_split(self):
+        if VERSION[0]  == 2:
+            res = render_field('date_time', 'add_class', 'validate')
+            assertIn("datepicker", res)
+            assertIn("timepicker", res)
+
 
 class ErrorsTest(TestCase):
 
@@ -314,6 +329,13 @@ class RenderFieldTagFieldReuseTest(TestCase):
         res = render_form('{{ form.simple }}{% render_field form.simple foo="bar" %}{% render_field form.simple %}')
         self.assertEqual(res.count("bar"), 1)
 
+    
+    def test_field_datetime_widget(self): #  issue #66 from github
+        if VERSION[0] == 2:
+            res = render_form('{{ form.simple }}{% render_field form.date_time class+="validate" %}')
+            self.assertEqual(res.count("timepicker"), 1, res)
+            self.assertEqual(res.count("datepicker"), 1, res)
+
     def test_field_double_rendering_simple_css(self):
         res = render_form('{% render_field form.simple %}{% render_field form.simple class+="bar" %}{% render_field form.simple class+="baz" %}')
         self.assertEqual(res.count("baz"), 1)

the pass show it clear:

test_field_datetime_widget (widget_tweaks.tests.RenderFieldTagFieldReuseTest) ... FAIL

======================================================================
FAIL: test_field_datetime_widget (widget_tweaks.tests.RenderFieldTagFieldReuseTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/zodman/apps/django-widget-tweaks/widget_tweaks/tests.py", line 336, in test_field_datetime_widget
    self.assertEqual(res.count("timepicker"), 1, res)
AssertionError: 0 != 1 : <input type="text" name="simple" required id="id_simple" /><input type="text" name="date_time_0" class="validate" required id="id_date_time_0" /><input type="text" name="date_time_1" class="validate" required id="id_date_time_1" />

@zodman
Copy link
Member

zodman commented May 24, 2019

SplitDateTimeField its a MultiWidget and not supported!

zodman added a commit that referenced this issue May 24, 2019
add not supported in readme by issue #66
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants