Skip to content

Instantly share code, notes, and snippets.

@bennettscience
Last active May 29, 2019 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennettscience/44c066fdeb6c266ef0ce375892776a4d to your computer and use it in GitHub Desktop.
Save bennettscience/44c066fdeb6c266ef0ce375892776a4d to your computer and use it in GitHub Desktop.
Update the assignment status from the speedgrader in canvas
// ==UserScript==
// @name SpeedGrader Status
// @namespace http://tampermonkey.net/
// @version 0.4
// @description Set Canvas Assignment statuses from the SpeedGrader
// @author You
// @include /^https://.*\.instructure\.com/
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Set your Base URL here. Used for all API calls.
const base = "https://yoursite.instructure.com"
// A little hack to quickly extract the course ID from the URL
let parser = document.createElement('a');
parser.href = window.location.href;
var course = parser.pathname.split('/')[2]
// Watch the URL for query string changes
function track (fn, handler, before) {
return function interceptor () {
if (before) {
handler.apply(this, arguments)
return fn.apply(this, arguments)
} else {
var result = fn.apply(this, arguments)
handler.apply(this, arguments)
return result
}
}
}
// Store the URL
var oldQs = location.search
// Run when the select option is changed on the assignment.
function putStatus(e) {
// Prevent a page reload
e.preventDefault();
// Check the URL you're on to make sure it's in the speedgrader
if (/^\/courses\/[0-9]+\/gradebook\/speed_grader$/.test(window.location.pathname)) {
const params = new URLSearchParams(window.location.search);
// Store the query strings for the assignment, student, and selected status
let assignment = params.get("assignment_id");
let student = params.get("student_id")
let status = this.value;
// Bake some JSON
var data = {
"submission": {
"late_policy_status": status,
}
}
$.ajax({
url:`${base}/api/v1/courses/${course}/assignments/${assignment}/submissions/${student}`,
type: 'PUT',
contentType: 'application/json',
data: JSON.stringify(data),
success: function(resp) {
console.log(resp);
$(`#confirm`).animate({
opacity: 1},100).animate({
opacity: 0},2000);
},
error: function(err) {
console.log(err)
},
})
}
}
// Handle all navigation changes
function handler() {
// Check for the custom select box
var customSelect = document.querySelector("#customSelect");
// If it's not there, put it there
if(!customSelect) {
const container = document.querySelector("#grade_container");
const div = document.createElement("div");
// Style the div so the checkbox stays inside
div.style = "position: relative";
const span = document.createElement("span");
// Add the span for confirmation
span.innerHTML = "<span id='confirm' style='position: absolute;left: 185px;top: 2.75vh;line-height: 1;transform: translateY(-75%);opacity:0;'>&#10003;</span>";
div.appendChild(span)
// Option value strings for the API call
const choices = ["none", "late", "missing", "excused"]
// Make a select, set the ID, add to the container.
const select = document.createElement("select");
select.id = "customSelect";
div.appendChild(select);
// Add the <option> els to the select.
for (var i in choices) {
var option = document.createElement("option");
option.value = choices[i];
// Set the choice string for display
option.text = choices[i].charAt(0).toUpperCase() + choices[i].slice(1);
select.appendChild(option);
}
// Add the whole thing to the container
container.append(div);
// Listen for those events
select.addEventListener("change", putStatus);
}
// If it's there, check the URL and make sure it's on the speedgrader.
if (/^\/courses\/[0-9]+\/gradebook\/speed_grader$/.test(window.location.pathname)) {
// Get the select item
customSelect = document.querySelector("#customSelect");
// Get the assignment and student IDs for posting
const params = new URLSearchParams(window.location.search);
let assignment = params.get("assignment_id");
let student = params.get("student_id")
$.ajax({
url: `${base}/api/v1/courses/${course}/assignments/${assignment}/submissions/${student}`,
method: 'GET',
success: function(resp) {
// "None" is actually a null value from Canvas. Make that show "None" instead.
(resp.late_policy_status == null) ? customSelect.value = "none" : customSelect.value = resp.late_policy_status;
},
error: function(err) {
console.log(`Error: ${err}`)
},
});
// Update the current location
oldQs = location.search
} else {
return
}
}
// Add all the listeners to make sure we don't miss a page change.
history.pushState = track(history.pushState, handler)
history.replaceState = track(history.replaceState, handler)
window.addEventListener('onpopstate', handler);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment