2

I'm having trouble with configuring the Mezzanine in-line editing for datetime fields.

I have a field in the page something like this (as in http://mezzanine.jupo.org/docs/inline-editing.html)

{% editable page.project.start %}
  {{ page.project.start|date:'Y M'}}
{% endeditable %}

However, the widget is showing only 9 future years (as https://docs.djangoproject.com/en/2.1/ref/forms/widgets/#selectdatewidget) specifies, so it's impossible to enter any dates in the past.

I'd need to set the years attribute for that widget, however, I don't have any direct access to it, as it's generated automagically by Mezzanine. How can I set the arguments to Django widgets through the Mezzanine in-line editing code?

Peteris
  • 3,281
  • 2
  • 25
  • 40
  • I'm not a mezzanine expert, but you can't just pass a range to the SelectDateWidget when you istantiate it, like this: `SelectDateWidget(years=range(1980, 2040))`? This would override the default value. – Manuel Fedele Jan 29 '19 at 10:48
  • @MilesDavis the whole point is that *I* am not instantiating the widget in my code. I'm providing only the code quoted above in the page template, and Mezzanine instantiates the widget somewhere behind the scenes if certain conditions are met. – Peteris Jan 29 '19 at 10:53
  • can't you write some js code that identifies if there is that widget and add a wider range of dates, and add it to the view just like in django? – Shinra tensei Jan 29 '19 at 11:28

1 Answers1

3

I don't think there is an easy way to do this, but here is one approach that might help.

Mezzanine looks for a FORMS_EXTRA_WIDGETS setting which you can use to define custom widgets. How this works is best understood from the code.

The widgets defined here are what is used to render the inline editor forms, so you should be able to supply your own. There is no way to supply initialisation arguments to the widget, so you would need to subclass the default SelectDateWidget and override it's __init__ method, something like:

class CustomSelectDateWidget(SelectDateWidget):

    def __init__(self, attrs=None, years=None, months=None, empty_label=None):
        years = [2017, 2018, 2019]   # Provide your list of years here
        super().__init__(attrs, years, months, empty_label)

And then pass this custom widget to the setting:

from mezzanine.forms.fields import DATE
FORMS_EXTRA_WIDGETS = [
    (DATE, 'dotted.path.to.CustomSelectDateWidget')
]

Obviously this will replace the widget use for all date fields on all forms rendered by Mezzanine. I can't see any way to do it specifically for one field without rewriting a lot of the inline editor logic.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73
  • The idea seems reasonable but sadly I couldn't get this to work (page 500s whenever I add FORMS_EXTRA_WIDGETS to settings). It does seem weird - how are people editing date fields in Mezzanine then? Am I doing something unusual? – Peteris Feb 04 '19 at 12:13
  • Can you share the stack trace? To be honest I suspect very few people are using the inline editing feature in Mezzanine. – solarissmoke Feb 04 '19 at 13:00
  • 1
    I did manage to get this to work in the end, had some trouble with the imports of SelectDateWidget being different in the old Django versions, and importing mezzanine.forms.fields didn't work for me if it's done in the settings file, so I put a hardcoded 10 instead of DATE there, but it worked in the end, so thank you. Weird about the inline editing - to me it seems the major reason to use Mezzanine at all, since most other things I needed were just fine with plain Django; WYSIWYG in-line editing is among the top in the feature list Mezzanine claims to have. – Peteris Feb 06 '19 at 00:27