Show student names for Differentiated Assignments

Navigator
6 16 3,216

When assignments, quizzes, or discussions have multiple due dates, Canvas gives a summary table of the dates and the number of students, but not the names of the students. This user script replaces the number of students with the names of the students.

Quick Install

For those power users who are impatient, here are the quick install steps.

  1. Install a browser add-on: Greasemonkey for Firefox or Tampermonkey for Chrome/Safari
  2. Install the Show Override Names user script.

The script has been tested with Firefox, Chrome, and Safari using the English language. If you run into problems, be sure to go back and read the instructions before asking for help.

Introduction

Canvas has Differentiated Assignments that allow you to assign different due or availability dates to assignments, graded discussions, and quizzes. People also refer to differentiated assignments as "multiple due dates" or "assignment overrides". I will mostly refer to them as overrides since that's what they are called in the Canvas REST API.

These differentiated assignments show up in the list of assignments as having "Multiple Dates" and you can mouse over them to see a very brief summary of the group and due date.

Differentiated Assignments

Clicking on the assignment name will take you to that assignment page where you will be given a summary table that provides additional details.

Assignment Due Dates

This is a summary table that provides all three dates (due, available from, and available until) as well as the number of students receiving each override. While the table shows the number of students, as shown in the red box, it does not tell you who those students are. If you want to see the names of the students, then you need to edit the assignment, scroll down to the "Assign to" section and then look for the appropriate information.

Assign To

Although the names are blurred in the image for privacy reasons, the student names are provided in "First Last" form, but not in alphabetical order by either first or last name.

Displaying the student's names instead of the counts was the essence of a feature request   by ezaurova@stanford.edu.

After you install this user script, the summary table on the assignment page looks like this.

Differentiated Student Info

The astute observer will notice that the order is different than it was before. That's because Canvas sorts on the due date and not on the available from or available until dates and the two assignments are both due at 5:05 pm.

The line wrapping isn't as bad with a wider monitor, but the browser decides how wide to make each column based on the amount of information in them. I put in seven names to force wrapping, but it looks pretty decent when there are only a few names. Here is a before/after example from a graded discussion that has three overrides.

Differentiated Discussion 1

Differentiated Discussion 2

Installing the User Script

A user script is a JavaScript that is ran by the browser on the user's machine. Rather than a Canvas-supplied script, it's one that the user installs and runs on their own. The installation is per user and per machine, so you will need to install it on each machine that you want to use the script with.


Install Browser Add-On

The first step is to install and enable the browser extension that allows you to run user scripts.

  • Firefox users should install an add-on called Greasemonkey.
  • Chrome and Safari users should install an add-on called Tampermonkey.

Here is a video showing how to install the Greasemonkey script with Firefox. Note that you do have to restart Firefox for the add-on to be recognized.


Install the Show Override Names User Script

Once you have installed and enabled the browser add-on, it's time to install the user script. Luckily, the browser add-on looks for filenames that end in .user.js and offer to install them for you. That makes installation extremely easy, just click the link below.

     Install the Show Override Names user script

Custom URLs

You shouldn't have to do anything if you're running if your Canvas instance ends in instructure.com. If you have a custom URL, like canvas.university.edu, then you will need to modify the script to get it to work.

The specific steps to do this vary depending on your browser add-on. In Greasemonkey, click on the Greasemonkey pull-down, choose Manage User Scripts, find the Access Report Data, right click and choose Edit. In Tampermonkey, click on the Tampermonkey Icon, choose Dashboard, and then click on Access Report Data.

In either case, you need to change // @include statement on line 5 to match your instance. In the case of canvas.university.edu, you should change it to:

// @include     /^https://canvas\..*\.university\.edu/courses/[0-9]+/(assignments|quizzes|discussion_topics)/[0-9]+(\?...

This is a regular expression that will match the main page for an assignment, quiz, or discussion topic. The (\?|$) at the end is in case you arrive there from either through modules or from the list of assignments, quizzes, or discussions.

Technical Stuff

This section is definitely not required reading. But for those who want to know what's going on behind the scenes, read on.

