rsp
rsp

Reputation: 869

How do I access the id of a Django Widget from the widget definition?

I am creating a custom widget for a datetime field:

class MySplitDateTimeWidget(forms.SplitDateTimeWidget):
    def format_output(self, rendered_widgets):
        mytimeid = self.widgets[1].attrs['id']  #####NEED HELP HERE
        temp = "javascript:$('%s').val(new Date().getHours());" % mytimeid
        temp1 = '<a href="%s">Now</a>' % temp
        return mark_safe(u'%s %s<br />%s %s %s' % \
            (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1],
            temp1
        ))

I need the "id" attribute of the widget, however self.widgets doesn't include the "id" attribute in attrs. It includes every other attribute though. I'm not sure where this attribute comes from?

Upvotes: 4

Views: 3181

Answers (2)

jlmcdonald
jlmcdonald

Reputation: 13667

Unless you've overwritten it, the ID should be:

id_[name]

So try:

mytimeid = 'id_'+self.widgets[1].attrs['name']

Upvotes: 0

SMX
SMX

Reputation: 1442

I was just grappling with the exact same thing; hopefully this is useful for other people. The "id" attr is set via:

  1. Form is asked to render itself
  2. Form iterates through its fields
  3. For each field, the form calls its custom __getitem__() which wraps the field as a BoundField
  4. The BoundField, in the as_widget() method, is what actually sets the "id" attribute (see also the auto_id() method)
  5. The MultiWidget then performs its render() method, which renders each of its child widgets and then joins them with format_output()

So, to answer your question, you want to get the ID in the render() method and not the format_output() method:

class MySplitDateTimeWidget(forms.SplitDateTimeWidget):
    def render(self, name, value, attrs=None):
        widgets_html = super(MySplitDateTimeWidget, self).render(name, value, attrs)

        # attrs['id'] is the ID of the entire widget, append the prefix to chose the sub-widget
        mytimeid = attrs['id'] + '_0' 
        temp = "javascript:$('%s').val(new Date().getHours());" % mytimeid
        temp1 = '<a href="%s">Now</a>' % temp

        return mark_safe(widgets_html + ' ' + temp1)

    def format_output(self, rendered_widgets):
        return mark_safe(u'%s %s<br />%s %s' % (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1]))

Upvotes: 1

Related Questions