cancel
Showing results for 
Search instead for 
Did you mean: 
sara_chai
Community Member

Accessing all student grades...

Jump to solution

Is there an easy way (like there is for the student when they log in on the right hand side) for an admin to access grades in all subjects (6 classes)?  Our counselor wants percentages and an easy way to print them.  I realize that you can go into each class, but they want an easier - all classes approach.

47 Replies

jason.castaldo​,

 @codom ​ solution is based on running on a single page, so it can't be used to generate the report for all students in a course.  That would require API calls and then formatting the pages yourself or setting up some kind of system that obtained a list of IDs for the students in a class and then called the pages one-by-one. I've used CasperJS in the past to obtain information behind a different LMS system that didn't have a publicly available API. It wasn't particularly easy because I'm not a JavaScript programmer (although I've been teaching myself a lot as I write tools for people in the Community), but it did have the ability to save to a PDF. Then you could gather up all the PDFs and print them if you wanted to.

Here is another option for those who aren't necessarily programmers, but can do a little with Microsoft Excel and can obtain list of Canvas User IDs for the students who you want to see the grades for.

Create an Excel Spreadsheet that looks like this:

2015-09-20_23-57-58.png

The function in C2 is ="https://richland.instructure.com/users/"&B2&"/grades"

Obviously, you would want to replace the richland.instructure.com with your instance.

After you have logged into Canvas, you can copy the links from Excel and paste them into your browser. You have to do this one at a time, but it saves clicking back and forth between students. There is a way to turn those into hyperlinks by using the hyperlink() function. but when i clicked on them, it started a new tab inside Canvas that got passed the authentication but didn't take me to the correct page. Copy/pasting the same URL did.

It also sets itself up for some automation using AutoHotKey (AHK) or similar tool. That takes the automation out of JavaScript like the CasperJS approach would do and puts it in the hands of a Windows user. I hate doing repetitive tasks, so I've use AHK to transfer rubrics from Excel to Canvas before. They're a program to themselves, so it still may be beyond your capability if you're a non-programmer.

Personally, I still like the API, but then I can do some programming. You can make one call to the List your courses API per student and get all of their grades. But you have to do it as the student, which means you need permissions to masquerade. Of course, you probably need that anyway for any of these other solutions to work.

@JamesJones, when I tried to replicate your Excel method, it worked, however it seems to have linked me as an observer to all related accounts.   Meaning, in your example above, if I copy / paste the Fred Flintstone link, my Canvas screen was labeled - Linked Student Accounts and it showed me courses and grades for not only Fred Flintstone, but also his two brothers and sister.  Again, it was acting as if I was the linked parent to all the Flintstone children.  Did you experience that as well?  Thoughts on how to get around that?  Thanks - Joe

 @joseph_allen ​,

The Excel method uses whatever permissions within Canvas that the user clicking on the link has. It just generates the link that you would get if you visited the page directly within the Canvas. It saves time by putting all the links in one place rather than having to click back and forth. But when you follow the link, you should get exactly the same page that you would get if you went there in Canvas.


So, if you're seeing brothers and sisters that are linked on that page, then that should be what you see if you went to Fred's grades page directly from Canvas. I don't use this system myself as we're in higher education and going and looking at people's grades is a bad thing if you don't have a job-related reason to do so. I also don't have any experience with linked accounts or observers (higher ed and FERPA means parents don't automatically get access to student's education records).

 @codom ​,

I'm glad to see someone else contributing some JavaScript code to the Community.

I've got a couple of suggestions that can help improve your script.

Your JavaScript would run on any page that contains /users/. You mention at least two places where this occurs. I see at least three, which doesn't contradict you, but the third one you didn't list may have unintended consequences.

  • From the People page within a course, which would provide a "Grades" link for teachers and students: /courses/*/users/*
  • From the User Account Details page, which you get to from the People page within a course: /users/*
  • From the User Search page under the Admin menus: /accounts/*/users/*

The other problem is with the code itself. It would run on /users/*/grades page that you're sending people to when they click on the Grades button. But on that page, the canvas_user_id isn't the last thing on the URL, so your flipping of the URL fails to get the canvas_user_id and generates a bad link.

It would probably be better to use a regular expression to get the user id.

Then you could write your code like this:

var regex = new RegExp('/users/([0-9]+)$');

var matches = regex.exec(document.location);

