Difficulty adding widgets to django form.

Posted by codingJoe on Stack Overflow See other posts from Stack Overflow or by codingJoe
Published on 2011-01-10T03:49:33Z Indexed on 2011/01/10 3:53 UTC
Read the original article Hit count: 294

Filed under:
|

I have a django app that tracks activities that can benefit a classroom. Using the django examples, I was able to build a form to enter this data. But when I try to add widgets to that form, things get tricky.

What I want is a calendar widget that lets the user enter the 'activity_date' field using a widget. If I use Admin interface. The AdminDateWidget works fine. however. This particular user isn't allowed access to the admin interface so I need a different way to present this widget. Also I couldn't figure out how to make the bring the admin widget over into non-admin pages. So I tried a custom widget.

This is the first custom widget I've built, so I'm not quite sure what is supposed to be going on here.

Any Expert Advice? How do I get my date widget to work?

# The Model
class Activity(models.Model): 
  activity_date = models.DateField()
  activity_type = models.CharField(max_length=50, choices=ACTIVITY_TYPES)
  activity_description = models.CharField(max_length=200)
  activity_duration= models.DecimalField(decimal_places=2, max_digits=4)
  est_attendance = models.IntegerField("Estimated attendance") 

# The Form
class ActivityForm(forms.ModelForm):  
  # The following line causes lockup if enabled.
  # With the DateTimeWidget removed, the form functions correctly except that there is no widget.
  #activity_date = forms.DateField(label=_('Date'), widget=DateTimeWidget)  ##!!! Point of Error !!!

  class Meta:
    model = Activity
    fields = ('activity_date', 'activity_type', 'activity_description', 'activity_duration', 'est_attendance')

  def __init__(self, *args, **kwargs):
      super(ActivityForm, self).__init__(*args, **kwargs)
      instance = getattr(self, 'instance', None)
      edit_aid = kwargs.get('edit_aid', False)
      # On a different approach, the following also didn't work.
      #self.fields['activity_date'].widget = widgets.AdminDateWidget()


# The Widget
# Example referenced:  http://djangosnippets.org/snippets/391/
calbtn = u""" <button id="calendar-trigger">...</button>
                <img src="%s/site_media/images/icon_calendar.gif" alt="calendar" id="%s_btn" style="cursor: pointer; border: 1px solid #8888aa;" 
                  title="Select date and time"
                  onmouseover="this.style.background='#444444';" onmouseout="this.style.background=''" />


<script type="text/javascript">

    Calendar.setup({
        trigger    : "calendar-trigger",
        inputField : "%s"
    });
</script>"""

class DateTimeWidget(forms.widgets.TextInput):  
    dformat = '%Y-%m-%d %H:%M'
    def render(self, name, value, attrs=None):  
        print "DTWgt render name=%s, value=%s" % name, value
        if value is None: value = ''
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        if value != '': 
            try:
                final_attrs['value'] = \
                                   force_unicode(value.strftime(self.dformat))
            except:
                final_attrs['value'] = \
                                   force_unicode(value)
        if not final_attrs.has_key('id'):
            final_attrs['id'] = u'%s_id' % (name)
        id = final_attrs['id']

        jsdformat = self.dformat #.replace('%', '%%')
        cal = calbtn % (settings.MEDIA_URL, id, id, jsdformat, id)
        a = u'<input%s />%s' % (forms.util.flatatt(final_attrs), cal)
        print "render return %s " % a
        return mark_safe(a)  

    def value_from_datadict(self, data, files, name):  
        print "DTWgt value_from_datadict"
        dtf = forms.fields.DEFAULT_DATETIME_INPUT_FORMATS
        empty_values = forms.fields.EMPTY_VALUES

        value = data.get(name, None)
        if value in empty_values:
            return None
        if isinstance(value, datetime.datetime):
            return value
        if isinstance(value, datetime.date):
            return datetime.datetime(value.year, value.month, value.day)
        for format in dtf:
            try:
                return datetime.datetime(*time.strptime(value, format)[:6])
            except ValueError:
                continue
        return None  

© Stack Overflow or respective owner

Related posts about django

Related posts about widgets