Start of week in datepicker in Grappelli admin interface

976 Views Asked by At

The Grappelli default datepicker comes with Sunday as the first day of the week. This is really irritating! I want Monday to be the first day of the week for all my present and future models.

Is there a way to do this?

So far, the only "solution" I found involved changing the models' Media class. However, this solution does not seem to work as is with the following:

class Monkey(ImportExportActionModelAdmin):

    class Media:
        js = ("static/i18n/ui.datepicker-en-GB.js")

    ...

Where static/i18n/ui.datepicker-en-GB.js is

(function($) {
    // datepicker, timepicker init
    grappelli.initDateAndTimePicker = function() {

        var options = {
            closeText: "Done",
            prevText: "Prev",
            nextText: "Next",
            currentText: "Today",
            monthNames: [ "January","February","March","April","May","June",
            "July","August","September","October","November","December" ],
            monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
            dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
            dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
            dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ],
            weekHeader: "Wk",
            dateFormat: "dd/mm/yy",
            firstDay: 1,
            isRTL: false,
            showMonthAfterYear: false,
            yearSuffix: ""
        };

} )(grp.jQuery);

In any case, this solution is sub-optimal as any new model using a date would have to have the same Meta class defined.

2

There are 2 best solutions below

0
Sardathrion - against SE abuse On BEST ANSWER

There are indeed a few mistakes in the code above.

First, the AdminModel should be

class Monkey(ImportExportActionModelAdmin):

    class Media:
        js = ("i18n/ui.datepicker-en-GB.js", )

    ...

As the static directory is automatically appended and the js variable must be a tuple -- notice the comma.

Second, the javascrpt I used was a copy-and-paste of the static/grappelli/js/grappelli.js one with the option firstDay: 1, added to the options variable. It reads like so:

(function($) {
    grappelli.initDateAndTimePicker = function() {

        // HACK: get rid of text after DateField (hardcoded in django.admin)
        $('p.datetime').each(function() {
            var text = $(this).html();
            text = text.replace(/^\w*: /, "");
            text = text.replace(/<br>[^<]*: /g, "<br>");
            $(this).html(text);
        });

        var options = {
            firstDay: 1,  // THIS IS THE ONLY CHANGE!!!
            constrainInput: false,
            showOn: 'button',
            buttonImageOnly: false,
            buttonText: '',
            dateFormat: grappelli.getFormat('date'),
            showButtonPanel: true,
            showAnim: '',
            // HACK: sets the current instance to a global var.
            // needed to actually select today if the today-button is clicked.
            // see onClick handler for ".ui-datepicker-current"
            beforeShow: function(year, month, inst) {
                grappelli.datepicker_instance = this;
            }
        };
        var dateFields = $("input[class*='vDateField']:not([id*='__prefix__'])");
        dateFields.datepicker(options);

        if (typeof IS_POPUP != "undefined" && IS_POPUP) {
            dateFields.datepicker('disable');
        }

        // HACK: adds an event listener to the today button of datepicker
        // if clicked today gets selected and datepicker hides.
        // use on() because couldn't find hook after datepicker generates it's complete dom.
        $(document).on('click', '.ui-datepicker-current', function() {
            $.datepicker._selectDate(grappelli.datepicker_instance);
            grappelli.datepicker_instance = null;
        });

        // init timepicker
        $("input[class*='vTimeField']:not([id*='__prefix__'])").grp_timepicker();

    };
})(grp.jQuery);

Thirdly, I modified all the AdminModels that needed a datepicker. This is a PITA and I wish there was a better way of doing it. There might be...

0
Peter Tröger On

The first part of the solution is to add another JavaScript file to the admin view, as already described by @Sardathrion:

class MyModelAdmin(ModelAdmin):
    class Media:
        js = ('js/grappellihacks.js',)

The second part is to re-configure the rendered datepicker widgets. Since they get a common class attribute, this code inside of your grappellihacks.js should be enough:

grp.jQuery(function() {
    grp.jQuery('.hasDatepicker').datepicker('option', 'firstDay', 1);
});

The option is described in the jQuery UI documentation. The grp attribute is set by grappelli.js, which is loaded by the admin template before your custom media file.