How to use a JQuery Datepicker with the Django template language

17,468

Solution 1

Edit your date widgets attributes in your model form, giving them the class '.datepicker', as that's what the JQuery datepicker will look for. So your ModelForm becomes:

class EForm(forms.ModelForm):
    class Meta:
        model = EModel
        widgets = {'date': DateInput(attrs={'class': 'datepicker'})}

Documentation here.

Solution 2

I use the following code and it works fine for me. I have mentioned all the files for this project,

models.py

    from django.db import models
    class EModel(models.Model):
        date = models.DateField(blank=False)

forms.py

    from django import forms
    from testApp.models import EModel
    class EForm(forms.ModelForm):
        class Meta:
            model = EModel
            widgets = {'date': forms.DateInput(attrs={'class': 'datepicker'})}

form.html

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Form</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css" />
        <script>
        $(function() {
            $( "#id_date" ).datepicker();
        });
        </script>
    </head>
    <body>
        <form action="/datepickerview/" method="post">{% csrf_token %}
            <!--{{ form.date }} -->
            <p>Date: <input name='date' type="text" id="id_date"></p>
            <!-- The rest of my form -->
            <input type="submit" value="login" />
        </form>
    </body>

views.py

    from django.shortcuts import render
    from django.http import HttpResponse
    from django.template import Context
    from django.shortcuts import render_to_response
    from django.http import HttpResponseRedirect
    from django.core.context_processors import csrf
    from django.template import RequestContext
    from forms import EForm
    def datepickerview(request):
        # Get the context from the request.
        context = RequestContext(request)
        # A HTTP POST?
        if request.method == 'POST':
            form = EForm(request.POST)
            # Have we been provided with a valid form?
            if form.is_valid():
                form.save(commit=True)
                return HttpResponse("Successfully added the date to database");
            else:
                # The supplied form contained errors - just print them to the terminal.
                print form.errors
        else:
            # If the request was not a POST, display the form to enter details.
            form = EForm()
        return render_to_response('form.html', {'form': form}, context)

urls.py

    from django.conf.urls import patterns, include, url
    from django.contrib import admin
    admin.autodiscover()
    urlpatterns = patterns('',
    url(r'^datepickerview/$', 'testApp.views.datepickerview'),
    )

admin.py

    from django.contrib import admin
    from testApp.models import EModel
    admin.site.register(EModel)

Solution 3

The best is to create a new widget in a widgets.py file in your app:

Here is an example of mine for a color picker:

-- widgets.py --

from django import forms
from django.conf import settings
from django.utils.safestring import mark_safe

class ColorPickerWidget(forms.TextInput):
    class Media:
        css = {
            'all': (
                settings.STATIC_URL + 'colorpicker/css/colorpicker.css',
            )
        }
        js = (
            settings.STATIC_URL + 'js/jquery-1.8.3.min.js',
            settings.STATIC_URL + 'colorpicker/js/colorpicker.js',
        )

    def __init__(self, language=None, attrs=None):
        self.language = language or settings.LANGUAGE_CODE[:2]
        super(ColorPickerWidget, self).__init__(attrs=attrs)

    def render(self, name, value, attrs=None):
        rendered = super(ColorPickerWidget, self).render(name, value, attrs)
        return rendered + mark_safe(u'''
            <script type="text/javascript">
                jQuery('#id_%s').css("background-color", "#"+jQuery('#id_%s').val());
                jQuery('#id_%s').ColorPicker({
                    onSubmit: function(hsb, hex, rgb, el) {
                        jQuery(el).val(hex);
                        jQuery(el).css("background-color", "#"+hex);
                        jQuery(el).ColorPickerHide();
                    },
                    onBeforeShow: function () {
                        code = this.value
                        if (code.length==3) code = code.charAt(0)+code.charAt(0)+code.charAt(1)+code.charAt(1)+code.charAt(2)+code.charAt(2);
                        jQuery(this).ColorPickerSetColor(code);
                    }
                }).bind('keyup', function(){
                    el = jQuery(this);
                    code = el.val();
                    hex = '#'+code;
                    var isOk  = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
                    if (isOk) {
                        el.css("background-color", hex);
                        if (code.length==3) code = code.charAt(0)+code.charAt(0)+code.charAt(1)+code.charAt(1)+code.charAt(2)+code.charAt(2);
                        el.ColorPickerSetColor(code);
                    }
                    else if (code=="") el.css("background-color", "");
                });
            </script>
            ''' % (name, name, name))

--- views.py ---

from django import forms ColorPickerWidget
from myapp.widgets import
class EditBackgroundForm(forms.Form):
    background = forms.CharField(max_length=10, widget= ColorPickerWidget(), required = False, label="Background color")

In additions you can also create a custom form field with your widget, and overide its clean() method.

Share:
17,468
reZach
Author by

reZach

Updated on June 11, 2022

Comments

  • reZach
    reZach almost 2 years

    Looked at this link and found some help but I am wondering how I can choose to use a JQueryUI Datepicker widget for a DateField I have in my models.py

    models.py


    from django.db import models
    
    class EModel(models.Model):
    
        date = models.DateField(blank=False)
    

    forms.py


    from django import forms
    from models import EModel
    
    class EForm(forms.ModelForm):
        class Meta:
            model = EModel
    

    form.html - How Django renders my form. Not in the admin page

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Form</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
        <link rel="stylesheet" href="/resources/demos/style.css" />
    </head>
    <body>
        <form action="" method="post">{% csrf_token %}
            {{ form.date }} <!-- ***** -->
            <!-- The rest of my form -->
        </form>
    </body>
    

    I am hoping for a way to make my 'date' model field render as a JQueryUI Datepicker widget, but I have searched around and found no way to link the two (in my case).

    SOLUTION








    In my forms.py

    from django import forms
    from models import EModel
    
    class EForm(forms.ModelForm):
        class Meta:
            model = EModel
            widgets = {
                'date' : forms.DateInput(attrs={'type':'date'})
            }