cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
sara_chai
Community Contributor

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

please do : )

The simple solution is that you can find the numbers in the ‘Last User Access’ report. I have included the steps I took to create a list of links to all of our students.

I will see if I can use a similar method to create a single page that puts each student’s grade in separate iframe so each can viewed at the same time. If my programming were a bit better, it would probably be pretty simple to do this with a script. If anyone knows how to program hopefully you can expand on the idea.

In the new interface, go to Admin -> Your School

Click the Settings link

Click the Reports tab, then ‘Configure’ for ‘Last User Access’

Run the report for the desired terms

Once the report is done, download it and then open it in MS Excel

In Excel, sort by ‘user sis id’  to separate students from observers (if you use observers), then delete non-students

You may then wish to sort by ‘last access at’ and delete those who are no longer accessing the portal

Finally, sort by last name

You may leave all existing columns as they are, then in cell G2, paste the following formula:

="<a href="&CHAR(34)&"https://bvhs.instructure.com/users/"&A2&"/grades"&CHAR(34) & ">" & C2 & "</a><br />"

96401_pastedImage_0.png

Use the fill handle to copy the formula down through all of the users

Copy the new column to the clipboard

Open Notepad (or another text editor) and paste the column into a new document

96403_pastedImage_1.png

Save the document with a .htm extension

Open the HTML file and use the links to check grades.

96404_pastedImage_2.png

You will need to be logged in as someone who has access to the grades.

NIce!! Thanks for sharing this!

If a teacher just wants these numbers for their class they can see How do I download scores from the Gradebook?

and when they do this they will have a csv file like this one below. The ID column is where all those Canvas assigned user numbers reside. It would be pretty easy to take that and concentrate this in a Google Spreadsheet or Excel and then you would have a link for every student in your class. This would make for a great PD session on using sheets.

96509_pastedImage_0.png

codom
Community Participant

This is awesome! This solves a big problem for us. I was just having the conversation Friday with someone at Canvas about this need--or at least the need to masquerade on the subaccount level. (found out you have to have root admin access to masquerade). This seems to get around it and even limits into the subaccount (I think). (one issue we had is giving admins on one campus access to all students in the district). I'm not certain what permissions you need to make it happen--seems those admin permissions MAY have something to do with editing course content.

So with that--I wondered that instead of creating a webpage with the custom links, could I leverage those admin permissions, along with some custom Javascript to create a button on each users page with the grades? I think I've figured it out. (full disclosure--I've got a lot of experience with HTML and CSS, but my Javascript knowledge is poor. This code is probably not eloquent, and may even be bad. It seems to work, so take it what you will.) I thought I'd share it.

Essentially, I'm grabbing the URL for each user, finding the UserID, and creating a new URL for each user. I placed the link on the right side of the User Page. I've just begun to play with it--and already had to edit it a bit...so fire away if you see anything wrong. This is, quite honestly, the first piece of JavaScript I've written in my life that does anything worth noting.

/*This script appears to add a link on a user's profile page after a search to view grades.
*This leverages Canvas' permissions to hide the grades for those who are not admin
*Use at your own risk
*/

$(document).ready(function(){

if(window.location.pathname.indexOf('/users/') >=0){

/*Get current URL from Canvas, and split into an indexed string */

var originalURL = window.location.pathname.split('/')

/*Flip the String in originalURL because Canvas has at least two paths for the user page
*(/accounts/subaccountnumber/users/ and /users/)
* and we are interested in just pulling the userID
*/

var flipURL = originalURL.reverse();

/*Access the User ID*/

var userID = flipURL[0];

/*Build New URL */

var newURL = "https://yourinstitution.instructure.com/users/" +userID+ "/grades";

/*Add Text Link to right side of User Page to see grades */

var c = $('#right-side');

var text = '<a href = "'+newURL+'" >Grades</a>';

$(text).appendTo(c);

}

});

jason_castaldo
Community Participant

