Removed dragging and added tool tip to student record.
Clarify and reformat some comments; rename a few functions to clarify those. Convert tabs to spaces. Fix inaccurate comment Fixed jshint issues Adjust how user-select is applied to the gradebook view. Add i18n for a string. Allow selection when not dragging.
This commit is contained in:
committed by
Jamie Folsom
parent
b92d239e47
commit
8b6c3757fe
@@ -2,106 +2,129 @@
|
||||
|
||||
|
||||
var Gradebook = function($element) {
|
||||
var _this = this;
|
||||
var $element = $element;
|
||||
var $body = $('body');
|
||||
var $grades = $element.find('.grades');
|
||||
var $studentTable = $element.find('.student-table');
|
||||
var $gradeTable = $element.find('.grade-table');
|
||||
var $search = $element.find('.student-search-field');
|
||||
var $leftShadow = $('<div class="left-shadow"></div>');
|
||||
var $rightShadow = $('<div class="right-shadow"></div>');
|
||||
var tableHeight = $gradeTable.height();
|
||||
var maxScroll = $gradeTable.width() - $grades.width();
|
||||
|
||||
var mouseOrigin;
|
||||
var tableOrigin;
|
||||
"use strict";
|
||||
var $body = $('body');
|
||||
var $grades = $element.find('.grades');
|
||||
var $studentTable = $element.find('.student-table');
|
||||
var $gradeTable = $element.find('.grade-table');
|
||||
var $search = $element.find('.student-search-field');
|
||||
var $leftShadow = $('<div class="left-shadow"></div>');
|
||||
var $rightShadow = $('<div class="right-shadow"></div>');
|
||||
var tableHeight = $gradeTable.height();
|
||||
var maxScroll = $gradeTable.width() - $grades.width();
|
||||
|
||||
var startDrag = function(e) {
|
||||
mouseOrigin = e.pageX;
|
||||
tableOrigin = $gradeTable.position().left;
|
||||
$body.css('-webkit-user-select', 'none');
|
||||
$body.bind('mousemove', moveDrag);
|
||||
$body.bind('mouseup', stopDrag);
|
||||
};
|
||||
var mouseOrigin;
|
||||
var tableOrigin;
|
||||
|
||||
var moveDrag = function(e) {
|
||||
var offset = e.pageX - mouseOrigin;
|
||||
var targetLeft = clamp(tableOrigin + offset, -maxScroll, 0);
|
||||
var startDrag = function(e) {
|
||||
mouseOrigin = e.pageX;
|
||||
tableOrigin = $gradeTable.position().left;
|
||||
$body.addClass('no-select');
|
||||
$body.bind('mousemove', onDragTable);
|
||||
$body.bind('mouseup', stopDrag);
|
||||
};
|
||||
|
||||
updateHorizontalPosition(targetLeft);
|
||||
/**
|
||||
* - Called when the user drags the gradetable
|
||||
* - Calculates targetLeft, which is the desired position
|
||||
* of the grade table relative to its leftmost position, using:
|
||||
* - the new x position of the user's mouse pointer;
|
||||
* - the gradebook's current x position, and;
|
||||
* - the value of maxScroll (gradetable width - container width).
|
||||
* - Updates the position and appearance of the gradetable.
|
||||
*/
|
||||
var onDragTable = function(e) {
|
||||
var offset = e.pageX - mouseOrigin;
|
||||
var targetLeft = clamp(tableOrigin + offset, maxScroll, 0);
|
||||
updateHorizontalPosition(targetLeft);
|
||||
setShadows(targetLeft);
|
||||
};
|
||||
|
||||
setShadows(targetLeft);
|
||||
};
|
||||
var stopDrag = function() {
|
||||
$body.removeClass('no-select');
|
||||
$body.unbind('mousemove', onDragTable);
|
||||
$body.unbind('mouseup', stopDrag);
|
||||
};
|
||||
|
||||
var stopDrag = function(e) {
|
||||
$body.css('-webkit-user-select', 'auto');
|
||||
$body.unbind('mousemove', moveDrag);
|
||||
$body.unbind('mouseup', stopDrag);
|
||||
};
|
||||
var setShadows = function(left) {
|
||||
var padding = 30;
|
||||
|
||||
var setShadows = function(left) {
|
||||
var padding = 30;
|
||||
var leftPercent = clamp(-left / padding, 0, 1);
|
||||
$leftShadow.css('opacity', leftPercent);
|
||||
|
||||
var leftPercent = clamp(-left / padding, 0, 1);
|
||||
$leftShadow.css('opacity', leftPercent);
|
||||
|
||||
var rightPercent = clamp((maxScroll + left) / padding, 0, 1);
|
||||
$rightShadow.css('opacity', rightPercent);
|
||||
};
|
||||
var rightPercent = clamp((maxScroll + left) / padding, 0, 1);
|
||||
$rightShadow.css('opacity', rightPercent);
|
||||
};
|
||||
|
||||
var clamp = function(val, min, max) {
|
||||
if(val > max) return max;
|
||||
if(val < min) return min;
|
||||
return val;
|
||||
};
|
||||
var clamp = function(val, min, max) {
|
||||
if(val > max) { return max; }
|
||||
if(val < min) { return min; }
|
||||
return val;
|
||||
};
|
||||
|
||||
var updateWidths = function(e) {
|
||||
maxScroll = $gradeTable.width() - $grades.width();
|
||||
var targetLeft = clamp($gradeTable.position().left, -maxScroll, 0);
|
||||
updateHorizontalPosition(targetLeft);
|
||||
setShadows(targetLeft);
|
||||
};
|
||||
/**
|
||||
* - Called when the browser window is resized.
|
||||
* - Recalculates maxScroll (gradetable width - container width).
|
||||
* - Calculates targetLeft, which is the desired position
|
||||
* of the grade table relative to its leftmost position, using:
|
||||
* - the gradebook's current x position, and:
|
||||
* - the new value of maxScroll
|
||||
* - Updates the position and appearance of the gradetable.
|
||||
*/
|
||||
var onResizeTable = function() {
|
||||
maxScroll = $gradeTable.width() - $grades.width();
|
||||
var targetLeft = clamp($gradeTable.position().left, maxScroll, 0);
|
||||
updateHorizontalPosition(targetLeft);
|
||||
setShadows(targetLeft);
|
||||
};
|
||||
|
||||
var updateHorizontalPosition = function(left) {
|
||||
$gradeTable.css({
|
||||
'left': left + 'px'
|
||||
});
|
||||
};
|
||||
/**
|
||||
* - Called on table drag and on window (table) resize.
|
||||
* - Takes a integer value for the desired (pixel) offset from the left
|
||||
* (zero/origin) position of the grade table.
|
||||
* - Uses that value to position the table relative to its leftmost
|
||||
* possible position within its container.
|
||||
*
|
||||
* @param {Number} left - The desired pixel offset from left of the
|
||||
* desired position. If the value is 0, the gradebook should be moved
|
||||
* all the way to the left side relative to its parent container.
|
||||
*/
|
||||
var updateHorizontalPosition = function(left) {
|
||||
$grades.scrollLeft(left);
|
||||
};
|
||||
|
||||
var highlightRow = function(e) {
|
||||
$element.find('.highlight').removeClass('highlight');
|
||||
var highlightRow = function() {
|
||||
$element.find('.highlight').removeClass('highlight');
|
||||
|
||||
var index = $(this).index();
|
||||
$studentTable.find('tr').eq(index + 1).addClass('highlight');
|
||||
$gradeTable.find('tr').eq(index + 1).addClass('highlight');
|
||||
};
|
||||
var index = $(this).index();
|
||||
$studentTable.find('tr').eq(index + 1).addClass('highlight');
|
||||
$gradeTable.find('tr').eq(index + 1).addClass('highlight');
|
||||
};
|
||||
|
||||
var filter = function(e) {
|
||||
var term = $(this).val();
|
||||
if(term.length > 0) {
|
||||
$studentTable.find('tbody tr').hide();
|
||||
$gradeTable.find('tbody tr').hide();
|
||||
$studentTable.find('tbody tr:contains(' + term + ')').each(function(i) {
|
||||
$(this).show();
|
||||
$gradeTable.find('tr').eq($(this).index() + 1).show();
|
||||
});
|
||||
} else {
|
||||
$studentTable.find('tbody tr').show();
|
||||
$gradeTable.find('tbody tr').show();
|
||||
}
|
||||
}
|
||||
var filter = function() {
|
||||
var term = $(this).val();
|
||||
if(term.length > 0) {
|
||||
$studentTable.find('tbody tr').hide();
|
||||
$gradeTable.find('tbody tr').hide();
|
||||
$studentTable.find('tbody tr:contains(' + term + ')').each(function() {
|
||||
$(this).show();
|
||||
$gradeTable.find('tr').eq($(this).index() + 1).show();
|
||||
});
|
||||
} else {
|
||||
$studentTable.find('tbody tr').show();
|
||||
$gradeTable.find('tbody tr').show();
|
||||
}
|
||||
};
|
||||
|
||||
$leftShadow.css('height', tableHeight + 'px');
|
||||
$rightShadow.css('height', tableHeight + 'px');
|
||||
$grades.append($leftShadow).append($rightShadow);
|
||||
setShadows(0);
|
||||
$grades.css('height', tableHeight);
|
||||
$gradeTable.bind('mousedown', startDrag);
|
||||
$element.find('tr').bind('mouseover', highlightRow);
|
||||
$search.bind('keyup', filter);
|
||||
$(window).bind('resize', updateWidths);
|
||||
}
|
||||
$leftShadow.css('height', tableHeight + 'px');
|
||||
$grades.append($leftShadow).append($rightShadow);
|
||||
setShadows(0);
|
||||
$grades.css('height', tableHeight);
|
||||
$gradeTable.bind('mousedown', startDrag);
|
||||
$element.find('tr').bind('mouseover', highlightRow);
|
||||
$search.bind('keyup', filter);
|
||||
$(window).bind('resize', onResizeTable);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
$cell-border-color: #e1e1e1;
|
||||
$table-border-color: #c8c8c8;
|
||||
|
||||
.no-select {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
div.gradebook-wrapper {
|
||||
|
||||
section.gradebook-content {
|
||||
@@ -75,7 +84,8 @@ div.gradebook-wrapper {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 76%;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
.left-shadow,
|
||||
.right-shadow {
|
||||
|
||||
@@ -74,13 +74,24 @@ from django.core.urlresolvers import reverse
|
||||
<thead>
|
||||
<tr> <!-- Header Row -->
|
||||
%for section in templateSummary['section_breakdown']:
|
||||
<th><div class="assignment-label">${section['label']}</div></th>
|
||||
<%
|
||||
tooltip_str = section['detail']
|
||||
# We are making header labels from the first student record. So for tool tip (title),
|
||||
# I am processing this string ```section['detail']``` from student record and removing
|
||||
# all student related data i.e marks, percentage etc to get only the title of homework.
|
||||
if "=" in section['detail']:
|
||||
tooltip_str = section['detail'][0: section['detail'].rfind('=')]
|
||||
|
||||
if "-" in tooltip_str:
|
||||
tooltip_str = tooltip_str[0: tooltip_str.rfind('-')]
|
||||
%>
|
||||
<th title="${tooltip_str}"><div class="assignment-label">${section['label']}</div></th>
|
||||
%endfor
|
||||
<th><div class="assignment-label">Total</div></th>
|
||||
<th title="${_('Total')}"><div class="assignment-label">${_('Total')}</div></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<%def name="percent_data(fraction)">
|
||||
<%def name="percent_data(fraction, label)">
|
||||
<%
|
||||
letter_grade = 'None'
|
||||
if fraction > 0:
|
||||
@@ -92,16 +103,16 @@ from django.core.urlresolvers import reverse
|
||||
|
||||
data_class = "grade_" + letter_grade
|
||||
%>
|
||||
<td class="${data_class}" data-percent="${fraction}">${ "{0:.0f}".format( 100 * fraction ) }</td>
|
||||
<td class="${data_class}" data-percent="${fraction}" title="${label}">${ "{0:.0f}".format( 100 * fraction ) }</td>
|
||||
</%def>
|
||||
|
||||
<tbody>
|
||||
%for student in students:
|
||||
<tr>
|
||||
%for section in student['grade_summary']['section_breakdown']:
|
||||
${percent_data( section['percent'] )}
|
||||
${percent_data( section['percent'], section['detail'] )}
|
||||
%endfor
|
||||
${percent_data( student['grade_summary']['percent'])}
|
||||
${percent_data( student['grade_summary']['percent'], _('Total'))}
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user