Sorting the Find a Rubric dialog

James
Community Champion
27
9913

This document will show how to move the current course to the top of the "Find a Rubric" dialog and optionally sort and filter the information to make it easier to find rubrics.

Sorting Find a Rubric Window Before and After Examples

The before list on the left has 30 items in a mostly random order. The after list on the right has all courses that ended more than 180 days ago removed as well as some other features enabled to help clean up the list. The list on the right will also show the full name of the course when you hover over a course name.

Quick Installation

Here are the quick install steps. It has been tested with Firefox, Chrome, and Safari.

  1. Install a browser add-on: Greasemonkey for Firefox or Tampermonkey for Chrome/Safari
  2. Install the Find Rubric Sorter user script.

The Problem

When adding a rubric to an assignment, discussion, or quiz, the current course is often buried in a list of courses rather than being listed first. And if your institution reuses the short name for courses, there is no easy way to tell which term the course goes with.

This image is the default list of courses that Canvas gives me when I click on Find a Rubric from an assignment in my MATH 230 course.

Find Existing Rubric

There is a MATH 230 that is shown at the bottom, but that may or may not be the current version of MATH 230. If I scroll down, I see that there is another one. They both say MATH 230 and both have 1 rubric in them. Which one is the current one?

Find Rubric Example

It turns out that the correct course wasn't either one of those. If you scroll down a little further, you find the desired MATH 230.

Find Rubric Correct Course

The MATH 230 course I was in, which was also the active one this semester, when I clicked on Find a Rubric was 17th in my list of 30 courses. Other people have it worse than I do.

Since the course short name (course code) is used by Canvas in the rubric list and our institution doesn't use the term name in the short name, there's no way to tell which course is the current one. Even if I go into each one, I might have used the rubrics with the same names in the course the last time I taught it, so there still may be no way to tell even by the list of rubrics that shows up in the second panel.

Okay, saying that there is no way is a bit too strong. You can bring up the browser's Developer Tools and inspect the element. Once you have the element pulled up, you can expand the anchor tag inside the list element and then find the span with a class of context_code. It has a code like course_178711. The course is the context and the other context is account. The number that follows is the Canvas course ID, 178711. You compare that with the URL in the location bar, which in this case shows 2054972. The mismatch lets you know that you don't have the right course.

View Rubric Course ID

You then repeat this process with every possible candidate from the leftmost column until you find a match and then you know you have the current course.

Technically, a better expression of the difficult is that there is no easy, reasonable, user-friendly, non-technical way to determine which course is the right one.

The Solution

 @tyler_mckell  asked a question that turned into a feature request: https://community.canvaslms.com/ideas/8535-finding-rubrics . His request was to move the current course to the top of the rubric list.  @kona ‌ sent me a message asking if we could do something about this and after a quick look, I wrote back that it seemed doable, but that things with Canvas are never easy, so not to hold me to that.

Find Rubric Solution

The result is a user script that will attach itself to assignment, discussion, and quiz pages and wait for the user to click the Add Rubric button, followed by the Find a Rubric search tool. Here are some features of that script. These features are all optional and configurable except for the first one.

  • It moves the current course, if present, to the top of the context list (the leftmost panel). This is the only feature that is not optional or configurable.
  • Look up the course information for a user and if the course is in the rubric list, add the term to the information line beneath the course code and add the full name of the course to the title attribute so that when you hover over the name you can see the full course name.
  • Perform a multiple key sort on the information. In the picture above, the current course comes first, and then the primary key is the context (course or account) so that all the account level rubrics are at the bottom. The secondary key is the name of the course, so you'll see that all MATH 113 courses are grouped together. The tertiary key is the term, so that the courses are listed with the newest at the top.
  • There are some predefined sorts included, but you can also specify your own custom sort order including the keys and whether to sort in ascending or descending order.
  • Hide any courses that have been over for more than a set number of days. The image above hides all courses older than 360 days.
  • Hide any courses that are not in your course list. This may help get rid of courses you don't have access to anymore. I noticed that we had some that I couldn't find anywhere in our system (not even on the provisioning report with include deleted objects checked).
  • Hide courses that belong to terms without an end date specified. For us, this was the Default Term that contained sandboxes, peer course reviews, and pretty much anything that wasn't an actual course that I had taught.
  • Hide any account level rubrics and show only course level rubrics.
  • When adding the term information to a course, you can put it in front of the rubric count, behind the rubric count, or completely replace the rubric count with the term name. To me, knowing the term is much more valuable than knowing there are 3 rubrics. The separator defaults to a vertical line, but you can specify a different separator if you want.

