Register for InstructureCon25 • Passes include access to all sessions, the expo hall, entertainment and networking events, meals, and extraterrestrial encounters.
Hello, All:
This is the first Tampermonkey script for me.
In Canvas, after manually doing this:
I want to then click a button, and automatically populate each of the points with the maximum in the rubric.
So, I want to go from this:
to this:
Here's what I'm attempting:
Edit: Well, all my nicely-aligned code got collapsed into one. Here's the full context: https://pastebin.com/D52jRfZ7
(function() { 'use strict'; var D = document; function initialize() { var btn = create_button('Default Points', set_values); var submission_details = D.getElementById('submission_details'); submission_details.appendChild(btn); } function create_button(text, handler) { var btn = D.createElement('button'); btn.type = 'button'; btn.id = 'pjo_default_points'; btn.classList.add('btn', 'btn-small'); btn.appendChild(D.createTextNode(text)); btn.addEventListener('click', handler, false); return btn; } function set_values(e) { var fields=D.getElementById('rubric_full').querySelectorAll('input[type=text]'); for (var i=0; i<fields.length; i++) { var pts = fields[i]; pts.value = i+1; // just a test value for now pts.dispatchEvent(new Event('change', { 'bubbles' : true })); } }
It does populate the values on the screen. (Note that I'm just using the index+1 for the value. Later I plan on more scraping to get the real value.)
But it's only superficial, because the score remains at 0:
And if I hit Save, all the scores change to "--"
I'm not sure what I'm doing wrong.
Any thoughts?
Thanks,
Phil
Solved! Go to Solution.
@pxo4 ,
I've spent more time on this than I want to admit -- even though I've not been posting things. I've fruitlessly tried for hours to make this work when I papers that needed graded. I tried change, blur, input, keypress, keyup, keydown, and anything else I could think of. None of them worked. None of them would trigger the event. I even tried things with the isTrusted and it didn't make any difference. Typing the score manually was the only thing I could get to work.
Tonight, I finally got caught up on all my grading and came into the community to catch up. Spotting your message made me try one more time. After about 10 minutes, I gave up and took a different approach. Rather than trying to figure out how to make it work, I focused on the "what changed" portion.
The what changed thing threw me in my previous testing. There was a file with a really enticing name called rubric_assessment.js that was being loaded. I kept on adding break points to it and couldn't get it to fire when I changed stuff. I thought that was just because it was getting loaded before I opened the rubric and enabled the breakpoint, but it turns out that it's not being anymore. It was a red herring.
What changed is that Canvas is using React on the rubrics now. Tonight, I changed my search to include triggering change events in React and came across this post on Stack Overflow: What is the best way to trigger onchange event in react js. That one hit was all I needed (and following some of the links within it) to find the issue and the solution.
Following down that path lead me to a solution that will work. Here it is, line breaking was added to make it display nicely in the Community.
var nativeInputValueSetter =
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
document.getElementById('rubric_full')
.querySelectorAll('tbody.criterions input[type=text]')
.forEach(e => {
var points = 2;
nativeInputValueSetter.call(e, points);
e.dispatchEvent(new Event('change', { 'bubbles': true }));
});
The points = 2 line is just an example. Modifying it slightly to fetch the maximum points from the ENV.rubric.criteria variable, we get this code snippet.
const nativeInputValueSetter =
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
let i = 0;
document.getElementById('rubric_full')
.querySelectorAll('tbody.criterions input[type=text]')
.forEach(e => {
let points = ENV.rubric.criteria[i].points;
nativeInputValueSetter.call(e, points);
e.dispatchEvent(new Event('change', { 'bubbles': true }));
i++;
});
I did not do any error checking, so make sure that you use the tbody as part of the query selector otherwise you will get more inputs than criteria. I get 7 inputs without it but my rubric only has 4.
I checked this with Firefox and Chrome with both free-form comments and ratings that you can click.
Finally, just in case you were curious, the bubbles does need to be there or it doesn't fire.
This has been a wonderful exercise. I have a feeling that it will need to happen a lot more as Canvas moves more and more things to React.
Here are some screen shots to show what's happening. Although this does show the ratings, I have tested it without them.
Before Shot
After shot
After closing Rubric
I revisited this after almost 3.5 years and wrapped it inside a userscript so that it automatically runs. This may duplicate some of the work that Phil had done, but I don't know where his script is and other people are asking for it. The code snippet I gave above doesn't work anymore unless you remove the .criterions from the selector. Still, it indiscriminately overwrote any existing point values and the process was not automatic.
It adds a "Max" button after the "Pts" in the rubric header. I had to widen the rubric pane to see it, but I thought that was the best place for the button since it applied to the points.
When you click the "Max" button, it will go through any rubric criteria that does not have a point value and assign it the maximum point value. This honors any ratings that you have already clicked on instead of setting them to the maximum value (as the code snippet I gave above does).
The two common uses I see are:
I would recommend using it with QuizWiz, which is a script I wrote that adds a button that will save the rubric, advance to the next user, and re-open the rubric
I haven't written a blog post in the Community about it yet, but the code and installation instructions are on the Max Ratings GitHub page.
You can ignore most of the private message I sent -- I didn't realize you were using free-form comments.
Hopefully I'm not introducing a red herring, but my current suspicion is that "isTrusted" is involved.
Most untrusted events will not trigger default actions, with the exception of the click event.
I had been using a bookmarklet all semester to accomplish this. A couple weeks ago, it stopped working.
I'm wondering if Canvas has begun enforcing "isTrusted". Because new Event('change') has isTrusted==false. And that's readonly.
Is the change event in the last line of code the correct event to be sending? just a guess.
Hello, Brett:
"change" was the right event all this semester. But something happened (either in Chrome, or in Canvas) about a month ago that now stops it from working.
I had also considered that maybe "change" had become the incorrect event to trigger. So I then used Chrome devtools to log all the events when I changed a score. Then I changed my code to trigger all those reported. Still didn't work.
I've not yet tried other browsers, but have gotten word from some other people that it doesn't work in FF or IE either.
Frankly, I've gotten behind on my grading because I was pursuing this. Need to catch up on that before I work on this again. 🙂
@pxo4 ,
I've spent more time on this than I want to admit -- even though I've not been posting things. I've fruitlessly tried for hours to make this work when I papers that needed graded. I tried change, blur, input, keypress, keyup, keydown, and anything else I could think of. None of them worked. None of them would trigger the event. I even tried things with the isTrusted and it didn't make any difference. Typing the score manually was the only thing I could get to work.
Tonight, I finally got caught up on all my grading and came into the community to catch up. Spotting your message made me try one more time. After about 10 minutes, I gave up and took a different approach. Rather than trying to figure out how to make it work, I focused on the "what changed" portion.
The what changed thing threw me in my previous testing. There was a file with a really enticing name called rubric_assessment.js that was being loaded. I kept on adding break points to it and couldn't get it to fire when I changed stuff. I thought that was just because it was getting loaded before I opened the rubric and enabled the breakpoint, but it turns out that it's not being anymore. It was a red herring.
What changed is that Canvas is using React on the rubrics now. Tonight, I changed my search to include triggering change events in React and came across this post on Stack Overflow: What is the best way to trigger onchange event in react js. That one hit was all I needed (and following some of the links within it) to find the issue and the solution.
Following down that path lead me to a solution that will work. Here it is, line breaking was added to make it display nicely in the Community.
var nativeInputValueSetter =
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
document.getElementById('rubric_full')
.querySelectorAll('tbody.criterions input[type=text]')
.forEach(e => {
var points = 2;
nativeInputValueSetter.call(e, points);
e.dispatchEvent(new Event('change', { 'bubbles': true }));
});
The points = 2 line is just an example. Modifying it slightly to fetch the maximum points from the ENV.rubric.criteria variable, we get this code snippet.
const nativeInputValueSetter =
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
let i = 0;
document.getElementById('rubric_full')
.querySelectorAll('tbody.criterions input[type=text]')
.forEach(e => {
let points = ENV.rubric.criteria[i].points;
nativeInputValueSetter.call(e, points);
e.dispatchEvent(new Event('change', { 'bubbles': true }));
i++;
});
I did not do any error checking, so make sure that you use the tbody as part of the query selector otherwise you will get more inputs than criteria. I get 7 inputs without it but my rubric only has 4.
I checked this with Firefox and Chrome with both free-form comments and ratings that you can click.
Finally, just in case you were curious, the bubbles does need to be there or it doesn't fire.
This has been a wonderful exercise. I have a feeling that it will need to happen a lot more as Canvas moves more and more things to React.
Here are some screen shots to show what's happening. Although this does show the ratings, I have tested it without them.
Before Shot
After shot
After closing Rubric
Hi, James:
Wow, this is exciting news! Thank you SO much for your tenacity and expertise on this. It's greatly appreciated!
I would have never figured that out!
As soon as I'm caught up on my grading, I will attempt to integrate your findings.
I'll update this thread after that.
Many thanks!
Phil
Hi, James:
I just incorporated your suggestions, and they worked perfectly!
Thank you again for your master expertise with this!
I appreciate your spending time on this. Hopefully it will benefit you with other scripts you write.
Thanks,
Phil
Hi Phil, where can I find this script to download it? It sounds very helpful.
Thanks,
FC
I revisited this after almost 3.5 years and wrapped it inside a userscript so that it automatically runs. This may duplicate some of the work that Phil had done, but I don't know where his script is and other people are asking for it. The code snippet I gave above doesn't work anymore unless you remove the .criterions from the selector. Still, it indiscriminately overwrote any existing point values and the process was not automatic.
It adds a "Max" button after the "Pts" in the rubric header. I had to widen the rubric pane to see it, but I thought that was the best place for the button since it applied to the points.
When you click the "Max" button, it will go through any rubric criteria that does not have a point value and assign it the maximum point value. This honors any ratings that you have already clicked on instead of setting them to the maximum value (as the code snippet I gave above does).
The two common uses I see are:
I would recommend using it with QuizWiz, which is a script I wrote that adds a button that will save the rubric, advance to the next user, and re-open the rubric
I haven't written a blog post in the Community about it yet, but the code and installation instructions are on the Max Ratings GitHub page.
James, thank you so much for your time and effort again!!
Yes, I did find myself needing to tweak the JS every once in a while, to accommodate the periodic changes Canvas was making to the HTML in new releases.
I will try your solution ASAP, and I expect that I will abandon mine in favor of it. 🙂
I am new to Canvas this year and this was the first issue I researched, as I use rubrics for all of my projects. Adding a MAX button to the speed grader page would be extremely helpful. Another option would be to add a DEFAULT method that would autofill each field with it's default max score value. Then, teachers could simply deduct points as they grade. One less click per page. Thanks pxo4 and James for your thread, and thanks Instructure for considering this.
@CLLions -
In addition to what James already gave you, if you are allowed to use his scripts(some institutions do not allow instructors to add tampermonkey and the scripts for security reasons), then I highly recommend that you look at using some of his other scripts - especially quizwiz-rubrics: This script helps with rubrics and if you use them - classic quizzes. Here is his page for all of his scripts: https://github.com/jamesjonesmath/canvancement and if you want links to explanations for most of them, check out this page: https://community.canvaslms.com/t5/Higher-Ed-Canvas-Users/Canvancements-Canvas-Enhancements/ba-p/246...
I wrote a script to add a Max button in April 2022. It's called Autofill Maximum Rubric Ratings.
To interact with Panda Bot in the Instructure Community, you need to sign up or log in:
Sign In
This discussion post is outdated and has been archived. Please use the Community question forums and official documentation for the most current and accurate information.