Skip navigation
All Places > Instructional Designers > Blog > Author: James Jones

Instructional Designers

3 Posts authored by: James Jones Expert

Update: August 26, 2017

This was one of my early works and before I learned how to package it to make it easy for people to use. I've repackaged it and made it act more like the other Canvancements I've written. The script still worked after these two years, so I didn't change it other than to make it easier to install and make sure it runs on the correct page.

Quick Install

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

  1. Install a browser add-on: Greasemonkey for Firefox or Tampermonkey for Chrome/Safari
  2. Install the sort-content-selector user script.

This script intentionally does not run on the course Home page. You'll need to go to the Modules page to use it.


Original Post: August 26, 2015


When a user clicks on the Add Items to a module, the order of the pages is inconsistent. Some items are listed in order of most recent edit and others are listed alphabetically. This can make it difficult to find items. This post will show you how to add a script that will sort those lists alphabetically for you.



This issue may not be as popular as the one addressed by Sorting Rubrics Made Easy , but it will help demonstrate some of what can be done with Greasemonkey and injecting your own user scripts onto a page.


Chris Hofer created a feature request Sorting "Add Item" List in Modules  that managed to get a whole 4 votes in the three months it was open for voting. After that one had been archived, Emanuela Pokryfki created a feature request Alphabetizing the list of items in the "Add items to...(module)" window that basically asked for the same thing. Jordan Dayton suggested the two of them collaborate and come up with a compelling description.


Here is a short 55 second video demonstrating the problem and the proposed solution.




Installing Greasemonkey

The key to doing this is Greasemonkey, which is a Firefox add-on. For Chrome users, there is Tampermonkey. I haven't tested Tampermonkey myself, but the principles are the same.


Here is a short video on how to install Greasemonkey and start your first script.



Creating a Script

Make sure you have enabled Greasemonkey. Then go to New User Script.


Hint: Greasemonkey will automatically attempt to use the name of the page you're on, so you might want to navigate to the proper page before you create it.


Complete the configuration form.

  • Name: Give it a name to identify the script
  • Namespace: This is a URL or URI to identify the author, just in case two people have the same name for a script. There are collections of user scripts out there. I'm not publishing this one to those places because the include pages need configured before they are useful.
  • Description: A brief description of what the script does
  • Includes: This is a list of the pages where you want the script to run. My Canvas instance is and I want it to run on the modules page (but not the homepage). So I put*/modules. The * is a wildcard so that it matches the modules page on any course. I also added https://richland.*,*/modules so that it will run on the test and beta instances as well. This part absolutely needs customized for your site!




Then click OK and you'll be given an editor. Paste the code below into the editor. Note that you may want to start after the header so that you don't wipe out the work you just did.


Note, this code is also available as an attachment to this post.


// ==UserScript==
// @name        Canvas Sort Module Add Item
// @namespace

// @description Alphabetically sort the Add Items to a Module lists
// @include*/modules

// @include    