I had recently written a couple of other user scripts that added functionality to Canvas and thought I could take one of those and make it add the names. I ended up using portions of both and coming up with some new stuff as well. I originally estimated a couple of hours, but had the units wrong and it took a couple of days instead.

The major stumbling block is that Canvas does not provide any identifying information in the summary table other than the information displayed. That means that there is no quick identifier like "This is assignment override # 123654" to uniquely identify the row. I had to scan the information in the table and try to match it with the information from the override tables. Compounding the issue is that Canvas displays the dates and times in some funky human readable form that tries to shorten up the information. Funky human readable form probably means that it's internationalized to use whatever language you're using, rather than English. I could have written it to just work in English, but I thought I would try to write something that others could use. Anyway, the year is left off when it's the current year (Feb 29 instead of Feb 29, 2016) and the minutes are left off when the time is on the hour (12pm instead of 12:00 pm). Then there is another flag thrown in there for those 11:59:59 pm times so that it doesn't display it, but just displays the date instead.

The information returned from the API calls is given in ISO 8601 format like 2016-02-28T22:46:12Z. The task was to take the timestamp and match it up with the displayed date. This is my first attempt to use the I18n internationalization (in anything) so I may not have gotten it right. Instead of relying on parsing "Feb 29" into a timestamp, I focused on converting the timestamp into that funky human readable form. The script looks at the override information and the information in the table and does a comparison.

  1. Look at the number of students. If this is unique for the table, then we have found our row.
  2. Look for an exact match of the dates and/or times by comparing four different forms of date (with and without year) and time (with and without minutes). If all three date/times agree, then we have a match.
  3. If the information doesn't match exactly, then look for information in the same spots. Does the combination of due date, available from date, and available until date in the table match that from the assignment override and there is only one such combination? If so, we've found the match.
  4. Is there only one item left -- if so, it's the remaining entry.

At each step in the process, the entries for any matches that are found are eliminated from the list of available overrides before checking the next step. That makes it easier to identify the ones that remain. It is possible that step 1 might skip something because there were two matches, but after completing step 3 there was only one left. If I reach step 4 and there are still some items left over, I run through the entire process again a few times to make sure it catches as much as it can.

If, after all of that, it still can't find a match, then it just displays the number of students like it did before.

Once it finds a match, it sorts the names alphabetically by the sortable name. That means that the names are sorted by the last name, but displayed in "Firstname Lastname" format. If, for some reason, the sortable name isn't available, it falls back to the regular name.

Discussions and Quizzes contain the assignment override information with the assignment, not with the discussion or quiz. That means I needed to fetch the assignment ID before I could fetch the assignment that contains the overrides. That information is technically available in the Speedgrader URL and I could have saved an API call, but I opted to go ahead and make the call anyway. Once I get to the assignment, I'm actually fetching the list of assignment overrides, which is a beta endpoint in the API, rather than the assignment that contains the overrides because it's smaller and thus faster.

Each override that involves individual students a list of Canvas user IDs for the students, but no name information. I then had to look up the names of the students using separate API calls. There are multiple ways to do that, but I ended up getting a list of course users and specify the user_ids[] of those who have overrides. This was a trade-off between downloading the entire list (very, very slow when there are lots of students) or downloading each student individually (slower because it has more network traffic) I chunk it into blocks of up to 50 students just to be cautious.

Remember that differentiated assignments that refer to sections or to "everyone else" don't get changed, so we only need to look up the cases where you have specified a student by name. If you are specifying more than a couple hundred students by name, you may not want to install this script.

Updating the Script

Every now and then I will make revisions and improvements to the script. Luckily, both Greasemonkey and Tampermonkey make it pretty easy to get the latest version. By default, both will automatically check for updates for you (Greasemonkey once a week and Tampermonkey daily). However, if you would like to force an update sooner, you can do the following:

  • In Greasemonkey, you pull down the options bar from the icon and choose Manage user scripts. Then right click on the Access Report Data script and choose Find Updates.
  • In Tampermonkey, you click on the Tampermonkey icon and choose Check for userscript updates.

Canvancements

