Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
I'm trying to keep track of the new UI and what needs to change in our js file. So far it looks like the course enrollment role detection is broken. It's no longer listed in the Nav menu. This was the old js code that we found somewhere.
function isRole(srole){
if (jQuery("[data-id = " + ENV.course.id +"]").children().children("span.subtitle").not("span.enrollment_term").text() == "Enrolled as: " + srole)
{
return true;
}
else
{
return false;
}
}
Did someone find it elsewhere? It doesn't look like it's in ENV either.
Has anyone found any other problem areas?
It also doesn't appear to load our custom css file. It's in the root account settings, but it's not loading at all. Is anyone else seeing this? Can we no longer load a custom css?
Hey @anf107 - I am having this same issue. We have extensively used our CSS in our instance and I needed to evaluate the impact of this new UI update. As a short term (not production worthy) solution, I have inserted the CSS using a little jQuery in our global JS, which is loading.
Something to get you going for now until Canvas resolves this:
$('head').append('<link href="yourCss.css" rel="stylesheet" type="text/css">');
It seems to be working now. In the new Theme Editor, you can upload your custom CSS file. Unfortunately, you can no longer specify a reference link to your CSS file. It's uploaded and hosted on their server, which isn't very good for managed code or automated development process. The solution I settled on was to create an "CSS importer". The CSS file we upload has just an @import statement and points to the CDN where we host our code and styles. For example:
CanvasExtensionsImporter.css
@import url("https://vision.calverteducation.com/canvas-extensions/CanvasExtensions.css")
Thanks for this great tip. Do you know if there is a similar way of doing it with javascript?
Hi Erlend,
the js equivalent to css importer would be jquery getScript
See this post by @nhayward - Re: Option for self hosted custom CSS and JavaScript
hope that helps!
For some reason (got deleted, flagged, not sure) the link above to Nick Hayward's post just displays "Unauthorized
(This place or content does not exist or access to it is restricted. If you think this is a mistake, please contact your administrator or the person who directed you here.)"
@phanley , Nick's post was made to a user group that has long since served its purpose, so it was retired and is now "closed." Here's the text of his post from December 2015:
Thanks for the info on this. I realize this post is a few months old, but I wanted to post my thoughts. I've been using a similar approach with a few tweaks to avoid choppiness once my CSS and JS kick in. I append a link tag for my CSS into the head and use getScript to pull in my JS as mentioned above. Here's where it gets fun. I have a small CSS file uploaded into the theme editor that merely sets the opacity of the page content to 0. Then within my getScript I have a callback function that animates the opacity to 1 to fade in the content (the fade is unnecessary, I just like it). Here it is in code form:
CSS uploaded to theme editor:
.ic-app-main-layout-horizontal {
opacity: 0;
}
JS uploaded to theme editor:
$('head').append('<link rel="stylesheet" type="text/css" ' +
'href="path/to/my.css"></link>');
$.getScript("path/to/my.js", function() {
setTimeout(function() {
$('.ic-app-main-layout-horizontal').animate({opacity: 1}, 500);
}, 500);
});
The setTimeout function within the getScript serves to get rid of choppiness. I essentially just give it an extra half second for everything to get loaded in. Without that timeout I was seeing an initial flash of unstyled content before my CSS was applied.
I have a feature request that is currently open for voting to allow us to add urls again
For now the above code is working well for my needs. I hope this proves useful!
Yes. With JavaScript, it's even better because I can detect the environment at runtime and then inject the appropriate code vs. having to remember to upload the appropriate "css importer". There is a little more code that runs during setup to do the environment detection, differentiating between my local instance of canvas, our dev instance, test, and then of course the production instance, but the final step is the most important and easy.
Something like this (I use ES2015 syntax and transpile with Babel to ES5):
AppInjector.js:
injectScript(scriptUrl) {
console.log('%s: START-Inject: %s', this.cid, scriptUrl);
let thisObj = this;
let head = document.getElementsByTagName('head')[0];
let script = document.createElement('script');
script.setAttribute('data-id', 'app');
script.type = 'text/javascript';
script.src = scriptUrl;
script.onload = function() {
console.log('%s: COMPLETE-Inject: %s', thisObj.cid, scriptUrl);
};
script.onerror = function() {
console.log('%s: ERROR-Inject: %s', thisObj.cid, scriptUrl);
};
head.appendChild(script);
}
Hey Michael,
This is spot on but those dozen plus lines of code accomplish the same as $.getScript() and while I am always a fan of not pulling in jQuery if it is not necessary, Canvas already pulls it in so you might as well use it.
$.getScript("scriptUrl.js")
That is all.
And there are callback functions to inform success and error if you want a descriptive log.
Matthew
It looks like you are all heavily into tweaking Canvas with CSS and JS. We've made our custom design with these two files:
https://matematikk-mooc.github.io/frontend/mmooc-min.js
https://matematikk-mooc.github.io/frontend/mmooc-min.css
If you are interested in using the code you can read how it is made here:
GitHub - matematikk-mooc/frontend: Custom JS and CSS frontend for inclusion in Canvas
There are probably some hardcoded strings in Norwegian, but they should be fairly easy to find and change. Here is a snapshot of what it looks like:
PS. This design will partly break down with the new inrevokable Canvas UI July 9th. We're looking into whether we're going to update the design or just stay with the current Canvas version (we're running open source).
@ @mwhite
Thanks for the tip.
I did come across $.getScript() when I first started looking into how we could improve our workflow, but wasn't sure how jQuery implemented it (via XMLHTTPRequest or through script tag injection). Plus, we saw that the new Canvas UI was bundling jquery, which introduce more uncertainty. Even though we could tell which version they were using, we decided the safest route was to minimize dependencies on Canvas includes, especially on the critical bootstrapping code. It did turn into a few more lines of code, but it's pretty basic, well insulated from Canvas or jQuery changes, and easier to handle in our test runner.
Thanks for the reminder though, I'll definitely look into it some more. Less code, is good code.
I was just reviewing the thread and noting that Matthews approach to handling the CSS is essentially the same approach I use for JavaScript. However, the reason I prefer the @import for CSS instead of injecting it into the head is because @import caused the browser to wait before rendering. So our overrides get applied immediately. When injecting with code there is a perceivable delay in rendering of those overrides.
This is totally valid, and it is due to the DOM structure of Canvas.
Canvas puts the <link> tags to the custom css in the head, so the @url executes before the browser has even start to load the DOM...
Whereas the script tags are near the end of the DOM structure, therefore the browser doesn't read them and therefore doesn't request your css file until after the DOM has loaded on the screen. Thereby creating the perceivable delay.
Great point Michael.
Yeah, it's also leveraging the behavior of the @import. Both AppInjector.js and our *CSSImporter.css's introduce delays on the initial load. The @import blocking until our external CSS is loaded and then AppInjector.js is loaded via Canvas's RequireJS. Then AppInjector.js loads our real Canvas extension code. All combined, on the initial startup, it causes more delay than I like.
I'm a little worried about the upload technique as a whole, and wish that Canvas provided the option to either upload the CSS and JavaScript or specify references to it as it used to do. For small extensions the upload is ok and working fine now, but with larger revisions the references were easier to manage and faster for us. Uploading code sets an opportunity for Canvas to parse and then limit what can be overridden. I actually found note about that in recent Canvas documentation stating that we may do "limited JavaScript". For example, if Canvas removed XMLHTTPRequest, getScript, or @import from uploaded code it would severely limit our ability to extend the environment. We talked with Instructure about it and were told that there were no limits. So, I guess the original problem was just a bug, but still worrisome.
I wholly agree with this. If Canvas removed xhr request, that would not be a good thing for our code base.
To reduce the loading delays, we actually remove our getScript and @import in production and upload a compiled version of our JS and CSS; we only use them for dev when we are working on our js/css files. Uploading them each time to Canvas would explode my brain!
One technique I have used to smooth the delays out, or at least hide the glitchy-ness from the user is MutuationObservers. This is good and bad, cause essentially this means that I am setting opacity to 0 on certain elements in my css, and then once my JS has done its job, I will fade them in. We use this when we are interacting directly with the DOM - adding / removing / modifying things.
Hopefully they will return the ability to self host js and css files.
Have to say, it's nice to meet ya. Good to find other folks working on extensions at this level.
Our company committed to Canvas about a year and a half ago, and it's been as rewarding as challenging at times. The biggest selling point for our development team at the time was the Canvas API. We've built a stand-alone app for part of our customer base, and give our other school users access to the full version of Canvas, but everyone needs access to the same content and same data collection.
Thanks for the tips!
For what it's worth there is a similar conversation going on here: Branding/customization and the new Canvas UX and here: (which you've posted in @anf107 ) InstructureCon Release Notes (2015-06-17).
To participate in the Instructure Community, you need to sign up or log in:
Sign In