if (matches) {

  if ($('#jj_allgrades').length == 0) {

    var url = '/users/' + matches[1] + '/grades';

    $('#right-side-wrapper div').append('<a id="jj_allgrades" class="btn button-sidebar-wide" href="' + url + '"><i class="icon-gradebook"></i> View All Grades for Student</a>');

  }

}

That's the entire code of what you have. Custom JavaScript is loaded at the bottom of the page, so it's probably save to run it without it, but better safe than sorry.

Some notes about the lines.

  1. This is running inside your Canvas instance, so I don't have to worry about other sites. I just need it to end in /users/ and a number. The $ at the end of the regular expression keeps it from having anything after the number. The parentheses around the [0-9]+ captures the number for later use.
  2. Check and see the document location matches the regular expression and save the results into the matches variable
  3. If does not match, then matches is null and the rest is not executed. This will skip any page not ending in a user number, so you don't have to test to make sure you're on the right page before running it. It adds a very slight performance hit, but then so does checking to see if the url matches.
  4. This is my own kludge to make sure that the button is not added more than once per page. It may not be necessary, but I got into the habit of doing it when I wrote my Course Roster Enhancements scripts. You might be able to remove lines 4 and 7 if you wanted to.
  5. Use a relative URL so you don't have to hard-code (or detect) the hostname of your institution. Remember, you're running inside your Canvas instance, so the browser already knows the hostname. matches[1] is the first captured match from the regular expression, which is the canvas user id.
  6. Add a button using the styling of the other buttons in the right-side-wrapper. I used icon-gradebook, but you can pick any icon available in the Canvas Style Guide​. The text of the button is "View All Grades for Student"

What I would then do is move this out of the global JavaScript file so that it doesn't run on every page. I would put it inside a user script that will run using GreaseMonkey (Firefox) or TamperMonkey (Chrome). I've tested it in both and it works just fine. Then I would load the script only for those users who need it. That way, it doesn't show up on student machines. That's not foolproof and of course, a student could still get the URL, but like you said, it relies on Canvas permissions once you actually get to the page.

GreaseMonkey and TamperMonkey scripts are automatically ran after the page is loaded, so you don't need the $(document).ready() check. That's another reason why I didn't put it in the code. It runs within its own scope, so you don't have to worry about your variables clobbering any document variables that might be named the same.

The only thing you have to do besides install GreaseMonkey or TamperMonkey is install the script and tell it where to run. You can include a regular expression to list the pages where you want to run it. This one matches all three instances I've mentioned as long as your Canvas instance is hosted at *.instructure.com. If you're running your own instance or have a branded URL, then you'll need to customize the first part.

// @include /^https://.*\.instructure\.com/?.*/users/[0-9]+$/

I'm attaching a user.js file to this message that contains the source code above. GreaseMonkey and TamperMonkey are programmed to automatically recognize *.user.js files and prompt you to load them when you click on one. So when it comes to installation, be sure to download GreaseMonkey before you download the user file.

Thanks again for the stellar work you did in putting this together in the first place.

 @James ​

Many thanks for your cleaning up of my code here and other places. I haven't had a moment to really look through it since then--as my instructional technology responsibilities have taken me away from some of this--but as someone who muddles through code, I definitely appreciate your input. Hopefully I'll have time this summer to really dig in and do some more work with all of this--but I just wanted to take a moment to thank you. I definitely want to contribute more and hopefully I'll be able to--hopefully this was helpful to others.

Thanks again.

Chris

Thanks for getting the ball rolling - it's a lot easier to tweak something than to write it from scratch.

James-

When we follow your directions and run the script, we get an error that states "Unauthorized."  However, if we replace the userID in the URL with the user SIS ID, then it loads correctly.  Is there a way within your script to change the userID to pull the SIS ID? 

 @ajuelmen  

Let me see if I understand what you're saying.

When I visit /users/1234/grades, even as that student, I get redirected to a gradebook for a certain course. If you don't have access to view the gradebook for that course, then you may be getting the unauthorized error. What I see as an admin is the gradebook for that course FOR EVERY STUDENT in the course, not just for the one that I was trying to see the grades for. Obviously that is unacceptable if I'm trying to print a summary for each student.

For some reason, when you go to /users/sis_user_id:5678/grades, then you get the regular screen that you're expecting to see.