This script is a Canvancement -- a Canvas Enhancement. The links in the document point to an installable version of the code, but there is a Show Override Names project page. Other projects can be found on the Canvancement website as well.

16 Comments
Community Member

Hey James,

Is this functionality still working? I installed the script and it gets enabled when I'm on a page with multiple due date students but the names aren't appearing. Let me know if I'm doing something wrong or if I'll need to look at tweaking the script!

Thanks,

Jon

Navigator

degroot@ntc.edu 

I had to check because I don't use this script regularly, but it appears to be working for me.

If you're sure the the script is being run, then the most likely culprit would be that you're using Greasemonkey.

Firefox changed behavior in late 2017 and Greasemonkey stopped working for any script that needed access to jQuery to load additional information. This script is one of those. A permanent fix would be making sure that you load jQuery with your user script rather than using the one supplied by Canvas. Tampermonkey continues to work (they chose a different way to work around the Firefox changes). 

I'm now recommending that people use Tampermonkey since it works with all of the major modern browsers and it continues to work with scripts that need to fetch information. I haven't gone through and updated all of the blog posts or documents that I wrote to reflect this, but I did make a general announcement on the page that leads here: Canvancements - Canvas Enhancements   Of course, that doesn't help if you found it through a search.

A second possibility is that you only think the script is running. Having it enabled isn't the same thing as it running. In Tampermonkey, a red badge with a number will show up on pages where the script is being run. In Greasemonkey, there's a section at the top that says "User scripts for this tab." However, as mentioned before, it is known not to work with Greasemonkey at the current time.

My scripts run by default on *.instructure.com, but it looks like Northcentral Technical College uses as custom URL for their Canvas of canvas.ntc.edu. I'm not positive on that, it's just what a Google search showed. If that's the case, then the script won't run. You'll need to modify line 5 of the script to point to your Canvas instance. In the example below, line 1 is what it says in the script that ships and line 3 is what you need to change it to. The line numbers apply to the example, it's line 5 in the code.

// @include     /^https://.*\.instructure\.com/courses/[0-9]+/(assignments|quizzes|discussion_topics)/[0-9]+(\?|$)/

// @include     /^https://canvas\.ntc\.com/courses/[0-9]+/(assignments|quizzes|discussion_topics)/[0-9]+(\?|$)/

If the custom URL or using Greasemonkey doesn't explain it, then I'll need more information to work with. I'd start on a Canvas page, opening the developer tools (F12) on the browser and switching to the console tab. Then navigate to the assignment page (or reload it). Look at the error messages and see if anything jumps out at you that looks like it might be coming from a user script.  For example, the error when you try to run that page under Greasemonkey looks like this:

290966_pastedImage_3.png

Community Member

Hey James,

I appreciate the very thorough response. Sorry for not providing more detailed information on my initial post. I am using Tampermonkey in Chrome and it appears to be enabled when I navigate to an assignment page with multiple due dates.

291015_Screenshot_1.png

Canvas.ntc.edu is simply a redirect so when we are actually on the page the URL looks like this https://northcentral.instructure.com/courses/16176/assignments/125051?module_item_id=364044 

I pressed F12 and switched to the console tab and this is what I got.

Uncaught ReferenceError: I18n is not defined
at isMatch (userscript.html?id=e78b0cd9-673c-4493-949c-c95c32a1b920:294)
at findMatch (userscript.html?id=e78b0cd9-673c-4493-949c-c95c32a1b920:237)
at process (userscript.html?id=e78b0cd9-673c-4493-949c-c95c32a1b920:183)
at Object.eval [as success] (userscript.html?id=e78b0cd9-673c-4493-949c-c95c32a1b920:152)
at p (jquery.js:1075)
at Object.fireWith [as resolveWith] (jquery.js:1193)
at y (jquery.js:7538)
at XMLHttpRequest.i (jquery.js:8324)

I went into Beta and removed all of our custom JS and tried again with no success. It must be something with our instance though as I had another user try it with the same results. This is not an urgent matter by any means and I really appreciate the time you've put into these scripts. I'll continue to tinker with it and see if I can get it working.

- Jon 

Community Member

