Commit af67ce5e authored by Roberto Aguilar's avatar Roberto Aguilar Committed by Julien Phalip
Browse files

Fixed #4574 -- Added CSS classes to the admin calendar widget for better control over styling.

parent 2bc51438
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -293,8 +293,9 @@ var DateTimeShortcuts = {
            var date_parts = inp.value.split('-');
            var year = date_parts[0];
            var month = parseFloat(date_parts[1]);
            var selected = new Date(inp.value);
            if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
                DateTimeShortcuts.calendars[num].drawDate(month, year);
                DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
            }
        }

+37 −6
Original line number Diff line number Diff line
@@ -27,13 +27,29 @@ var CalendarNamespace = {
        }
        return days;
    },
    draw: function(month, year, div_id, callback) { // month = 1-12, year = 1-9999
    draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
        var today = new Date();
        var todayDay = today.getDate();
        var todayMonth = today.getMonth()+1;
        var todayYear = today.getFullYear();
        var todayClass = '';

        // Use UTC functions here because the date field does not contain time
        // and using the UTC function variants prevent the local time offset
        // from altering the date, specifically the day field.  For example:
        //
        // ```
        // var x = new Date('2013-10-02');
        // var day = x.getDate();
        // ```
        //
        // The day variable above will be 1 instead of 2 in, say, US Pacific time
        // zone.
        var isSelectedMonth = false;
        if (typeof selected != 'undefined') {
            isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month);
        }

        month = parseInt(month);
        year = parseInt(year);
        var calDiv = document.getElementById(div_id);
@@ -55,7 +71,7 @@ var CalendarNamespace = {
        tableRow = quickElement('tr', tableBody);
        for (var i = 0; i < startingPos; i++) {
            var _cell = quickElement('td', tableRow, ' ');
            _cell.style.backgroundColor = '#f3f3f3';
            _cell.className = "nonday";
        }

        // Draw days of month
@@ -69,6 +85,13 @@ var CalendarNamespace = {
            } else {
                todayClass='';
            }

            // use UTC function; see above for explanation.
            if (isSelectedMonth && currentDay == selected.getUTCDate()) {
                if (todayClass != '') todayClass += " ";
                todayClass += "selected";
            }

            var cell = quickElement('td', tableRow, '', 'class', todayClass);

            quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));');
@@ -78,7 +101,7 @@ var CalendarNamespace = {
        // Draw blanks after end of month (optional, but makes for valid code)
        while (tableRow.childNodes.length < 7) {
            var _cell = quickElement('td', tableRow, ' ');
            _cell.style.backgroundColor = '#f3f3f3';
            _cell.className = "nonday";
        }

        calDiv.appendChild(calTable);
@@ -86,7 +109,7 @@ var CalendarNamespace = {
}

// Calendar -- A calendar instance
function Calendar(div_id, callback) {
function Calendar(div_id, callback, selected) {
    // div_id (string) is the ID of the element in which the calendar will
    //     be displayed
    // callback (string) is the name of a JavaScript function that will be
@@ -97,14 +120,22 @@ function Calendar(div_id, callback) {
    this.today = new Date();
    this.currentMonth = this.today.getMonth() + 1;
    this.currentYear = this.today.getFullYear();
    if (typeof selected != 'undefined') {
        this.selected = selected;
    }
}
Calendar.prototype = {
    drawCurrent: function() {
        CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback);
        CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
    },
    drawDate: function(month, year) {
    drawDate: function(month, year, selected) {
        this.currentMonth = month;
        this.currentYear = year;

        if(selected) {
            this.selected = selected;
        }

        this.drawCurrent();
    },
    drawPreviousMonth: function() {
+73 −0
Original line number Diff line number Diff line
@@ -549,6 +549,79 @@ class DateTimePickerSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
        self.assertEqual(
            self.get_css_value('#clockbox0', 'display'), 'none')

    def test_calendar_nonday_class(self):
        """
        Ensure cells that are not days of the month have the `nonday` CSS class.
        Refs #4574.
        """
        self.admin_login(username='super', password='secret', login_url='/')
        # Open a page that has a date and time picker widgets
        self.selenium.get('%s%s' % (self.live_server_url,
            '/admin_widgets/member/add/'))

        # fill in the birth date.
        self.selenium.find_element_by_id('id_birthdate_0').send_keys('2013-06-01')

        # Click the calendar icon
        self.selenium.find_element_by_id('calendarlink0').click()

        # get all the tds within the calendar
        calendar0 = self.selenium.find_element_by_id('calendarin0')
        tds = calendar0.find_elements_by_tag_name('td')

        # make sure the first and last 6 cells have class nonday
        for td in tds[:6] + tds[-6:]:
            self.assertEqual(td.get_attribute('class'), 'nonday')

    def test_calendar_selected_class(self):
        """
        Ensure cell for the day in the input has the `selected` CSS class.
        Refs #4574.
        """
        self.admin_login(username='super', password='secret', login_url='/')
        # Open a page that has a date and time picker widgets
        self.selenium.get('%s%s' % (self.live_server_url,
            '/admin_widgets/member/add/'))

        # fill in the birth date.
        self.selenium.find_element_by_id('id_birthdate_0').send_keys('2013-06-01')

        # Click the calendar icon
        self.selenium.find_element_by_id('calendarlink0').click()

        # get all the tds within the calendar
        calendar0 = self.selenium.find_element_by_id('calendarin0')
        tds = calendar0.find_elements_by_tag_name('td')

        # verify the selected cell
        selected = tds[6]
        self.assertEqual(selected.get_attribute('class'), 'selected')

        self.assertEqual(selected.text, '1')

    def test_calendar_no_selected_class(self):
        """
        Ensure no cells are given the selected class when the field is empty.
        Refs #4574.
        """
        self.admin_login(username='super', password='secret', login_url='/')
        # Open a page that has a date and time picker widgets
        self.selenium.get('%s%s' % (self.live_server_url,
            '/admin_widgets/member/add/'))

        # Click the calendar icon
        self.selenium.find_element_by_id('calendarlink0').click()

        # get all the tds within the calendar
        calendar0 = self.selenium.find_element_by_id('calendarin0')
        tds = calendar0.find_elements_by_tag_name('td')

        # verify there are no cells with the selected class
        selected = [td for td in tds if td.get_attribute('class') == 'selected']

        self.assertEqual(len(selected), 0)


class DateTimePickerSeleniumChromeTests(DateTimePickerSeleniumFirefoxTests):
    webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver'