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

This commit is contained in:
Roberto Aguilar 2013-09-07 21:12:13 +00:00 committed by Julien Phalip
parent 2bc5143866
commit af67ce5e18
3 changed files with 112 additions and 7 deletions

View File

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

View File

@ -27,13 +27,29 @@ var CalendarNamespace = {
} }
return days; 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 today = new Date();
var todayDay = today.getDate(); var todayDay = today.getDate();
var todayMonth = today.getMonth()+1; var todayMonth = today.getMonth()+1;
var todayYear = today.getFullYear(); var todayYear = today.getFullYear();
var todayClass = ''; 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); month = parseInt(month);
year = parseInt(year); year = parseInt(year);
var calDiv = document.getElementById(div_id); var calDiv = document.getElementById(div_id);
@ -55,7 +71,7 @@ var CalendarNamespace = {
tableRow = quickElement('tr', tableBody); tableRow = quickElement('tr', tableBody);
for (var i = 0; i < startingPos; i++) { for (var i = 0; i < startingPos; i++) {
var _cell = quickElement('td', tableRow, ' '); var _cell = quickElement('td', tableRow, ' ');
_cell.style.backgroundColor = '#f3f3f3'; _cell.className = "nonday";
} }
// Draw days of month // Draw days of month
@ -69,6 +85,13 @@ var CalendarNamespace = {
} else { } else {
todayClass=''; 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); var cell = quickElement('td', tableRow, '', 'class', todayClass);
quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));'); 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) // Draw blanks after end of month (optional, but makes for valid code)
while (tableRow.childNodes.length < 7) { while (tableRow.childNodes.length < 7) {
var _cell = quickElement('td', tableRow, ' '); var _cell = quickElement('td', tableRow, ' ');
_cell.style.backgroundColor = '#f3f3f3'; _cell.className = "nonday";
} }
calDiv.appendChild(calTable); calDiv.appendChild(calTable);
@ -86,7 +109,7 @@ var CalendarNamespace = {
} }
// Calendar -- A calendar instance // 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 // div_id (string) is the ID of the element in which the calendar will
// be displayed // be displayed
// callback (string) is the name of a JavaScript function that will be // 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.today = new Date();
this.currentMonth = this.today.getMonth() + 1; this.currentMonth = this.today.getMonth() + 1;
this.currentYear = this.today.getFullYear(); this.currentYear = this.today.getFullYear();
if (typeof selected != 'undefined') {
this.selected = selected;
}
} }
Calendar.prototype = { Calendar.prototype = {
drawCurrent: function() { 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.currentMonth = month;
this.currentYear = year; this.currentYear = year;
if(selected) {
this.selected = selected;
}
this.drawCurrent(); this.drawCurrent();
}, },
drawPreviousMonth: function() { drawPreviousMonth: function() {

View File

@ -549,6 +549,79 @@ class DateTimePickerSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
self.assertEqual( self.assertEqual(
self.get_css_value('#clockbox0', 'display'), 'none') 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): class DateTimePickerSeleniumChromeTests(DateTimePickerSeleniumFirefoxTests):
webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver'