allow showing only a certain section in gradebook

if they can only see 1 section (possibly the default section),
they do not get the option to change it.

they can only change sections they are allowed to see

the setting is stored in $.store.userGet and is keyed
off of the course too so it will be remembered for a
given user/course/browser combo.

if the page loads and tries to show only a section,
but that section does not have anyone in it, or they
cant see anyone in it, it will alert() reload to show
all sections.

fixes #3653

Change-Id: Ie6de238ac8e1d5367ae8ab961aaa0fcc1ca66c1e
Reviewed-on: https://gerrit.instructure.com/2324
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Whitmer <brian@instructure.com>
This commit is contained in:
Ryan Shaw 2011-02-16 17:36:00 -07:00
parent 37b74ecc04
commit 5718b9520b
5 changed files with 215 additions and 153 deletions

View File

@ -196,142 +196,6 @@
:title => "New message for this submission",
:class => "new_message" %>
</div>
<% js_block do %>
<script type="text/javascript">
lastGradebookUpdate = "<%= ActiveSupport::TimeWithZone.new(Time.now, Time.zone).strftime("%Y-%m-%dT%H:%M:%S") %>";
var ignoreUngradedSubmissions = true;
setTimeout(function() {
$(document).ready(function() {
$("#embed_code input[type='button']").click(function() {
$("#embed_code textarea:first").focus().select();
});
$(document).delegate('#gradebook_options', 'click', function(event) {
event.preventDefault();
event.stopPropagation();
var show = $("#hide_students_option").attr('checked');
var hide_show = "Show";
var options = {
'<span class="ui-icon ui-icon-person">&nbsp;</span> Show Student Names': function() {
$("#hide_students_option").attr('checked', false).change();
}
}
if(!show) {
hide_show = "Hide";
options = {
'<span class="ui-icon ui-icon-person">&nbsp;</span> Hide Student Names': function() {
$("#hide_students_option").attr('checked', true).change();
}
}
}
if(!ignoreUngradedSubmissions) {
options['<span class="ui-icon ui-icon-check">&nbsp;</span> Ignore Ungraded Assignments'] = function() {
ignoreUngradedSubmissions = true;
gradebook.updateAllStudentGrades();
}
} else {
options['<span class="ui-icon ui-icon-check">&nbsp;</span> Include Ungraded Assignments'] = function() {
ignoreUngradedSubmissions = false;
gradebook.updateAllStudentGrades();
}
}
options['<span class="ui-icon ui-icon-carat-2-e-w">&nbsp;</span> Sort Columns By...'] = function() {
$(".sort_gradebook").each(function() {
$(this).attr('disabled', false).text($(this).attr('title'));
});
$("#sort_columns_dialog").dialog('close').dialog({
autoOpen: false,
width: 400,
height: 300
}).dialog('open');
};
options['<span class="ui-icon ui-icon-carat-2-n-s">&nbsp;</span> Sort Rows By...'] = function() {
$(".sort_gradebook").each(function() {
$(this).attr('disabled', false).text($(this).attr('title'));
});
$("#sort_rows_dialog").dialog('close').dialog({
autoOpen: false,
width: 400,
height: 300
}).dialog('open');
};
options['<span class="ui-icon ui-icon-pencil">&nbsp;</span> Set Group Weights'] = function() {
$("#groups_data").dialog('close').dialog({
title: "Assignment Groups",
autoOpen: false
}).dialog('open').show();
};
options['<span class="ui-icon ui-icon-clock">&nbsp;</span> View Grading History'] = function() {
location.href = $(".gradebook_history_url").attr('href');
};
options['<span class="ui-icon ui-icon-disk">&nbsp;</span> Download Scores (.csv)'] = function() {
location.href = $(".gradebook_csv_url").attr('href');
};
options['<span class="ui-icon ui-icon-clock">&nbsp;</span> Upload Scores (from .csv) '] = function() {
$("#upload_modal").dialog({
bgiframe: true,
autoOpen: false,
modal: true,
width: 410,
resizable: false,
buttons: {
'Upload Data': function() {
$(this).submit();
}
}
}).dialog('open');
};
$(this).dropdownList({
options: options
});
});
$(".sort_gradebook").click(function(event) {
event.preventDefault();
var $button = $(this);
if($button.hasClass('by_grade') && !gradebook.finalGradesReady) {
$button.attr('disabled', true).text("Computing Grades...");
setTimeout(function() {
if($button.filter(":visible").length > 0) {
$button.click();
}
}, 1000);
return;
}
$button.attr('disabled', false);
$button.text($button.attr('title'));
if($button.hasClass('sort_rows')) {
sortStudentRows(function(student) {
if($button.hasClass('by_secondary_identifier')) {
return [student.secondary_identifier, student.display_name, student.course_section];
} else if($button.hasClass('by_section')) {
return [student.course_section, student.display_name, student.secondary_identifier];
} else if($button.hasClass('by_grade_desc')) {
return [Math.round((1000 - student.grade) * 10.0), student.display_name, student.secondary_identifier, student.course_section];
} else if($button.hasClass('by_grade_asc')) {
return [10000 + Math.round(student.grade * 10.0), student.display_name, student.secondary_identifier, student.course_section];
} else {
return [student.display_name, student.secondary_identifier, student.course_section];
}
});
} else {
sortAssignmentColumns(function(assignment) {
var list = [assignment.special_sort, assignment.date_sortable || "1050-12-12T99:99", assignment.title];
if($button.hasClass('by_group')) {
list.unshift(parseInt(assignment.groupData[assignment.group_id || assignment.id.toString().substring(6)], 10));
}
return list;
});
}
$("#sort_rows_dialog").dialog('close');
$("#sort_columns_dialog").dialog('close');
});
sortStudentRows
});
}, 1000);
// only update entries that have changed since the last gradebook update!
// compare to all updates, replace value with the highest update (keep it all server-time based)
</script>
<% end %>
<div id="loading_submission_details_dialog" style="display: none;">
<a href="<%= context_url(@context, :context_assignment_submission_url, "{{ assignment_id }}", "{{ user_id }}") %>" class="submission_details_url" style="display: none;">&nbsp;</a>
<div style="margin: 20px 10px; text-align: center; font-size: 1.5em; ">
@ -412,7 +276,7 @@
<div style="display: none;">
<div id="submission_comment_attachment_blank">
<a href="<%= context_url(@context, :context_assignment_submission_url, "{{ assignment_id }}", "{{ user_id }}", :download => "{{ id }}", :comment_id => "{{ comment_id }}") %>" class="file">Download <span class="display_name">&nbsp;</span></a>
</div>http://localhost:3000/courses/5/gradebook#
</div>
</div>
<%= image_tag 'word_bubble.png', :title => "Submission Comments", :id => "information_link", :style => "position: absolute; top: 2px; right: 1px; display: none; cursor: pointer;" %>
@ -444,6 +308,12 @@
<button type="button" class="button sort_gradebook sort_columns by_group" title="By Assignment Group" style="width: 300px;">By Assignment Group</button>
</div>
</div>
<div id="section_to_show_dialog" title="Choose A Section To Show">
<label for="section-to-show">Section to show</label>
<select id="section-to-show">
<option value="all">All</option>
</select>
</div>
<div id="sort_rows_dialog" title="Sort Gradebook Rows">
<h2>Sort Gradebook Rows:</h2>
<div style="margin-bottom: 5px;">
@ -465,3 +335,6 @@
<%= render :partial => "shared/message_students" %>
</div>
<script>
var lastGradebookUpdate = "<%= ActiveSupport::TimeWithZone.new(Time.now, Time.zone).strftime("%Y-%m-%dT%H:%M:%S") %>";
</script>

