cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
haceved5
Community Participant

Enroll user via theme edit

Jump to solution

Hello,

Not a web developer so I have only basic knowledge of CSS and JS. I am trying to put some buttons in the course settings that instructors can click on to add people to their course. These buttons are for our student assistants and it speeds up the process of them being added to a course to help troubleshoot remotely.

I got a version of this working, but it isn't working consistently. Right now the latest version of Firefox isn't doing it while previous versions are working. Chrome is working on my machine.

Is there any way I can modify this to make it more consistent? It is adding them as a custom role, and when it works it works well. Any help is appreciated. This code is part of the .js in the theme.

if (ENV['current_user_roles'].includes('teacher')) {
    var undel = window.location.href;
    var course_id = undel.match(/\d{2,}/);
    var api_url = "/api/v1/courses/REPLACE_THIS/enrollments";
    api_url = api_url.replace("REPLACE_THIS",course_id);
    undel = undel.slice(0, -9);
    undel = undel + "/undelete";
    
    $("div#right-side-wrapper.ic-app-main-content__secondary aside#right-side > div > a.Button.Button--link.Button--link--has-divider.Button--course-settings.validator_link").after("<a class='Button Button--link Button--link--has-divider Button--course-settings' href='" + undel + "'><i class='icon-trash'></i> Undelete Content</a>");
    
    $("div#right-side-wrapper.ic-app-main-content__secondary aside#right-side > div > a.Button.Button--link.Button--link--has-divider.Button--course-settings.validator_link").after("<a class='Button Button--link Button--link--has-divider Button--course-settings' href='.' id='addLMS3'><i class='icon-user'></i> LMS Support #3</a>");
    
    $("div#right-side-wrapper.ic-app-main-content__secondary aside#right-side > div > a.Button.Button--link.Button--link--has-divider.Button--course-settings.validator_link").after("<a class='Button Button--link Button--link--has-divider Button--course-settings' href='.' id='addLMS2'><i class='icon-user'></i> LMS Support #2</a>");
    
    $("div#right-side-wrapper.ic-app-main-content__secondary aside#right-side > div > a.Button.Button--link.Button--link--has-divider.Button--course-settings.validator_link").after("<a class='Button Button--link Button--link--has-divider Button--course-settings' href='.' id='addLMS1'><i class='icon-user'></i> LMS Support #1</a>");


    document.getElementById("addLMS1").onclick = function() {addLMSPerson1()};
    document.getElementById("addLMS2").onclick = function() {addLMSPerson2()};
    document.getElementById("addLMS3").onclick = function() {addLMSPerson3()};

    function addLMSPerson1() {
        $.post(api_url, { 'enrollment': {'user_id': xxxxx, 'type': 'TaEnrollment', 'role_id': 23} });
    }
    
    function addLMSPerson2() {
        $.post(api_url, { 'enrollment': {'user_id': xxxxx, 'type': 'TaEnrollment', 'role_id': 23} });
    }
    
    function addLMSPerson3() {
        $.post(api_url, { 'enrollment': {'user_id': xxxxx, 'type': 'TaEnrollment', 'role_id': 23} });
    }
}

Thank you,

Henry

1 Solution

Accepted Solutions
robotcars
Community Champion

Hi  @haceved5 

First, I'd like to warn that enrolling students as a teacher aid could be a huge FERPA violation if that role allows students to access other students information, grades, profile, and submissions. You might want to evaluate that, change permissions, create a different role, or find a new solution. 

Several things bubble to the top for improvement:

  • Steer away from using the URI (window.location.pathname) and parts to attain values (course_id). You've already used the ENV provided in pages. There's more there, checkout ENV in the console. ENV.COURSE_ID, which can have inconsistencies depending on the page the user is on.
  • Try to use Regular Expressions to limit your Theme hacks to the page you want them to execute on. I'll share one for this below.
  • While the #right-side-wrapper seems to be consistent on most pages, it is empty on several pages within the course navigation. Link Navigator only exists on the Settings page. Are you expecting to only see these links there?
  • Clicking 1 of the 3 LMS Support buttons fires incorrectly. GlobalEventHandlers.onclick - Web APIs | MDN takes a function reference, not a function. So change that to 
    document.getElementById("addLMS1").onclick = addLMSPerson1;
  • The href for the LMS button are '.', which when clicked, the browser follows , ignoring your click event. Change this to something like a hashtag href="#", which the browser recognizes are part of the page, or href="javascript:void();" or href="return false", which tells the browser to do nothing, which will let your callback execute.
  • The jQuery post makes it hard to troubleshoot or do any error handling, without building your own logic. I've change that to use $.ajax with a success and error callback. These come in useful when working in the Browser Console, see Developer Tools for the Canvas User 

I've reduced the code a bit to make it more readable or concise. Looking at the code, you added 3 buttons, without a Modal (little window for adding additional info, or a dialog box). Are you expecting to enroll the same 3 users, 1 for each button, or allow the Teacher to pick names? If it's the same 3 users, we can probably add them with 1 button. But this leaves the user's CanvasID exposed in your publicly accessible javascript, which isn't a good thing. Either way, we could reduce the code to execute all 3 onclick, or pass the userid to a single function for each button.

Here's a revised version, working in the new Firefox... actually I only test there. :smileyshocked:

This version will enroll You (self) as the TA, for testing. You can change the user_id.

// https://community.canvaslms.com/thread/49469-enroll-user-via-theme-edit