Installation

The installation steps here are similar to other user scripts.

  1. Install a browser add-on: Greasemonkey for Firefox or Tampermonkey for Chrome/Safari
  2. Install the Find Rubric Sorter user script.

Customization

If you want to perform customization, you will need to edit the source code.

  • For Greasemonkey, click on the Greasemonkey icon and choose Manage user scripts. Then find the script from the list, click the right mouse button, and choose Edit. After making changes, click Save, and then close the window.
  • For Tampermonkey, click the Tampermonkey icon and choose Dashboard. Find the script in the list and click the left mouse button on it. When you are done, click the Save button and then close the tab.

Custom Domain

If your Canvas instance is hosted at *.instructure.com, then it should run with the installation instructions above. However, if you have a custom domain for your Canvas instance like canvas.institution.edu, then you will need to modify the // @include line on line 5 of the source code to match your institution.

This is a regular expression, with the exception that you don't need to escape the forward slashes. 

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

The part you will be interested in modifying is the hostname, which is currently the .*\.instructure\.com portion. Since this is a regular expression, the dots in the domain name need escaped with a backslash.

As an example, canvas(\.beta|\.test)?\.institution\.edu would matches canvas.institution.edu, canvas.beta.institution.edu, and canvas.test.institution.edu.

The use of regular expressions is slightly more complicated, but I only wanted the script to run on the pages that had the option of finding a rubric and using the normal wildcard matching would include any page under assignments, discussion_topics, or quizzes.


The first block of code is to check the location and make sure it's not trying to run on the wrong page, so it shouldn't hurt too much to use the regular wildcard system, except that it makes a needless check, which might slow the browser down just a little.

Feature Configuration