View File

@ -3,5 +3,5 @@
<% e = @context.course_sections.active.count > 1 && @enrollments_hash && @enrollments_hash[student.id] && @enrollments_hash[student.id].course_section && @enrollments_hash[student.id] %>
<div class="secondary_identifier <%= 'with_section' if e %>" title="<%= student.secondary_identifier %>"><%= student.secondary_identifier %></div>
<% if e %>
<div class="course_section" title="<%= e.course_section.display_name %>"><%= e.course_section.display_name %></div>
<div class="course_section" data-course_section_id="<%= e.course_section.id %>" title="<%= e.course_section.display_name %>"><%= e.course_section.display_name %></div>
<% end %>

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
(function(){
var gradebook = (function(){
var $loading_gradebook_progressbar = $("#loading_gradebook_progressbar"),
$default_grade_form = $("#default_grade_form"),
$assignment_details_dialog = $("#assignment_details_dialog"),
@ -26,9 +26,33 @@
$message_students_dialog = $("#message_students_dialog"),
$information_link = $("#information_link"),
$total_tooltip = $("#total_tooltip"),
content_offset = $("#content").offset();
content_offset = $("#content").offset(),
ignoreUngradedSubmissions = true;
var possibleSections = {},
$courseSections = $(".outer_student_name .course_section").each(function(){
possibleSections[$(this).data('course_section_id')] = $(this).attr('title');
}),
contextId = $("#current_context_code").text().split("_")[1],
sectionToShow = $.store.userGet("grading_show_only_section" + contextId);
window.gradebook = {
if (sectionToShow) {
var atLeastOnePersonExistsInThisSection = false;
$courseSections.add('.gradebook_table .course_section').each(function() {
if ($(this).data('course_section_id') != sectionToShow){
$(this).closest('tr').remove();
} else {
atLeastOnePersonExistsInThisSection = true;
}
});
if (!atLeastOnePersonExistsInThisSection) {
alert("Could not find any students in that section, falling back to showing all sections.");
$.store.userRemove("grading_show_only_section"+contextId);
window.location.reload();
}
}
var gradebook = {
hoverCount: -1,
fileIndex: 1,
assignmentIndexes: {},
@ -81,7 +105,7 @@
.attr('role', 'grid')
.prepend(function(){
var topRowHtml = $("#datagrid_top .assignment_title").map(function(){
return "<div role='columnheader' id='th_" + $(this).parents('.assignment_header').attr('id') + "' tabindex='-1'>" + $(this).text() + "</div>"
return "<div role='columnheader' id='th_" + $(this).parents('.assignment_header').attr('id') + "' tabindex='-1'>" + $(this).text() + "</div>";
}).get().join("");
return "<div class='hidden-readable' role='row'><div role='columnheader' tabindex='-1'>Student Name</div>" + topRowHtml +"</div>";
})
@ -101,8 +125,8 @@
}
});
}
};
$(document).ready(function() {
gradebook.pointCalculations = !$("#class_weighting_policy").attr('checked');
var init = function() {
@ -333,7 +357,7 @@
.find(".assignment_link").attr('href', data.url);
};
options['<span class="ui-icon ui-icon-newwin">&nbsp;</span> SpeedGrader'] = function() {
window.open(extendedGradebookURL);
window.location.href = extendedGradebookURL;
};
options['<span class="ui-icon ui-icon-mail-closed">&nbsp;</span> Message Students Who...'] = function() {
var data = objectData($td),
@ -380,7 +404,7 @@
return student.score != null && student.score !== "" && cutoff != null && student.score > cutoff;
}
});
return $.map(students, function(student) { return student.user_data.id });
return $.map(students, function(student) { return student.user_data.id; });
}
});
};
@ -910,9 +934,144 @@
$curve_grade_dialog.dialog('close');
});
}, 1500);
$('#gradebook_options').live('click', function(event) {
event.preventDefault();
event.stopPropagation();
var options = {
'<span class="ui-icon ui-icon-carat-2-e-w" /> Sort Columns By...' : function() {
$(".sort_gradebook").each(function() {
$(this).attr('disabled', false).text($(this).attr('title'));
});
$("#sort_columns_dialog").dialog('close').dialog({
autoOpen: false,
width: 400,
height: 300
}).dialog('open');
},
'<span class="ui-icon ui-icon-carat-2-n-s" /> Sort Rows By...' : function() {
$(".sort_gradebook").each(function() {
$(this).attr('disabled', false).text($(this).attr('title'));
});
$("#sort_rows_dialog").dialog('close').dialog({
autoOpen: false,
width: 400,
height: 300
}).dialog('open');
},
'<span class="ui-icon ui-icon-pencil" /> Set Group Weights' : function() {
$("#groups_data").dialog('close').dialog({
title: "Assignment Groups",
autoOpen: false
}).dialog('open').show();
},
'<span class="ui-icon ui-icon-clock" /> View Grading History' : function() {
window.location.href = $(".gradebook_history_url").attr('href');
},
'<span class="ui-icon ui-icon-disk" /> Download Scores (.csv)' : function() {
window.location.href = $(".gradebook_csv_url").attr('href');
},
'<span class="ui-icon ui-icon-clock" /> Upload Scores (from .csv) ' : function() {
$("#upload_modal").dialog({
bgiframe: true,
autoOpen: false,
modal: true,
width: 410,
resizable: false,
buttons: {
'Upload Data': function() {
$(this).submit();
}
}
}).dialog('open');
}
};
var show = $("#hide_students_option").attr('checked');
options['<span class="ui-icon ui-icon-person" /> ' + (show ? 'Show' : 'Hide') + ' Student Names'] = function() {
$("#hide_students_option").attr('checked', !show).change();
};
options['<span class="ui-icon ui-icon-check" /> ' + (ignoreUngradedSubmissions ? 'Include' : 'Ignore') + ' Ungraded Assignments'] = function() {
ignoreUngradedSubmissions = !ignoreUngradedSubmissions;
gradebook.updateAllStudentGrades();
};
if ($.size(possibleSections) > 1) {
var sectionToShowLabel = sectionToShow ?
('Showing Section: ' + possibleSections[sectionToShow]) :
'Showing All Sections';
options['<span class="ui-icon ui-icon-search" />' + sectionToShowLabel] = function() {
var $dialog = $("#section_to_show_dialog").dialog({
modal: true,
resizable: false,
buttons: {
'Change Section': function() {
var val = $("#section_to_show_dialog select").val();
$.store[val == "all" ? 'userRemove' : 'userSet']("grading_show_only_section"+contextId, val);
window.location.reload();
}
}
});
var $select = $dialog.find('select');
$select.find('[value != all]').remove();
for (var key in possibleSections) {
$select.append('<option value="' + key + '" ' + (sectionToShow == key ? 'selected' : '') + ' >' + possibleSections[key] + '</option>');
}
};
}
$(this).dropdownList({
options: options
});
});
$(".sort_gradebook").click(function(event) {
event.preventDefault();
var $button = $(this);
if($button.hasClass('by_grade') && !gradebook.finalGradesReady) {
$button.attr('disabled', true).text("Computing Grades...");
setTimeout(function() {
if($button.filter(":visible").length > 0) {
$button.click();
}
}, 1000);
return;
}
$button.attr('disabled', false);
$button.text($button.attr('title'));
if($button.hasClass('sort_rows')) {
sortStudentRows(function(student) {
if($button.hasClass('by_secondary_identifier')) {
return [student.secondary_identifier, student.display_name, student.course_section];
} else if($button.hasClass('by_section')) {
return [student.course_section, student.display_name, student.secondary_identifier];
} else if($button.hasClass('by_grade_desc')) {
return [Math.round((1000 - student.grade) * 10.0), student.display_name, student.secondary_identifier, student.course_section];
} else if($button.hasClass('by_grade_asc')) {
return [10000 + Math.round(student.grade * 10.0), student.display_name, student.secondary_identifier, student.course_section];
} else {
return [student.display_name, student.secondary_identifier, student.course_section];
}
});
} else {
sortAssignmentColumns(function(assignment) {
var list = [assignment.special_sort, assignment.date_sortable || "1050-12-12T99:99", assignment.title];
if($button.hasClass('by_group')) {
list.unshift(parseInt(assignment.groupData[assignment.group_id || assignment.id.toString().substring(6)], 10));
}
return list;
});
}
$("#sort_rows_dialog").dialog('close');
$("#sort_columns_dialog").dialog('close');
});
});
function objectData($td) {
var id = $td.data('object_id');
@ -955,6 +1114,7 @@
}
return data;
}
function submitDataEntry(data, fromDialog) {
var formData = $update_submission_form.getFormData();
var $div = $("#submission_" + data.student_id + "_" + data.assignment_id);
@ -995,6 +1155,7 @@
$.ajaxJSON($update_submission_form.attr('action'), 'POST', formData, formSuccess, formError);
}
}
function updateSubmission(submission) {
if(!submission) { return; }
var $submission = null;
@ -1084,6 +1245,7 @@
$submission_grade.empty().append(emptySubmissionText(submission));
}
}
function emptySubmissionText(submission) {
var result = $("#submission_" + submission.submission_type + "_image").clone().attr('id', '');
if(result.length === 0) {
@ -1091,6 +1253,7 @@
}
return result;
}
function updateDataEntry($box, forceUpdate) {
var $input = $box;
var $parent = $input.parents(".table_entry");
@ -1128,6 +1291,7 @@
}
$parent.find(".grade").show().empty().append(val);
}
function toggleColumn($obj, show) {
var assignment_id = objectData($obj).assignment_id;
var $list = $(".assignment_" + assignment_id);
@ -1137,6 +1301,7 @@
$list.hide().parent().addClass('hidden_column');
}
}
function populateSubmissionInformation($submission, submission) {
var $td = $submission,
assignment = object_data["assignment_" + submission.assignment_id].assignment,
@ -1304,6 +1469,7 @@
autoOpen: false
}).dialog('open').dialog('option', 'title', title);
}
function submissionInformation($submission) {
var $td = $submission;
var submission = objectData($td);
@ -1328,6 +1494,7 @@
});
}
}
var studentsToUpdate = [];
gradebook.finalGradesReady = true;
var studentsToInitialize = {};
@ -1387,6 +1554,7 @@
$assignment.data('assignment_object', assignment);
});
}
function moveAssignmentColumn(assignment_id, movement, relative_assignment_id) {
if(movement == "first") {
movement = "before";
@ -1409,6 +1577,7 @@
}
}
}
window.sortStudentRows = function(callback) {
var $students = $(".outer_student_name");
var students = [];
@ -1443,6 +1612,7 @@
});
datagrid.reorderRows(new_order);
};
window.reverseRows = function() {
var new_order = [0];
for(var idx = datagrid.rows.length - 1; idx > 0; idx--) {
@ -1450,6 +1620,7 @@
}
datagrid.reorderRows(new_order);
};
window.sortAssignmentColumns = function(callback) {
var $assignments = $(".outer_assignment_name");
var assignments = [];
@ -1486,6 +1657,7 @@
});
datagrid.reorderColumns(new_order);
}
function updateGroupTotal(updateGrades) {
var total = 0.0;
var weighted = $("#class_weighting_policy").attr('checked');
@ -1515,6 +1687,7 @@
gradebook.updateAllStudentGrades();
}
}
function setGroupData(groups, $group) {
if(!$group) { return; }
if($group && $group.length === 0) { return; }
@ -1563,6 +1736,7 @@
groups[data.assignment_group_id] = groupData;
return groupData;
}
function updateStudentGrades(student_id) {
var $submissions = $(".table_entry.student_" + student_id);
if($submissions.length === 0) { return; }
@ -1708,25 +1882,30 @@
.find(".score").hide().end()
.find(".pct").text(' %').show();
}
$(document).ready(function(){
$(document).bind('update_student_grades', function(event, student_id) {
updateStudentGrades(student_id);
});
});
$.fn.gradebookLoading = function(action) {
this.find(".refresh_grades_link").find(".static").showIf(action).end()
.find(".animated").showIf(!action);
};
function updateGrades(refresh) {
var url = window.location.protocol + "//" +
window.location.host +
window.location.pathname +
"?updated=" + lastGradebookUpdate;
$("#datagrid_topleft").gradebookLoading();
var url = "http://" + location.host + location.pathname + "?updated=" + lastGradebookUpdate;
var options = {};
$.ajaxJSON(url, 'GET', {}, function(data) {
$.ajaxJSON(url, 'GET', {}, function(submissions) {
if(refresh) {
setTimeout(function() { updateGrades(true); }, 120000);
}
$("#datagrid_topleft").gradebookLoading('remove');
var submissions = data;
var newGradebookUpdate = lastGradebookUpdate;
for(idx in submissions) {
var submission = submissions[idx].submission;
@ -1744,6 +1923,8 @@
setTimeout(function() { updateGrades(true); }, 240000);
}
$("#datagrid_topleft").gradebookLoading('remove');
}, options);
});
}
return gradebook;
})();