(function () {
if (/^\/courses\/\d+\/settings/.test(window.location.pathname)) {

if (ENV['current_user_roles'].includes('teacher')) {

$('.validator_link').after('<a class="Button Button--link Button--link--has-divider Button--course-settings" href="undelete"><i class="icon-trash"></i> Undelete Content</a>');

$('.validator_link').after('<a class="Button Button--link Button--link--has-divider Button--course-settings" href="#" id="addLMS1"><i class="icon-user"></i> LMS Support #1</a>');

function addLMSPerson() {

$.ajax({
type: 'POST',
url: `/api/v1/courses/${ENV.COURSE_ID}/enrollments`,
data: {
'enrollment': {
'user_id': 'self',
'type': 'TaEnrollment',
'role_id': 1936 //23
}
},
success: function (r) {
console.log(r)
},
error: function (xhr, status, error) {
console.log(status)
console.log(error)
console.log(xhr)
}
});
}
document.getElementById('addLMS1').onclick = addLMSPerson;
}
}
})();

Suggestion: Some kind of user notification/indicator of success/error.

Let me know if you have any questions, happy to help.

View solution in original post

0 Kudos
5 Replies
robotcars
Community Champion

Hi  @haceved5 

First, I'd like to warn that enrolling students as a teacher aid could be a huge FERPA violation if that role allows students to access other students information, grades, profile, and submissions. You might want to evaluate that, change permissions, create a different role, or find a new solution. 

Several things bubble to the top for improvement:

  • Steer away from using the URI (window.location.pathname) and parts to attain values (course_id). You've already used the ENV provided in pages. There's more there, checkout ENV in the console. ENV.COURSE_ID, which can have inconsistencies depending on the page the user is on.
  • Try to use Regular Expressions to limit your Theme hacks to the page you want them to execute on. I'll share one for this below.
  • While the #right-side-wrapper seems to be consistent on most pages, it is empty on several pages within the course navigation. Link Navigator only exists on the Settings page. Are you expecting to only see these links there?
  • Clicking 1 of the 3 LMS Support buttons fires incorrectly. GlobalEventHandlers.onclick - Web APIs | MDN takes a function reference, not a function. So change that to 
    document.getElementById("addLMS1").onclick = addLMSPerson1;
  • The href for the LMS button are '.', which when clicked, the browser follows , ignoring your click event. Change this to something like a hashtag href="#", which the browser recognizes are part of the page, or href="javascript:void();" or href="return false", which tells the browser to do nothing, which will let your callback execute.
  • The jQuery post makes it hard to troubleshoot or do any error handling, without building your own logic. I've change that to use $.ajax with a success and error callback. These come in useful when working in the Browser Console, see Developer Tools for the Canvas User 

I've reduced the code a bit to make it more readable or concise. Looking at the code, you added 3 buttons, without a Modal (little window for adding additional info, or a dialog box). Are you expecting to enroll the same 3 users, 1 for each button, or allow the Teacher to pick names? If it's the same 3 users, we can probably add them with 1 button. But this leaves the user's CanvasID exposed in your publicly accessible javascript, which isn't a good thing. Either way, we could reduce the code to execute all 3 onclick, or pass the userid to a single function for each button.

Here's a revised version, working in the new Firefox... actually I only test there. :smileyshocked:

This version will enroll You (self) as the TA, for testing. You can change the user_id.

// https://community.canvaslms.com/thread/49469-enroll-user-via-theme-edit

(function () {
if (/^\/courses\/\d+\/settings/.test(window.location.pathname)) {

if (ENV['current_user_roles'].includes('teacher')) {

$('.validator_link').after('<a class="Button Button--link Button--link--has-divider Button--course-settings" href="undelete"><i class="icon-trash"></i> Undelete Content</a>');

$('.validator_link').after('<a class="Button Button--link Button--link--has-divider Button--course-settings" href="#" id="addLMS1"><i class="icon-user"></i> LMS Support #1</a>');

function addLMSPerson() {

$.ajax({
type: 'POST',
url: `/api/v1/courses/${ENV.COURSE_ID}/enrollments`,
data: {
'enrollment': {
'user_id': 'self',
'type': 'TaEnrollment',
'role_id': 1936 //23
}
},
success: function (r) {
console.log(r)
},
error: function (xhr, status, error) {
console.log(status)
console.log(error)
console.log(xhr)
}
});
}
document.getElementById('addLMS1').onclick = addLMSPerson;
}
}
})();

Suggestion: Some kind of user notification/indicator of success/error.

Let me know if you have any questions, happy to help.

View solution in original post

0 Kudos
robotcars
Community Champion

Forgot to switch the role_id back to 23.

robotcars
Community Champion

One more thing... took me a bit to remember why I recognized your name. You forked ccsd/ledbelly. Would love to talk about how you're using it, or how it can be improved. Let me know if you have some time to chat.

haceved5
Community Participant

Hello Robert,

Thank you for the detailed post. Yes, we are only expecting the buttons on the settings page. The three buttons are for three different people and instructors would click on the one corresponding to the person they are talking to. I was able to modify your code and add a parameter to the function.

I was interested in working with SQS to improve some processes we run at our campus. I wasn't able to get any of that infrastructure set-up, so I ultimately didn't end up using it.

I will work on something to provide a notification for success.

Thank you again for the great help.

-Henry

robotcars
Community Champion

A green fade or something on the button would be quick. What if the user is already enrolled, could it use a lookup to hide the button if it's already been done, or show the status of the enrollment?

Live Events/SQS is proving to be pretty useful for us in getting new data and creating/changing processes. I'm currently working on setting up a New Student Orientation process using course_completed to release SIS enrollments after the student completes Orientation. LE makes this happen with 1-2 second latency instead of having to schedule an API task to look up new submissions.