MDL-48288 gradebook: fix floating footer exception when averages disabled

The code we use to update styles on floating elements did not account for
situations where those floating elements don't exist. This was discovered
when a test site didn't have column averages enabled, resulting in no
floating footer element being created, so when _handleScrollEvent was
fired the first time, a null reference exception was thrown trying to
apply styles to a non-existent element.
This commit is contained in:
Jetha Chan 2014-11-19 15:08:02 +08:00
parent ca0e301c7b
commit a71d9d28b7
4 changed files with 134 additions and 95 deletions

View File

@ -173,7 +173,8 @@ Y.namespace('M.gradereport_grader').init = function(config) {
var HEIGHT = 'height',
WIDTH = 'width',
OFFSETWIDTH = 'offsetWidth',
OFFSETHEIGHT = 'offsetHeight';
OFFSETHEIGHT = 'offsetHeight',
LOGNS = 'moodle-core-grade-report-grader';
CSS.FLOATING = 'floating';
@ -980,43 +981,55 @@ FloatingHeaders.prototype = {
floatingHeaderStyles[SELECTORS.FOOTERTITLE] = floatingFooterTitleStyles;
}
// Apply the styles.
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
this.userColumnHeader.setStyles(userColumnHeaderStyles);
this.userColumn.setStyles(userColumnStyles);
this.footerRow.setStyles(footerStyles);
// Apply the styles and mark elements as floating, or not.
if (this.gradeItemHeadingContainer) {
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
}
if (this.userColumnHeader) {
this.userColumnHeader.setStyles(userColumnHeaderStyles);
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
}
}
if (this.userColumn) {
this.userColumn.setStyles(userColumnStyles);
if (userFloats) {
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumn.removeClass(CSS.FLOATING);
}
}
if (this.footerRow) {
this.footerRow.setStyles(footerStyles);
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
}
// And apply the styles to the generic left headers.
Y.Object.each(floatingHeaderStyles, function(styles, key) {
this.floatingHeaderRow[key].setStyles(styles);
if (this.floatingHeaderRow[key]) {
this.floatingHeaderRow[key].setStyles(styles);
}
}, this);
// Mark the elements as floating, or not.
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
this.userColumn.removeClass(CSS.FLOATING);
}
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
Y.Object.each(this.floatingHeaderRow, function(value, key) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
if (this.floatingHeaderRow[key]) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
}
}
}, this);

View File

@ -173,7 +173,8 @@ Y.namespace('M.gradereport_grader').init = function(config) {
var HEIGHT = 'height',
WIDTH = 'width',
OFFSETWIDTH = 'offsetWidth',
OFFSETHEIGHT = 'offsetHeight';
OFFSETHEIGHT = 'offsetHeight',
LOGNS = 'moodle-core-grade-report-grader';
CSS.FLOATING = 'floating';
@ -979,43 +980,55 @@ FloatingHeaders.prototype = {
floatingHeaderStyles[SELECTORS.FOOTERTITLE] = floatingFooterTitleStyles;
}
// Apply the styles.
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
this.userColumnHeader.setStyles(userColumnHeaderStyles);
this.userColumn.setStyles(userColumnStyles);
this.footerRow.setStyles(footerStyles);
// Apply the styles and mark elements as floating, or not.
if (this.gradeItemHeadingContainer) {
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
}
if (this.userColumnHeader) {
this.userColumnHeader.setStyles(userColumnHeaderStyles);
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
}
}
if (this.userColumn) {
this.userColumn.setStyles(userColumnStyles);
if (userFloats) {
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumn.removeClass(CSS.FLOATING);
}
}
if (this.footerRow) {
this.footerRow.setStyles(footerStyles);
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
}
// And apply the styles to the generic left headers.
Y.Object.each(floatingHeaderStyles, function(styles, key) {
this.floatingHeaderRow[key].setStyles(styles);
if (this.floatingHeaderRow[key]) {
this.floatingHeaderRow[key].setStyles(styles);
}
}, this);
// Mark the elements as floating, or not.
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
this.userColumn.removeClass(CSS.FLOATING);
}
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
Y.Object.each(this.floatingHeaderRow, function(value, key) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
if (this.floatingHeaderRow[key]) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
}
}
}, this);

View File

@ -30,7 +30,8 @@
var HEIGHT = 'height',
WIDTH = 'width',
OFFSETWIDTH = 'offsetWidth',
OFFSETHEIGHT = 'offsetHeight';
OFFSETHEIGHT = 'offsetHeight',
LOGNS = 'moodle-core-grade-report-grader';
CSS.FLOATING = 'floating';
@ -837,43 +838,55 @@ FloatingHeaders.prototype = {
floatingHeaderStyles[SELECTORS.FOOTERTITLE] = floatingFooterTitleStyles;
}
// Apply the styles.
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
this.userColumnHeader.setStyles(userColumnHeaderStyles);
this.userColumn.setStyles(userColumnStyles);
this.footerRow.setStyles(footerStyles);
// Apply the styles and mark elements as floating, or not.
if (this.gradeItemHeadingContainer) {
this.gradeItemHeadingContainer.setStyles(gradeItemHeadingContainerStyles);
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
}
if (this.userColumnHeader) {
this.userColumnHeader.setStyles(userColumnHeaderStyles);
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
}
}
if (this.userColumn) {
this.userColumn.setStyles(userColumnStyles);
if (userFloats) {
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumn.removeClass(CSS.FLOATING);
}
}
if (this.footerRow) {
this.footerRow.setStyles(footerStyles);
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
}
// And apply the styles to the generic left headers.
Y.Object.each(floatingHeaderStyles, function(styles, key) {
this.floatingHeaderRow[key].setStyles(styles);
if (this.floatingHeaderRow[key]) {
this.floatingHeaderRow[key].setStyles(styles);
}
}, this);
// Mark the elements as floating, or not.
if (headerFloats) {
this.gradeItemHeadingContainer.addClass(CSS.FLOATING);
} else {
this.gradeItemHeadingContainer.removeClass(CSS.FLOATING);
}
if (userFloats) {
this.userColumnHeader.addClass(CSS.FLOATING);
this.userColumn.addClass(CSS.FLOATING);
} else {
this.userColumnHeader.removeClass(CSS.FLOATING);
this.userColumn.removeClass(CSS.FLOATING);
}
if (footerFloats) {
this.footerRow.addClass(CSS.FLOATING);
} else {
this.footerRow.removeClass(CSS.FLOATING);
}
Y.Object.each(this.floatingHeaderRow, function(value, key) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
if (this.floatingHeaderRow[key]) {
if (leftTitleFloats) {
this.floatingHeaderRow[key].addClass(CSS.FLOATING);
} else {
this.floatingHeaderRow[key].removeClass(CSS.FLOATING);
}
}
}, this);