View File

@ -3131,4 +3131,12 @@
return decodeURIComponent(results[1].replace(/\+/g, " "));
};
// tells you how many keys are in an object,
// so: $.size({}) === 0 and $.size({foo: "bar"}) === 1
$.size = function(object) {
var keyCount = 0;
$.each(object,function(){ keyCount++; });
return keyCount;
}
})(jQuery);

View File

@ -107,7 +107,7 @@ var jsonData, visibleRubricAssessments;
// handle showing students only in a certain section.
// the sectionToShow will be remembered for a given user in a given browser across all assignments in this course
sectionToShow = Number($.store.userGet("eg_show_only_section"+jsonData.context_id));
sectionToShow = Number($.store.userGet("grading_show_only_section"+jsonData.context_id));
if (sectionToShow) {
var tempArray = $.grep(jsonData.studentsWithSubmissions, function(student, i){
return $.inArray(sectionToShow, student.section_ids) != -1;
@ -227,7 +227,7 @@ var jsonData, visibleRubricAssessments;
.hide()
.menu()
.delegate('a', 'click mousedown', function(){
$.store[$(this).data('section-id') == 'all' ? 'userRemove' : 'userSet']("eg_show_only_section"+jsonData.context_id, $(this).data('section-id'));
$.store[$(this).data('section-id') == 'all' ? 'userRemove' : 'userSet']("grading_show_only_section"+jsonData.context_id, $(this).data('section-id'));
window.location.reload();
});