I the solution for web links works fairly well for us, however it would be

ideal if we could use the URLs to generate a report of all students.

Unfortunately, I'm not a programmer.

On Sun, Sep 6, 2015 at 10:46 PM, codom@rhmail.org <instructure@jiveon.com>

isaac_piercy
Community Participant

Chris,

This is a really interesting work around! Any idea which permissions make this page visible to a user? I'm assuming they need to have some type of admin status on the server to see that grades page.

Chris_Munzo
Community Champion

All -- It looks like you've got some ways within native Canvas to get this information.  We've also created a screen within our Dropout Detective solution to do this.  It's "jumping off" point is a dashboard of at-risk students, so that's a bit different than the native Canvas. 

Overview K-12.PNG

codom
Community Participant

As I stated earlier--I've been messing around with some custom Javascript to create the link for grades and stuff. I just finished working on a way to display the student's name on the grades page. That was our number one complaint from our administration after we implemented the Grades button that I described earlier. I'm attaching screenshots to show what each code does: (which I didn't do last time)

Grades Button:

103004_pastedImage_0.png

$(document).ready(function(){

if(window.location.pathname.indexOf('/users/') >=0){

/*Get current URL from Canvas, and split into an indexed string */

var originalURL = window.location.pathname.split('/')

/*Flip the String in originalURL because Canvas has at least two paths for the user page
*(/accounts/subaccountnumber/users/ and /users/)
* and we are interested in just pulling the userID
*/

var flipURL = originalURL.reverse();

/*Access the User ID*/

var userID = flipURL[0];

/*Build New URL */

var newURL = "https://yourinstitution.instructure.com/users/" +userID+ "/grades";

/*Add Text Link to right side of User Page to see grades */

var c = $('#right-side');

var text = '<a href = "'+newURL+'" >Grades</a>';

$(text).appendTo(c);

}

});

I've now added the student's name to the top of the grades page:

103005_pastedImage_1.png

$(document).ready(function(){

if(window.location.pathname.indexOf('/grades') >= 0){

var originalURL = window.location.pathname.split('/');

var userID = originalURL[2];

console.log(userID);

var studentinfo = "/api/v1/users/" +userID;

console.log(studentinfo);

$.getJSON(studentinfo, function(json){

console.log(json.name);

studname = '<center> <h3> Grades for ' + json.name + '</h3> </center>';

$('#content').prepend(studname);

});

Just thought I'd share--since I wouldn't have gotten this far without this thread. Thanks again, everyone!

James
Community Champion

 @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
Community Champion

 @codom ​

Thanks again for the work you do.

There is a problem with this latest piece, though. It will run on the page the student gets when they click on the Grades link at the top of the page (or wherever it is in the new UI).

That page has a location of <canvas>.instructure.com/grades

It does not have the canvas_user_id in it, which means that you'll be making an API call that will fail for every student who looks at their grades.

I just posted a cleaned-up version of your original JavaScript up higher in this thread. It uses Regular Expressions to make sure that the path matches the right thing.

It would be

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

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

if (matches) {

     // do your stuff

}

Although not necessary, I notice you did it everywhere else and it's good programming practice, you may want to put a var in front of studname.


You don't have to compute studname first, you can just put it inside the prepend statement.

I was kind of surprised when i saw that report. The breadcrumbs had my name in it and the actual student's name wasn't anywhere to be seen. I thought about doing an API call like you did, but then I thought about FERPA. I have my own grade system for some classes that aren't in Canvas and I don't print the name on the screen, either. I don't want someone to print it and accidentally leave the paper lying around (or still in the printer) and have other people know what grades there are.

I would recommend the same thing here that I did with the other script, though. Consider putting it inside a GreaseMonkey or TamperMonkey script and then only loading that script on the computers of the people who will be using it. GreaseMonkey and TamperMonkey scripts only run on the pages specified, so you don't have to check the location of the page to make sure it matches.

Thanks again. It's great to see someone else contributing code.