After an outage on September 1, the Instructure Community is now fully available, including guides, release notes, forums, and groups. If some styling still looks unusual, clear your cache and cookies.
Found this content helpful? Log in or sign up to leave a like!
I am a Canvas LMS manager at my company and we are creating NPS forms for courses. This form the student will be able to vote from 0 to 10 and give a justification of his vote, this is the only information he inserts. We also want some information about the student, such as name, ID, course and among others that he does not need to fill in, but rather access this type of information through the API. This form would be an HTML within the course that is downloaded by an iframe within a course page.
The way we are doing it today is a javascript function that is loaded by the js file that is inside the subaccount theme. This is the code that is inside the js file of the subaccount theme, the user is the object that the API call returns and the user.id would be the user ID of the session. This is already working
function getId() {
$.getJSON("/api/v1/users/self?include[]=uuid", "keys=id", function (data) {
var user = data;
console.log(user.id);
window.onload = function () {
var frame = document.getElementById('M3').contentWindow;
frame.postMessage(user.id, "*");
}
});
}
Is there any way I can access thus user.id in an HTML file loaded by an iframe inside a course page, so that the form can read and send this information to the answer sheet?
I may be missing something here or perhaps reading more into what you're writing than you're meaning to say.
If you know about postMessage and you say it's working, then you probably know how to access the data within the iframe as well (otherwise, how would you know it's working?). Just in case you are not aware, in the HTML loaded in the IFrame, you would need JavaScript to add an eventListener that listens for the "message" event. The documentation on window.postMessage provides an explanation and examples of how to do this. That same JavaScript could then modify the DOM to change what is displayed or use the variable to complete the form. It cannot be done with straight HTML, you would need to use JavaScript.
What you're describing seems like a great use for an external tool (LTI). You can pass those the ID and other values as variables in the request and provide enhanced security over the postMessage method.
Hello,
@James
So the best solution would be inside the HTML file being loaded by IFrame, use a Window.postMessage() that makes an API call and returns the values ?
That is the opposite of what I said. I don't even think what you wrote is possible. IFrames are sandboxed and don't have access to APIs. Perhaps they would be if you're storing the HTML in the files section of Canvas rather than on an external server (I would discourage that approach),
The iFrame would not have access to the API to make the call. The code that you inject into the custom JavaScript would have to have the postMessage. Your iFrame HTML would have to have its own JavaScript that would have an eventListener for the "message" event type to listen for the message sent by the postMessage sent from the parent frame and then act on it.
As for the best method, I would not go that far. I think the best method is probably to use an external tool or LTI, but there are cases where that isn't going to work for people. But with an external LTI, Canvas can pass all of the information that you need to pass to the external tool and then it can act on it and deliver the content.
An LTI is not the easiest way (easiest is different from best). My solution was based off of what you had written that you already had working. My confusion was why you would be using postMessage in the first place if you didn't know about the eventListener so that you could use it?
Canvas has an eventListener for messages coming from LTIs. It allows you to request a full window launch, toggle the course navigation menu, hide the right side wrapper, resize the iframe, get the window size, show the module navigation, scroll to the top of the page, show an alert for screen readers, show an alert using the Canvas system, enable scroll events, and a couple of others.
Some of those require a token that is sent during the LTI launch, but others could be used by JavaScript acting within an iFrame. However, most of those are probably not things that you need, so if you were to do it the way you wrote and try to post a message from the iframe to the parent frame by adding an event listener in the custom JavaScript and the postMessage in the JavaScript within an iframe, you would want to make sure that the events bubble back to Canvas' handler so you didn't break other things. It's much saner to add the postMessage in the global JavaScript and the event listener in the JavaScript within your HTML file.
To interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign inTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign in