Hi all. I have been meaning to pull this together to share for quite awhile but better late than never. I have done a some playing with custom CSS and JavaScript on the mobile app but am far from knowing everything I would like to know and debugging the mobile app has been an absolute pain so any suggestions would be appreciated.
There are a few things you should know before I share some code:
- I couldn't stand that jQuery was not available so I worked up some code to add it to the app (The code below is also configured to pull in jQuery UI).
- The Mobile App CSS and JavaScript have been known to make an appearance in the browser version of Canvas which can cause chaos.
- I have adapted the code pasted here from code I developed for Design Tools for Canvas but I believe I have all of the essentials here.
Okay, that being said, lets look at some code. This is what you can upload to Canvas to load jQuery before processing your code:
(function () {
function loadScript(url, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("https://code.jquery.com/jquery-1.9.1.min.js", function () {
loadScript("https://code.jquery.com/ui/1.11.3/jquery-ui.min.js", function () {
});
});
})();
I have been using this code for a few years and it loads jQuery version 1.9.1. I just checked and Canvas loads version 1.7.2 into the browser but I have not noticed any issues from that difference.
Another thing that you should know is that I hate having to continually upload files into the theme editor. Because of that, I actually keep the code above in a file on an external server and upload a variation to Canvas that loads the external file. It looks something like this:
(function () {
function loadScript(url, scriptID, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.id = scriptID;
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
var today = new Date(),
appScript = document.getElementById('inst_app_script');
if (appScript === null && window.jQuery === undefined) {
loadScript("https://<path to js file>?" + today.getDate(), 'inst_app_script', function () {
console.log('Global App JavaScript Ran');
});
}
})();
The script is given an id that can be checked to make sure doesn't get added more than once. It also looks to make sure jQuery isn't already defined, this helps prevent the code from running in the browser if it somehow finds its way there. There was an issue in the past where Canvas loaded the mobile app assets twice for every discussion response in the browser. It made Canvas discussions that had more than a couple of posts pretty much unusable. I also add a little code in the browser JavaScript to remove the app stylesheet if it ever appears.
A few other thoughts that I can share that might be helpful (or might be out of date).
- Canvas urls do not function the same in the app. As far as I can tell, the url for every piece of content returns as <inst>.instructure.com. This makes it very hard to identify a particular course or piece of content.
- None of the default Canvas CSS is loaded into the app so you will need to recreate any components you hope to use and have match.
- I have been unable to figure out how to make API calls from the mobile app. I use ajax to make calls in the browser but was never able to get that to work in the app.
- Debugging in the app is a pain, but here are a few things I have tried (typically using a subaccount where the code won't run for anyone else):
- Use a try catch statement to alert me of errors
try {
} catch (err) {
alert(err);
}
- I will also through in a textarea to help me see what is going on in the app. I would love a better solution if anyone has one. The following will dump all of the html into the created text area. I can then copy it and past it into something I can access from the desktop.
$('body').prepend('<textarea id="fillMe" style="width:50%;height:50px; margin:auto;"></textarea>');
$('#fillMe').val($('html').html());
Anyway, those are the approaches that I can think of that I have used to work with the mobile app that might be helpful. I have not been able to dedicate as much time as I would like to try and figure things out. This has just helped me get some of the essentials working.