Right now, we only have one course open for the students I looked at -- a shared student resource course. So I don't know if it's an issue that happens when there is just one active course or not. When I pulled up the grades for myself based off my Canvas ID, it worked properly, but that could have been because it's me or because I'm an admin.

When I masquerade as a student and then click on the "View Grades" button, it shows just grades for that one course (the same as if you were in that course).

I finally remembered that we have a dummy account for testing and when I tried it, it showed the expected grades.


So, what it looks like has happened is that Canvas has modified their logic so that if you only have one active course, it shows the details for the course. If you have more than one active course, then it shows the summary? Is this consistent with what you're seeing?

I could modify it to attempt to get the SIS User ID and then make that call. This is problematic as that information is not always available (it's more restricted than the Canvas user ID) and it would require an API call to fetch that information since it's not already available on the page, while the Canvas user ID is. However, the route (URL) with the Canvas user ID and the route with the SIS User ID should do the same thing, so any fix on their part is likely to make the SIS User ID act the same way that the Canvas user ID does, which means it will be just a temporary change.

I think a better route would be for Canvas to provide a way to get a summary, even when there is just a single course. But that means letting them know how this decision has interrupted your workflow and you're no longer able to do (whatever it is that you were counting on that to do).

To Canvas, this is an unsupported feature. There was never a "View all grades" option for anyone other than the student, so they're looking at it from the intended perspective, which means that they may not be receptive to fixing it. In their minds, they probably have already fixed it to provide details when there's only one course.

Thanks James for your quick response.

What I am trying to accomplish is to find a way for our teachers to access all student grades in all courses (not just the grade for the courses they have them in).  They need this for an academic check done daily in Homeroom.  During this time, teachers look at all student grades in all courses and have conversations about areas needing improvement. 

Your solution is perfect for what we need.  However, after I ran the script, I then masqueraded as a teacher to test.  The button to View all Student grades is present, but when I click on it, I get an "Unauthorized" screen. I don't believe it's a rights issue as I verified I have teachers set to "View all grades."  If I simply replace the user ID number in the URL with the student's SIS ID, I get the page I was hoping to get:

Ie:  Here's an example from an actual student.

(information deleted due to student privacy)

Does't work:  https://pulaskischools.instructure.com/users/1553/grades 

Works: https://pulaskischools.instructure.com/users/41298/grades 

246959_Screen Shot 2017-08-17 at 5.56.13 AM.png

246960_Screen Shot 2017-08-17 at 5.56.35 AM.png

I have read about this topic in various threads on Canvas.  It appears this all grades access was voted on in March and made it to production, but then Canvas reported they could no longer do this.  I assumed it was because the functionality is built into Dropout Detective and they didn't want to take business away from them- I could be wrong on that assumption!  However, I don't want to pay for another service when it appears this should be easy for Canvas to accomplish.

So, thank you for writing the script. Can you revise it to replace the userID with SIS ID? Will that still work?  Or, am I doing something wrong that it isn't working for us?  Thanks so much for your help!

Are you sure that you don't have your SIS ID and Canvas ID switched? When I try using the SIS ID without prefixing it with the sis_user_id:, I get the unauthorized error when there is no user with that ID. Well, technically there is a user associated with that ID, it's just a user at another institution, which is why I'm unauthorized to see it.

There is another issue potentially going on. If the script is working for you as an admin but not for a teacher, then it's a permissions error. See page 33 of the Canvas Account Role Permissions document and page 19 of the Canvas Course Role Permissions document. They both have a "View all grades" permission. The account level permission is what's needed to see the grades for all students in all courses and defaults to only Canvas Admins. The teacher role is a course level role (they are a teacher in one course but not in another) and they have permissions to view all grades within that course, but not the one to see the grades in other courses.  In order for that to happen, you would need to create an admin-type account role for all teachers with extremely limited permissions, but including the permission to view all grades.

As far as I know -- and the Canvas employees that I talked to at InstructureCon -- they are not refusing to develop anything because a partner like Dropout Detective does something already. When Dropout Detective is mentioned, it is usually by customers (or AspireEdu themselves) as a value-added functionality or a way to get things that the Canvas core product doesn't include easily. Canvas may not develop something for many reasons, like other things have a higher priority or there is a solution out there or a whole bunch of other things, but I don't think it's because it would make Dropout Detective go out of business.