There is a config variable towards the top of the source code with some explanation of what the variables do.

  • sortOrder can be given as a number, in which case it chooses a predefined sort order, as an array of key fields with an optional + or - at the end to override the default sort order for that key. This can be complicated if you let it, so see the next section for the predefined sorts and more explanation about what can be used.
  • courseLookup tells whether or not to look up additional information about the course. Without this, you won't be able to use anything date related and the titles of the courses won't be available as a mouseover tooltip either.
  • addTerm tells the script to add the name of the term to information displayed. The following other items are related to this:
    • removeCount says to remove the rubric count completely and replace it with the term name.
    • prependTerm determines whether the term name should go in front or behind the rubric count (unless you've told it to removeCount)
    • separator specifies the characters that should go between the term name and the rubric count.
  • hideDays says to hide courses from the list that ended more than this many days ago. For example, to hide courses that ended more than a year ago, set hideDays to 365. Set it to a negative number to ignore the end date and show all courses. You must also enable the courseLookup to get the course dates. This is based off the course end date and not the term end date.
  • hideUnknown says to hide courses that weren't found in your course list.
  • hideAccounts says to hide all account level rubrics
  • hideNeverending says to hide courses with terms that do not have an end-date set. I could have told it to hide courses in the "Default Term", determining the "Default Term" is language specific and this opens up more courses. If your school doesn't put end dates on any of the terms, then I don't recommend using this.

Here is the config file as it comes and with all of the comment stripped out.

var config = {
'sortOrder' : 1,
'courseLookup' : true,
'addTerm' : true,
'removeCount' : false,
'prependTerm' : true,
'hideDays' : -1,
'hideUnknown' : false,
'hideAccounts' : false,
'hideNeverending' : false,
'separator' : ' | '
};‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Sorting the list

There are also a couple of items that follow immediately after this in the code.

  var sortableKeys = {
'name' : 's+',
'title' : 's+',
'context' : 's-',
'courseEnd' : 'd-',
'courseStart' : 'd-',
'termName' : 's-',
'termStart' : 'd-',
'termEnd' : 'd-',
'term' : ':termEnd'
};
var predefinedSorts = {
1 : [ 'context', 'name', 'term' ],
2 : [ 'context', 'term', 'name' ],
3 : [ 'context+', 'name', 'term' ],
};‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The sortableKeys object listing the keys that you can specify in your custom sort, including whether they are a (s)tring (and the localeCompare should be used when sorting) or a (d)ate. The second character is a + or - and indicates the default sort order of ascending for + or descending for -. The "term" is an alias for "termEnd". Capitalization is important when specifying a custom sort order. Any of these can be followed by a + or - in the custom sort order specification to change the default order. If you don't specify a + or - at the end, it will use the default sort for that key.

  • name is the short course name or course code
  • title is the full course name, which is only available when you have the courseLookup feature enabled.
  • context is either 'course' or 'account'. The default is to sort in descending order, so that courses come first and accounts come at the bottom. Include 'context+' in your sort order if you want the account level rubrics listed first.
  • courseEnd and courseStart are the end and start date and times for the course.
  • termName is the name of the term
  • termEnd is the end date for the term. This is what is sorted on if you specify term in the sort order. This is currently role-based, so it's when you last had access to the course, not when the term actually ended.
  • termStart is the start date for the term. If your institution allows you to access the course starting whenever, then this will come through as null and will be useless for sorting purposes.

There are also some predefined sorts. You may specify one of these by putting a number in the config.sortOrder property. 

  1. Place the courses rubrics at the top and the account rubrics at the bottom. Then sort by name in ascending order and when the names are the same, then sort by term in descending order.
  2. Place the courses rubrics at the top and the account rubrics at the bottom. Then sort by the term end date in descending name order so that the newest courses are at the top and the oldest are the bottom. Within each term, sort the names in ascending order.
  3. Place the account rubrics at the top and the course rubrics at the bottom. Then sort by name in ascending order and finally, if duplicate names exist, by the term.

Quizzes and Discussions

The Find a Rubric search tool is not the same for Quizzes and Discussions as it is for assignments.

For assignments, there is a table with scrollbars for when there are more items that can be displayed in the dialog box. Dragging the dialog box taller doesn't necessarily give you much more space as there is a maximum height that you can have for the table.

For Quizzes and Discussions, that table still exists, but the scrollbars do not. This means that if you have a large number of contexts (courses and accounts) and select a context with few items, that you may not be able to see them without having to use the single scrollbar on the far right. 

Here is an image showing the portion my Find a Rubric tool for a quiz from my sandbox. Even though there are 10 rubrics, there are 30 contexts, and I had to scroll down some to get any of the rurbrics in the middle column to show. If you have a really long rubric on the right side, it will also make you have to scroll to see the list of contexts or the list of rubrics for that context.

Find Existing Rubric Sorted

The good news is that you can drag the dialog box larger and actually make full use of all of the real estate that you have on your screen. The other good news is that the script works for quizzes and discussions so you can filter some of your values out, although having lots of rubrics within a context or having large rubrics will still make it cumbersome.

Technical Challenges

Never say things are easy when trying to develop an add-on for Canvas. There are always technical hurdles that must be overcome. I develop with Firefox and then once it's working there, I move over to Chrome and Safari and validate that it still works. Most of the time, it works across browsers without modification, but this time it didn't. Although sometimes it would and other times it wouldn't. That kind of sporadic behavior suggested a timing issue and so I had to add another mutation observer to the code.

Rather than continuing to write this document, I may write a blog about the technical challenges encountered here. If I do, I'll be sure to link it from here.

27 Comments
BethCrook
Community Contributor

:smileyshocked:  <--  Me.  Mouth dropped.  

kroeninm
Community Champion

You made me so happy today, looks lovely!!!!  I can find my rubrics again.  When attaching the same rubric to 10 discussions in a row, I will no longer complain, just wishing this were available last month. :smileygrin:

- Melanie

James
Community Champion

I contacted Canvas support about the missing dates in the term information and it turns out that I will have to rework the logic. The term start and end dates are based on the role the user has in the course, not the actual dates for the term.

This is determined based on the Term settings under the admin menu. Here is what we have for the Spring 2017 term.

232459_pastedImage_1.png

The term end date was showing up for me (as a teacher) because our school has a term end date (Jul 31) specified in the term settings. This is also why the start date was showing up as null, because none was specified.

However, if a school had "to term end", then the end date would show up as null in the list of terms and my code would interpret it as a Neverending term. Hiding those is disabled by default, but it would affect sort order if you were listing by terms and your school had "to term end" as the end date.

I think I'll need to fetch the list of terms and possibly any overrides to get the real term dates. I was hoping to avoid that since it is an extra API call and those add times, especially for institutions with lots of terms as must fetch the entire list of terms, but not individual terms. The enrollment term ID is included with the List your courses information, so I can take away my extra include[]=term from that API call and make it a separate call.

I've got some actual coursework to do, so it may take a few days to get it fixed.

Shar
Community Champion

I love this script.. I used to have it in Greasemonkey and now I've updated my scripts to Tampermonkey. All works great and as expected. But Now I'm spoiled and I keep getting frustrated when I'm adding quizzes from quiz banks and it's showing all the banks I've ever made in the universe when all I want are the ones for this course.

How do I modify this script to find quiz banks for my course? Is that possible? *hopeful smile*

Cheers - Shar

James
Community Champion

ishar-uw,

This might be better addressed under a new question so there's a place to have the discussion without hijacking this thread. Be sure to ping me on it and link to it from here in case someone finds this thread and says "I'd like that, too".

But to see if I'm on the right track, are you talking about turning this (where AZ SB1062 and all of the other question banks shown are not part of the current course)

263995_pastedImage_1.png

into this (where equationtest and everything else shown is part of the current course -- notice they all say James_Sandbox now)

264008_pastedImage_2.png

If so, then the answer is about 1.5 hours and around 55 lines of code NOT including the Mutation Observer to wait for it to appear on the page. It can probably be cleaned up, but this is the first time I've tried the new Web API commands with Promises and some of the ES6 shortcuts for JavaScript so I'm still trying to figure out exactly how it works.  But it really cleans up the code and it's all done without jQuery. That 55 lines is starting from scratch, btw, not building off what was on the Find Rubric approach.

Also, I've got some other questions like what all should be included? The call that Canvas makes includes bookmarked and inherited question banks, but I just went through and looked for anything that had the course context. Are there other places this appears, etc? In other words, there's some fleshing out to do and since I don't use this much, I could use the help of someone who does to tie down the details. You're great at that and we work well together, I just don't think it belongs in this thread.

kona
Community Champion

Strangely enough I just ran into this issue today as well and was thinking the same thing! Unfortunately I don’t have the programming skills to be much help in getting this going. 

Shar
Community Champion

But you're the in-house test case and a ringing endorsement!

Smiley Happy Shar

kona
Community Champion

Per our conversation I posted this as a question here - https://community.canvaslms.com/message/92445-sorting-the-find-a-question-bank-dialogue 

Boekenoogen
Community Contributor

Have there been any conversations with Instructure about adding this to their code? I really enjoy this tool and many of the others that #JamesJones has created.

James
Community Champion

I showed them to some product managers last year at Project Khaki and the code is released under the ISC license. They wouldn't implement it as an add-on,  it would be incorporated through their code so most likely written in Ruby rather than JavaScript. Basically they can take the idea and implement it their own way if they like.

Canvas is open source and someone who had signed on to submit code changes to them could also add it. I'm not one of those people since I don't program Ruby and we don't run our own instance for me to test things with before submitting it.

Way back when I first started these Canvancements, I thought it would be awesome if Canvas could incorporate all of this directly, but came to understand that may not be the best choice. When they do something, they normally do it better than I do, but people may get tired of waiting for them to do something. In other words, there's still a place for them.

abigail_smith_2
Community Contributor

 @James ‌ I installed GreaseMonkey and the Find Rubric Sorter script. Our institution's domain is "_".instructure.com.  GM says the rubric sorter is enabled.

It should just automatically ... work... now, right? It doesn't seem to be working. It's not sorting rubrics at all.  I tried adding a rubric to both an assignment and a discussion board. What am I missing?

James
Community Champion

 @abigail_smith_2 , 

The first thing I see is that you're using Greasemonkey. It stopped working in the Fall of 2017 when Firefox upgraded to version 57. It made breaking changes. Greasemonkey chose to implement the new version in a way that is not compatible with the old way. I have not gone through and updated all of the documentation -- I'm still kind of holding out that Greasemonkey will fix the incompatibilities or that I will rewrite the scripts so it works with both. Realistically, neither of those is going to happen any time soon.

I'm now recommending that people use Tampermonkey instead of Greasemonkey. It works with all of the major browsers, including Firefox. Uninstall Greasemonkey, you don't want the script attempting to run twice.

abigail_smith_2
Community Contributor

Aha, that fixed it. Thank you! Awesome feature!!!

mpromislo
Community Explorer

Hi James, is your tool to sort rubrics still working? I added the Tampermonkey extension and ran the script you posted, but Canvas still isn't sorting my rubrics when I click on "Find a Rubric." I can't believe Instructure still hasn't addressed this after four years!

naboznyk
Community Participant

Hello, @James :

I will preface this by saying that I know practically nothing about JavaScript, but I have tried to figure this out on my own.

I cannot get the 'Sort a Rubric' script to work.

I installed Tampermonkey and I installed version 3 of the UserScript you created.

I updated the "(at)include" in the script for my college's Canvas page.

When I edit a rubric, I do not have an option to move rows around.

I looked at the script in Tampermonkey, and I have a warning for line 39 that says:

         eslint: no -undef - '$' is not defined.

I researched online and tried fixing it by adding this line to the top of the script:

/* eslint-env jquery */

which makes the warning go away, but the when I try to edit a rubric, I still cannot move the rows around.

Any ideas?

Thanks!

Keith

James
Community Champion

@mpromislo 

Are you talking about sorting a rubric (reordering rows) or sorting the list of rubrics when you find a rubric? Both are still working for me on April 1 (no joke) with Chrome on a Windows machine.

The sort a rubric is not what this blog post is about. It's at Sorting Rubrics Made Easy. To use it, you must go to the rubrics page and then click on Edit to actually edit a rubric. There are no handles, you just have to drag and drop the rows. It will not work from the rubrics that are attached to assignments, it must be done from the rubrics page.

The Sorting the Find a Rubric Dialog is what this blog post is about. It pulls the information about all of the rubrics and then sorts them with the current context at the top. The script there is at version 1 and it runs from the "Add Rubric" menu for a discussion, quiz, or assignment when you click on Find a Rubric.

If you're in the correct location and the script isn't running, then check the Tampermonkey icon and make sure that it is recognizing the page that you're on.

In this image, Tampermonkey is enabled and running two scripts on the page.

James_0-1617334329492.png

If I click on the Tampermonkey icon, I can get the details about which scripts are running and can enable or disable them as well as edit them (under the + symbol).

James_2-1617334469385.png

If your Canvas instance isn't hosted be Instructure and using instructure.com as a hostname (for example, canvas.institution.edu instead of institution.instructure.com), then you will need to modify the // @include line at the top of the script metadata.

 

James
Community Champion

@naboznyk 

Keith, it sounds like you're describing the sort a rubric script, but this page is about sorting the list of rubrics that appear when you click on Find a Rubric. I just tested both of those scripts and they are still both working for me on 2021-04-01.

The sort a rubric blog post is at Sorting Rubrics Made Easy and if you're trying to use that script with the directions on this page, it won't work.

To use the sort a rubric script, which is at version 3, you must go to the rubrics page and then click on Edit to actually edit a rubric. It will not work while you are editing a rubric within an assignment, discussion, or quiz, it must be from the rubrics page.

You are correct that the eslint code won't fix the problem. That's just a Tampermonkey warning saying that it doesn't know what $ is while you're editing it. At runtime, jQuery is supplied by Canvas. If you were watching the developer tools console and got a message about an unknown $ then it would be a browser error and the script would not work past that point.

naboznyk
Community Participant

@James 

I figured out the problem.

I was on the correct Rubrics page, I had the correct script and I had correctly edited the script.

There were two problems (both on my side).

First, I was clicking on the Edit Rubric button to actually edit the rubric, before trying to reorder the criteria. So, when I clicked on a criterion to move it, I would end up just editing that specific criterion. There was no mechanism to move it.

The reason I was doing that was because I expected there to be some indicator (like a hamburger button) on the rubric showing that criteria could be rearranged, but there was not. Because you confirmed that it was working correctly, I knew that I must be doing something wrong, so I went back to the rubric and tried clicking and moving criteria, and sure enough, it worked as expected.

Thank you for the help!

Cheers,

Keith

James
Community Champion

@naboznyk 

Glad you figured it out. It isn't a very accessible script (no indicator of dragability), it was just intended to be a quick fix.

naboznyk
Community Participant

@James 

Now that I understand how it works, it is fine! 

It makes a huge difference in reordering the rubric criteria into something more logical.

Thank you for creating it!

Cheers,

Keith

mpromislo
Community Explorer

James, sorry for the delay. I am talking about sorting the list of rubrics when you find a rubric. It is still not working for me and is extremely frustrating. Would you be willing to connect somehow to walk me through your fix? Thank you, Mark

mpromislo
Community Explorer

If it helps: in the TamperMonkey dashboard it shows that the Find Rubric Sorter is installed. However, when I click on the TamperMonkey icon in the group of extensions, it says that "No script is running."Screenshot 2021-07-28 14.09.51.pngScreenshot 2021-07-28 14.15.20.png

James
Community Champion

@mpromislo 

Sorry your post sat so long without me seeing it. The problem is that you are using a custom domain instead of rider.instructure.com, you have canvas.rider.edu. You need to edit the source code and change the include statement on line 5 to match your institution.

This is explained in the "Custom Domain" portion of the instructions above so you may have already figured it out. If not, try modifying the hostname portion of line 5 (the include statement) to be canvas(\.beta|\.test)?\.rider\.edu

ddavis4
Community Explorer

Or ... Canvas could take on the task to write the code and add the feature to Canvas where users could click a button saying "Find rubric from current course". Most of us do not care to be adding scripts, etc.

Instructure, please add this feature.

lettgo583
Community Participant

Our College of Nursing is now requiring faculty to use rubrics for assignments -- so that we can add Canvas Outcomes to the rubrics. This issue with trying to locate rubrics with "Find a Rubric" is going to be a bear. (Our IT folks control what goes onto faculty computers... they're not going to like adding extra apps to them all ... )

Is there anything else we can do?  

James
Community Champion

@lettgo583 

When I write these apps, I usually try to write them in a way that they can be added to the global custom JavaScript for an institution. That essentially puts it into everyone's browser (not sure that it works in the mobile app) in one step.

Usually, all it takes is a check to make sure that it only runs on the page it's supposed to run on. That's already part of the userscript code, but I add that double check so people can run it for their whole institution.

They would just strip out the meta-data at the top of the source code, although it's a comment so it wouldn't hurt if it was left in.

The global approach has the added benefit that they don't have to open the potential security risks associated with userscripts. They control what goes into the global file and can check it. I wrote it 6 years ago, so it's probably not up to current coding standards, but it still works.

lettgo583
Community Participant

Hi James,

Wow! That is fantastic news! I'll get with our university's Canvas admin.  I know he's already familiar with and uses a couple of your Canvancements personally ... so maybe we're halfway there! 

Thank you for all you do for the Canvas community!