Add div wrapper to each select in SelectDateWidget

佐手、 提交于 2019-12-25 03:53:58

问题


Is it possible to overwrite SelectDateWidget to wrap a div around each select?

Like this:

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_day" name="birthdate_day">
<option value="0">---</option>....
</select>
</div>

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_month" name="birthdate_month">
<option value="0">---</option>....
</select>
</div>

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_year" name="birthdate_year">
<option value="0">---</option>....
</select>
</div>

回答1:


You can inherit the SelectDateWidget and override the render method within it. After that, you can use your CustomSelectDateWidget in the form.

Eg:

class CustomSelectDateWidget (SelectDateWidget):
"""Override of the standard renderer used for SelectDateWidget"""    

    def render(self, name, value, attrs=None):
        try:
            year_val, month_val, day_val = value.year, value.month, value.day
        except AttributeError:
            year_val = month_val = day_val = None
            if isinstance(value, six.string_types):
                if settings.USE_L10N:
                    try:
                        input_format = get_format('DATE_INPUT_FORMATS')[0]
                        v = datetime.datetime.strptime(value, input_format)
                        year_val, month_val, day_val = v.year, v.month, v.day
                    except ValueError:
                        pass
                else:
                    match = RE_DATE.match(value)
                    if match:
                        year_val, month_val, day_val = [int(v) for v in match.groups()]
        choices = [(i, i) for i in self.years]
        year_html = self.create_select(name, self.year_field, value, year_val, choices)
        choices = list(six.iteritems(MONTHS))
        month_html = self.create_select(name, self.month_field, value, month_val, choices)
        choices = [(i, i) for i in range(1, 32)]
        day_html = self.create_select(name, self.day_field, value, day_val,  choices)

        output = []
        for field in _parse_date_fmt():
            if field == 'year':
                output.append('<div class="wrapper">' + year_html + '</div>')
            elif field == 'month':
                output.append('<div class="wrapper">' + month_html + '</div>')
            elif field == 'day':
                output.append('<div class="wrapper">' + day_html + '</div>')
        return mark_safe('\n'.join(output))`

The important bit is towards the end of the code. This should work, not tested though. I would suggest copy the render method from your own version of SelectDateWidge within Django (I am running Django 1.5) and override the part with the div appended.




回答2:


To expand on what @BogdiG has said, it would be more useful to pass your wrapper to the widget as a string so that it is more generic & reusable.

class MySelectDateWidget(SelectDateWidget):

    def __init__(self, attrs=None, years=None, required=True, wrapper='%s'):
        self.wrapper = wrapper


    def render(self, name, value, attrs=None):

        # don't forget to put the rest of the render()
        # in here if you want to copy/paste this

        output = []
        for field in _parse_date_fmt():
            if field == 'year':
                output.append(self.wrapper % year_html)
            elif field == 'month':
                output.append(self.wrapper % month_html)
            elif field == 'day':
                output.append(self.wrapper % day_html)
        return mark_safe('\n'.join(output))`


class MyForm(forms.ModelForm):
    dob = forms.DateField(
        label=_('Date of birth'),
        widget=SelectDateWidget(wrapper='<div class="wrapper">%s</div>')
    )


来源:https://stackoverflow.com/questions/25202154/add-div-wrapper-to-each-select-in-selectdatewidget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!