Love this Canvancement James.  Something weird is happening for me though.  The names of the students are only showing up if there is more than one student, otherwise it still shows "1 student"  Any idea what might be happening?  Has anyone else reported this?  Thanks in advance!

Navigator

kevin.schaub@colorado.edu

Every now and then Canvas changes something on the back-end and things break. Since I don't use this script (or do much with differentiated assignments), I rely on other people to let me know what it breaks.

I'll try to get a look at it and see if I can find something out. Was this happening in a particular place (quizzes, assignments, or discussions) or all three?

Community Member

This happened for me in Quizzes.  I don't have Assignments or Discussions assigned to multiple students, otherwise I'd check those out for you.  Thanks James!

Navigator

Where are you exactly trying to view this? I went into Quizzes, picked one, changed a date for one student, and am getting the name. This is on the quiz page itself. 

311864_pastedImage_1.png

Now, on the syllabus page, it doesn't show that.

311865_pastedImage_2.png

But it never showed the names on the syllabus page.

Nor did it ever work on the main lists for assignments, discussions, or quizzes. This is the expected behavior.

311866_pastedImage_3.png

If you look at the top of the script, there is an include line. It only works on specific assignments, discussions, or quizzes, as identified by by the path. It must be an assignment, discussion, or quiz, followed by a number.

Community Member

I'm seeing it after I click on the quiz.  It works for multiple students but not individual students.  Here's a screen shot of what it looks like:

quiz

Community Member

Weird thing is that it's working for 1 student in a different quiz where I don't have multiple students assigned to a date:

quiz

Navigator

If I'm understanding correctly, I need to assign different due dates to more than one student. I have done this and can verify that it's only showing the ones with multiple students.

It's much easier to track down the problem once I can duplicate it, so thanks for clarifying and for the screen shots so I could see what is happening.

Navigator

Okay, I know what the problem is, now I just have to fix it.

At some point (at least by April 2017 because I asked a Canvas engineer about it), they stopped exposing some of their variables to the user. The I18n translation was part of that. That's a shame, because it allowed me to see what things looked like in the language the user had selected and it made it easier to support different locales.

Because the I18n variable isn't exposed anymore, the script is throwing an error and stopping execution. That means that's it's getting one converted and not all of them. Once I figure out how to get around the time/date issue, I should be able to get it to process all of them.

Of course, that's a 321 line script, so I may take the time to tweak it. I know a little more about JavaScript now than I did then and some of my early scripts were very hackish. Now they're just moderately hackish.

Community Member

Thanks James.  I'm glad you were able to replicate it.  With so many things in Canvas, I often think it's just me experiencing it 🙂

Navigator

I started refactoring the code last night, trying to remove the jQuery dependency. I've already removed two API calls that it turns out aren't necessary because the information is contained in the ENV variable (web browser only, but this never worked on mobile apps anyway). If I could find a deterministic way that the overrides are displayed, then I could possibly bypass the date / time check and remove the need to try and convert the human friendly times that Canvas gives but relied on the I18n internationalization to support other locales besides US English. The good news is that the code is getting shorter, not longer. But I had to finally quit and go to bed about 4:30 this morning.

Community Member

Ouch!  That's dedication.  I'm happy to test out all your hard work whenever you're ready.  Hope you got some sleep!

Community Member

Hi James.  Any chance you have a new release ready for testing?  Thanks!

Navigator

No, I worked heavily on it for a couple of weeks and then got distracted and haven't been able to get back to it. When I pull it up to work on it, it's hard to get back into the swing.

I was able to rewrite it to use better fetching of the data and now have it to the part that was the original problem -- determining the matches without looking at the date. Canvas sorts them in order by due date ... provided there is a due date. Beyond that, I haven't been able to find any deterministic sort order.

About the Author
I'm James Jones. The new Community software Khoros doesn't seem to like people using real names, but I think that names are important part of building community. I'm here trying to make Canvas a better experience for people. I hate repetitive tasks and will spend 13 hours writing a computer program to automate something that takes 5 minutes to do. The last two statements often benefit others in the form of Canvancements, which are my Canvas Enhancments that I contribute to the Canvas Community.