// @version     1
// @grant       none
// ==/UserScript==
var itemTypes = [
for (var i = 0; i < itemTypes.length; i++) {
  var sel = '#' + itemTypes[i] + '_select select.module_item_select';
  if ($(sel + ' optgroup').length > 0) {
    sel += ' optgroup';
  $(sel).each(function () {
function sortOptions(j) {
  var newRegex = new RegExp('^\\[ New');
  var numRegex = new RegExp('^([^0-9]*)([0-9.]+)');
  var options = $(j).children('option');
  if (options.length > 0) {
    options.sort(function (a, b) {
      var atxt = a.text;
      var btxt = b.text;
      if (newRegex.test(atxt)) {
        return - 1;
      if (newRegex.test(btxt)) {
        return 1;
      var anum = numRegex.exec(atxt);
      var bnum = numRegex.exec(btxt);
      if (anum && bnum && anum[1] == bnum[1]) {
        return parseFloat(anum[2]) > parseFloat(bnum[2]) ? 1 : - 1;
      return atxt.localeCompare(btxt);


Then click Save and enjoy alphabetically sorted lists when you add items on the modules page.


If you need to edit the code and you're on one of the included pages, just open up the Greasemonkey menu and right click on the script name at the bottom. If you're not on that page, then you can go to Manage User Scripts and right click on the script there.


Explanation of Code (Optional)


There are no additional JavaScript libraries needed to run this as jQuery comes with every page in Canvas.


  • Lines 1-9 are the Greasemonkey configuration. Be sure you change the @include statements on line 5 and 6 to match your site. The second one in line 6 is optional if you don't want to use this in your test or beta site.
  • Lines 10-15 specify which types of items to sort. You'll notice that attachments (files) is not included. It is loaded by AJAX calls when you first click on it. The others are all loaded ahead of time. Quizzes were already sorted alphabetically, but I included them anyway.
  • Lines 16-25 iterate through the types of items to sort. It looks for a "optgroup", which is HTML-speak for a grouped item. In particular, the assignments list is that way. It does not change the order of the groups, so those will still be in the order they are on the assignments page, but it will sort the items within the groups.
  • Lines 26-49 does the sorting. It makes sure that any "[ New" type item remains at the top. Then it looks for text that contains a number. The sorting is done by comparing two items at a time, and if both entries contain a number and the part before the numbers are identical, then it will sort by the number rather than alphabetically. The normal alphabetical sort puts "Item 12" before "Item 2" and this keeps it in the proper order. It doesn't handle decimals with more than one decimal place, so if you have "Section 3.12", it will appear before "Section 3.2". I didn't want to overly complicate the code, because the idea of major.minor.minor numbering could go on forever. The comparison uses the localeCompare() function, so if you have accents or multinational characters, it should properly sort. When it's all done, it wipes out the existing options and then replaces it with the sorted ones.


User Scripts

Greasemonkey and User Scripts have the potential to provide interim solutions for a lot of feature requests. They allow you to do some things that would normally require access to the Global JavaScript file. One major benefit is that anyone can run user scripts, not just administrators. Another is that you can decide what you want to do, so if one instructor wants the items sorted alphabetically and another doesn't, then that's doable. With the Global JavaScript file, that's not an option.


You also get to manage the scripts separately rather than one large JavaScript file. If you need to include other libraries, that can usually be done by adding a single @require statement to the configuration in the heading. All GitHub hosted JavaScript files can be loaded through a content distribution network (CDN) so that you don't even have to host it yourself. And if you want to do something that requires a newer version of jQuery than the 1.7.2 that ships with Canvas, you can load that as well (usually this isn't needed).


The important thing to remember is that User Scripts do not run for anyone other than you and they only run on the pages you tell them to run on. That means that you cannot insert JavaScript that will do anything for anyone else, like embed a video or show a tweet. If you are asking a question like, "Can I use this so that the students will ..." the answer is "no!". But if you're designing a course, they can provide some added or improved functionality to make your workflow faster.


If you have Firefox sync enabled, you can sync your Greasemonkey scripts with your other computers.

James Jones

Sorting Rubrics Made Easy

Posted by James Jones Expert Aug 24, 2015

Quick Install

  1. Make sure a user script manager such as Tampermonkey is installed and enabled.
  2. Install the sort-rubric.users.js file

More information is available on my Sort a Rubric Canvancement page.

Update: October 24, 2019

With the October 23, 2019, deployment, Canvas changed the way that jQuery is loaded so that it will be available for your custom global JavaScript and you won't have to worry about it. However, all of the scripts now have async loading, which is a good thing, but it means that the script manager was injecting this script before jQuery was loaded and it failing.

I took the time to update the script and improve the coding. It was one of the early ones I wrote before I knew much about what I was doing.


Note that the blog post below refers to Greasemonkey. Tampermonkey is now the recommended userscript manager. Also do not use the source code in the original blog post -- it will no longer work.


Update: May 3, 2016


Why the Update?

The original blog post (below) talks about copying and pasting into GreaseMonkey. This was one of my earliest attempts with user scripts and I've since learned how to make them really, really easy to install, but the documentation was in the comments to this blog post and people were missing it and still trying to follow the original instructions.


I didn't want to lose the blog post, because it explains what happens and has videos that show it in action, but most people want a plug-n-play, drag-n-drop, or click-n-go solution, and that's what you get through the quick install. Please use the Quick Install and read the instructions and comments below if you care to know what it's doing or run into trouble.


Original Blog Post: August 25, 2015



The ability to sort (drag and drop) rows of a rubric can be made transparent so that it automatically runs on the Rubric editing page. The techniques shown here open up a whole world of solutions to "I wish Canvas would ..."



On August 16, I wrote a blog post illustrating how you could inject two lines of JavaScript into a page sort the criteria in a rubric: How to Reorder Rubric Criteria


Since then, I've learned more and found a new technique that blows the first way out of the water. It allows for automatic injection of the JavaScript based on the URL, so it only loads on the Rubric page on your site. But then it automatically runs, you don't need to do anything other than enable it. It works with the Javascript already included on every Canvas page. it downloads the libraries you include when you save the script so that loading them is almost instantaneous.


This is so much easier than the first blog that I'm almost tempted to pull the first one down, except some people have linked to it and it illustrates some of the technical details that this one omits. So if you want to understand more about what it's doing, go read that.


Let's begin with a 55 second video demonstration of what to expect. Notice that when I get to the Rubric editing page from Outcomes > Manage Rubrics that the rubric was automatically sortable once it loaded. That's the beauty of this over last week's method, you don't need to do anything special once it's set up, it just automatically allows you to drag and drop rubric rows.



The key to doing this is Greasemonkey, which is a FireFox add-on. For Chrome users, there is Tampermonkey. I haven't tested Tampermonkey myself, but the principles are the same.


Here is a video that shows everything needed to accomplish the rubric editing demonstration above. It begins with the installation of the Greasemonkey, shows how to include javascript libraries, and explains what the code does.



Greasemonkey User Script

This is all about User Scripts. User scripts are scripts that the user creates that runs on the page. Last week, I was talking about bookmarklets that someone could click on to run on the page after they clicked the Edit Rubric button. This is automatic - you don't need to do anything other than enable the script. It's also a lot easier to create than a bookmarklet.


// ==UserScript==
// @name        Canvas Rubric Sort
// @namespace
// @description Injects the RowSorter.js jQuery library into Rubric Pages on Canvas
// @include*/rubrics/*
// @include*/
// @include*/
// @require
// @require
// @version     1
// @grant       none
// ==/UserScript==
waitForKeyElements('.rubric_container.rubric.editing', attachRowSorter);
function attachRowSorter() {


That is the complete code. Let's take a look at what each line does.

  1. Define this as a Greasemonkey user script
  2. The name of the script
  3. A URL or URI to identify the author in case two or more authors have the same program name
  4. A brief description of what the script does
  5. Run this script on pages matching the main Canvas instance for your site. The main page for editing rubrics is /courses/*/rubrics/*, where * is a wildcard
  6. Run it on the test site as well - optional
  7. Run it on the beta site too - optional
  8. Inject the waitForKeyElements javascript library. This will make sure that the rubric is done loading before you can sort it.
  9. Inject the RowSorter javascript library. allows you to link to any GitHub hosted file, so you don't have to install your own version like I wrote last week.
  10. The version of the code - this is up to you to maintain (or ignore)
  11. The grant statement gives special permissions, none are needed
  12. End the header
  13. The rubric_container and rubric classes are already present. The "editing" one gets added when you click Edit Rubric, so wait for that class to be added to the table, then call the attachRowSorter function.
  14. This function is called after the "editing" class is added by the user clicking on the Edit Rubric button.
  15. Add the rowSorter() method to the rubric_table.
  16. End the function

Every time you make changes and save the code, it will automatically get the javascript libraries on the @require lines so that it's hosted locally and doesn't have to be downloaded when you run the script.


The only changes that you need to make to this script are lines 6-8, where you define where your Canvas instance is loaded.


Using Greasemonkey

Greasemonkey is relatively easy to use. As long as it is enabled, it will check the pages for a match against the @include lines in the header. If you want to disable Greasemonkey, go the monkey and click on Enabled to disable it.


There are a couple of ways to edit a script. If you are on the page where the script would be executed, the name of the script will appear the bottom of the menu. Just right click your mouse on the name and it will load it for editing. The second way is to go to Greasemonkey > Manage User Scripts and then right click your mouse on the script you want to edit.



  • When you drag and drop rows, make sure you grab the description (left) or the points (right). Do not try to drag one of the items in the middle, the formatting goes crazy and you can't do anything. If you do that, reload the page and edit again and don't drag in the middle.
  • If you want to disable the drag & drop editing, then go to the Greasemonkey on the menu and disable it.
  • Greasemonkey scripts run after the page is loaded, so you have access to jQuery.
  • Greasemonkey is synced with Firefox so it will follow you from machine to machine if you have sync setup.


No Global Javascript Access? No Problem!

In case you haven't realized the ramifications of this, it allows you to add your own JavaScript to Canvas like you had access to the global JavaScript page.

That means that regular users can add their own features, even if the administrator's won't put make the changes globally.


You should, of course, not use it for features that you want your students to see because they won't be able to see it -- it's local to your machine. However, it is useful for development and for teachers. For instance, want to add the ability to sort tables by clicking at the top of a column -- you can do that.


Want to automatically create a rubric based on an Excel spreadsheet -- well, that's going to take some work. But let your imagination run wild.


This will show how you can execute two lines of JavaScript code inside your browser that will add drag and drop functionality to a rubric and allow you change the order of the criteria.



Back in April, Chris Hofer created a feature request Editing Capabilities for Rubrics . His second item was "Drag and drop an existing rubric row to another location in the same rubric."


On May 14, Canvas indicated that this project had already been designed so they get to skip ahead and are hoping to get it onto their roadmap in June. On July 13, they are collecting and evaluating suggestions and the process starts soon with a hope to share some updates. It's now a month later, August 16, and it's still not implemented. In the Canvas Studio, the closest I can find is a document about outcomes The specified item was not found. that is in development (last updated May 18) that says they want the ability to mass-edit outcomes including some things that could be rubrics.

So basically, this is another one of my "Here's something you can do while you wait on Canvas" endeavors. Other ones include Google Spreadsheets to Adjust all assignment and quiz dates on a single page  or How to Count Student Discussion Posts. I hope to take that adjust all dates on a single page sheet and add the ability to duplicate or delete any assignment or quiz in a course from a single page.


Although I had voted for Chris' request, this wasn't even on my radar until I was developing my course materials and made the mistake of having someone proof my discussion rubric. Getting the "Looks good", I went ahead and put it into Canvas and then proceeded to add it to 16 different discussions. I decided that I would make a handout for the students with the rubric and stressing that there were two due-dates, one for the initial post and one for the follow-up discussion. It was at that point that I realized I had misspelled four words in the rubric, but was unaware because I had created it in Excel and it didn't indicate spelling mistakes.


As you probably know, you can't edit a rubric once it's used in more than one place, so I diligently went through and deleted the rubric from 15 of the discussions so I could edit it.


That led me to ask the question "Isn't there an easier way?"


Now I do a lot of work with the API and I had looked at rubrics before and the answer was no, there isn't. I looked again and that's still the answer. Part of searching for answers led me to Chris' feature idea and that led to this blog post.


This is intended as an interim solution until Canvas can deliver a fully-developed one. I hope you benefit from it.


Drag-Drop Criteria in a Rubric

Did you know that ...

  1. when editing a rubric,
  2. you can drag and drop the rows in the table, and
  3. change the order of the criteria


This summer, Kona Jones taught a statistics class online and her get-to-know-each-other discussion was "2 truths and a lie." You basically make three statements, two of which are true and one of which is false.The students then try to guess which is the lie.


Well, two of the statements I made are true and one is false.


Yes, you guessed it, it's the second statement that's false.


But hypothetically speaking, if you could could do step 2, then step 3 is correct. It's not documented because step 2 is a lie.


Well, it turns out that you can't natively do the drag and drop, but you can with two simple lines of JavaScript code and a little bit of computer savvy (no programming, but you do need to install a browser add-on)


I'll tell you how to do it from your browser (assuming you're using FireFox), but if have control of your global Javascript file and have lots of people who would benefit from this (or just one really loud and obnoxious one), you might consider putting it there so it's automatically available to everyone editing a rubric.


The first line of JavaScript loads the RowSorter.js jQuery plugin and the second line attaches it to the rubric table.




This is a JavaScript library by Gökhan Bora and can be found at GitHub: borayazilim/rowsorter · GitHub


All that you need is to install the jquery.rowsorter.min.js file onto a web server. By that, I mean that you don't need any other file in the distribution to make it work.


There is concern about HTTPS vs HTTP connections. Canvas is HTTPS and doesn't like mixed content (non-secure content on a page that is otherwise secure). But I tested it on a non-secure server at home using the HTTP protocol and it worked fine.


Installing the file is beyond the scope of this blog, but it's basically just putting the file out somewhere you can reach it with a web browser. You don't even have to mess with Git, you could just view the jquery.rowsorter.min.js file, click on the Raw button, copy the code, and paste it into a text editor.


FireBug Extension for FireFox

I did the testing for this using FireBug for Firefox. The bulit-in web developer stuff might have been able to do it, but I couldn't find documentation that explained how, so I just stuck with FireBug. You can add it to Firefox through the Addons or from their website Firebug


There is probably something that allows similar functionality for Chrome, but I didn't go looking.


How to Reorder the Criteria

Choose Your Rubric

Rubrics can be found by going to Outcomes >> Manage Rubrics. You can also get there by appending /rubrics to the end of your course homepage URL.


I chose a rubric that had 19 criteria. The first few criteria looked something like this:


Edit the Rubric

Once you select your rubric, click the big Edit Rubric button on the right.


Technically, you could inject the javascript first and then edit the rubric. The point is, at some point, you need to click Edit Rubric.


Inject the JavaScript Library

Now it's time to open FireBug and load the JavaScript Library. The RowSorter.js library is a jQuery library, and jQuery is already loaded by Canvas, so this makes it really simple to install because you don't have to bother with loading jQuery first.


Click on the FireBug icon on the toolbar or go to press F12.


The bottom of your screen should have a menu like this:


The important part is that Console be selected.


When you do that, the right side of your screen should look like this:


You can paste JavaScript commands into that box and that is exactly what we need to do.


The URL to where I placed the jquery.rowsorter.min.js file is:


Don't try pasting that into your browser, it's part of the private IP address space, which basically means that you can't get there from where you are. But make a note of where you stuck it because you will need that in this step.


The FireBug command to load a javascript file from its source is include.  Paste this into the console box, but use your URL instead of mine.




The right side should now look like this:


When it does, click the Run button at the top of that console box.


Over on the left side, the console should now say that the file was included:


If you don't get that "properly included" message, then pay attention the error message. It's possible that your URL may be wrong. Try pasting the URL it into another browser window and see if you get Javascript code.


Yay! We're half-way there, although this was the longer half.


Attach RowSorter.js to the Rubric Table

Now that we've loaded the library, we can tell RowSorter that it should attach itself to the rubric.


The way to identify the rubric table is with a class of rubric_table (score one for simplicity).


So we need to execute the jQuery command:



This command is the same for everyone, it doesn't matter where you stuck your jquery.rowsorter.min.js file.


Remove the include line that was already there and replace it with this one so that your right-side console box looks like this:


I guess technically you don't have to remove the include(); line first, but if you don't it will download it again. It's small, but there's no point in duplication.


When you click Run, the left side should now look like this:


Close Firebug (optional)

You're done with FireBug. You were just using it to get the JavaScript commands executed and it's taking up a lot of your screen. You can click the red power button in the top right hand corner or to deactivate it or press F12 to minimize it (return it to the toolbar).


Although you don't have to close Firebug, it's recommended.


Warning: Don't be Anxious!

Some of you are wondering, "Why can't I just put both lines in there at the same time?"


Others of you tried it and found it didn't work ... the first time, but it did the second.


The problem is that you need to let the RowSorter.js library load before you try to use it and if you put them both in at the same time, then the RowSorter.js routines aren't ready when they are called. There are other ways around this, but I was going for simple.


If you absolutely hate two lines of code and are the only person that is going to be using the copy of the RowSorter.js library that you made available, then you can just add the line that attaches the rowSorter() method to the table at the end of that file. Then all you need to do is just include the one source code and you'll know that the source code is loaded before you attempt to use it because it came after the library in the file.


You may be able to create a bookmarklet that will allow you to just click a button to make a rubric editable. That is beyond my skill set.


Drag and Drop Criteria

That's it! It's now ready to drag and drop the criteria. Just click anywhere in the row and drag it to another row to reorder your criteria.


The defaults of the RowSorter.js file are good enough to do the basics. There are extra things that can be done like adding styling so you can tell which row you're dragging, but again, I was going for simple. With just those two commands, can drag and drop to reorder your rows.


Here's what the first few criteria in the rubric look like after I moved the rows around (the first two rows are switched from what I had before).


When you're done, just Update your rubric like normal.



  • Don't do this while you're creating a rubric. It would probably work, but it's probably simpler and safer to go ahead and create the rubric and then go back later if you need to reorder rows.
  • If you insist on running both JavaScript commands at the same time, you may have to press the Run button a second time to get it to work. The key to success is making sure sure the library loads before you try to use it. Alternatively, you can combine the library and the jQuery statement together to save time.
  • If you have control over your global Javascript file and don't mind using it to add functionality, you could include the RowSorter.js file there (different commands would be needed). I don't have control over that file for our site, so this was a way that anyone with a few skills could reorder the rubric criteria.


I hope this can help someone who has ever wanted to change the order of the criteria in a rubric.

Filter Blog

By date: By tag: