cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
akinsey
Community Contributor

Custom JavaScript/CSS Changes

Jump to solution

Hello all,

Question. Over the weekend there was a Canvas Production Release. In the notes, it mentions undocumented changes to the CSS/Javascript. It seems that those changes have broken our Resources Tab, specifically the slide out menu. We've tried rewriting the code, and even used the code found here as a basis: canvas-contrib/Branding/JS_and_CSS/react-tray-link at master · kajigga/canvas-contrib · GitHub 

Has anyone else had this issue or have any thoughts/ideas as to what has changed?

Thanks!

4 Solutions
ryan
Instructure
Instructure

Hey Everyone,


I'm an Engineer that works on canvas and I wanted to help clear up what changed and how to fix it going forward here so I made a quick screencast.

Basically the issue was that we used to use a JavaScript library we created called "ReactTray" which was a precursor to the one we officially added to InstructureUI. The latter is better because it fixes a bunch of bugs, has better screenreader and Right-to-Left language support and there was no point in loading 2 tray javascript libraries on the page since all of the other trays we use in canvas are all already using the InstructureUI one.

but the good news is that you really shouldn't have to use custom JavaScript or CSS to make custom help links,  or to change the help menu's name and icon.  those are all things that are officially supported right in the canvas UI. just click the "Customize this menu" link at the bottom of the tray when it pops open and it will take you to an account settings page where you can create as many custom links as you'd like (see screencast).

And even if you want to add some kind of custom JavaScript behavior when you click on one of those links you can use the officially supported way to add them and add something like this to your custom JavaScript file to handle clicking on them (also see screencast):

// this is not supported by Instructure, I'm just providing it as a reference in case it is helpful
// Replace "http://example.com/test" in the selector with whatever url you use in the link you want to add custom behavior to
$(document.body).on('click', '#help_tray a[href="http://example.com/test"]', function(event) {
event.preventDefault()
alert('do something special')
})‍‍‍‍‍‍‍

Hopefully that helps clear things up. If there is anything any of you are needing that is not possible ‍‍‍‍using the officially supported way of adding custom links, we'd be interested to hear what you are doing. The hope in creating that feature was that there wouldn't be an need to use custom JS for that anymore and that people could do the same thing in a way that was easier, less-brittle, and officially supported.

PS:  I just want to add another reminder to people that are using a Custom JavaScript override file that those modifications are not officially supported and that you should make sure to check beta before every release to make sure your stuff is going to work when it goes to production.

View solution in original post

robotcars
Community Champion

Are you using an Instructure icon or a custom svg?

View solution in original post

0 Kudos
qnguyen
Community Contributor

Hi,

I am using Instructure icon but need to be as big as others. I used the code you sent starting with icon-xxxx

  addMenuItem('Training Course', 'https://edu.instructure.com/courses/123', 'icon-certified', '_blank');

View solution in original post

0 Kudos
robotcars
Community Champion

I'm looking into it.

The icon in your screenshot isn't the icon-certified.

Are you loading any other custom css or javascript?

View solution in original post

0 Kudos
55 Replies
robotcars
Community Champion

I took a stab at the linked code, it seems on line 105 .ReactTrayPortal no longer exists.

$('.ReactTrayPortal div').append(trayHtml);‍‍

$('.ReactTrayPortal').length // result = 0

Changing it to the following, allowed the slider to show me the list of links.

$('#menu').append(trayHtml);‍‍

Not sure if it's a complete solution, but it might get you started.

I have some code that appends content after .ic-NavMenu__link-list, when I came in yesterday it's now ._2j92CzO._17Ovwhm._1eZWDls :smileyconfused:

akinsey
Community Contributor

Thanks, carroll-ccsd‌. We just tried this and now it is still not working. It seems to be a class error...

0 Kudos
robotcars
Community Champion

How different is your code from the example, would you be willing to post it?

0 Kudos
akinsey
Community Contributor

We originally had this: $('.ReactTrayPortal div').append(trayHtml);

Then we changed it to $('#menu').append(trayHtml); with no change.

0 Kudos
robotcars
Community Champion

Alan,

I don't seem to have enough knowledge of React to make this work at the moment. When a menu item with a tray is clicked a <span> with no ID or CLASS attribute is appended to <div id="main" class="ic-Layout-columns">, when I try to append similar content, nothing shows up. I feel like Canvas left us without an HTML element to drop the content into, which used to be .ReactTrayPortal div. Multiple events in the contrib code point to this DIV, which doesn't exist.

I want to finish up a project I'm working on, and then I may try to play with this later in the week. Maybe someone else will have better luck.

akinsey
Community Contributor

Thanks! We're going to keep looking as well. A short-term solution is just to add our needed links into the Help Menu, but I definitely feel changes like this need to be put in the release notes documentation.

robotcars
Community Champion

Agreed...

Also, I typically check all our customization and hacks against beta before they release to production. In this case I think it would have been helpful, because you could compare old to new, and try and swap out the classes/html structure, the primary difficulty being I couldn't exactly tell what changed.


// THIS IS NOT SUPPORTED BY INSTRUCTURE, WORKS as of 12-4-15
$(document).ready(function() {
    if(ENV.current_user_roles.indexOf('teacher') >= 0 || ENV.current_user_roles.indexOf('admin') >= 0){
        //items to show to teachers and admins
        var trayLinks = [
            {key: 'https://msmelo2.squarespace.com/', val: 'MS MELO'},
            {key: 'https://msvcc2.squarespace.com/facultyresources/', val: 'Faculty Resources'},
{key: 'https://sbcjcweb.sbcjc.cc.ms.us/ET/EThome.aspx', val: 'Enrollment Tool'},
{key: 'http://www.holmescc.edu', val: 'HolmesCC'}
        ];
    } else if (ENV.current_user_roles.indexOf('student') >= 0) {
        //items to show to students
        var trayLinks = [
            {key: 'https://msmelo2.squarespace.com/', val: 'MS MELO'},
            {key: 'https://msvcc2.squarespace.com/student/', val: 'Student Resources'},
{key: 'https://sbcjcweb.sbcjc.cc.ms.us/ET/EThome.aspx', val: 'Enrollment Tool'},
{key: 'http://www.holmescc.edu', val: 'HolmesCC'}
        ];
    } else {
        //items to show to people who are not teachers, students or admins
        var trayLinks = [
            {key: 'https://msmelo2.squarespace.com/', val: 'MS MELO'},
            {key: 'https://msvcc2.squarespace.com/student/', val: 'Student Resources'},
{key: 'https://sbcjcweb.sbcjc.cc.ms.us/ET/EThome.aspx', val: 'Enrollment Tool'},
{key: 'http://www.holmescc.edu', val: 'HolmesCC'}
        ];
    }

    var slide_out_title = "Resources" //Changes the title on the slide out menu
    var global_nav_name = "Resources" //Change the title on the global navigation menu

    var footerContent = ''; //Changes the text of the bottom on the slide out tray
    ////////////////////////////////////////////////////////////////////////////////
    //DO NOT EDIT ANYTHING BELOW THIS LINE!
    ////////////////////////////////////////////////////////////////////////////////

    //Browser Detection
    navigator.agentDetect = (function(){
     var ua= navigator.userAgent, tem,
     M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
     if(/trident/i.test(M[1])){
     tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
     return 'IE '+(tem[1] || '');
     }
     if(M[1]=== 'Chrome'){
     tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
     if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
     }
     M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
     if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
     return M;
    })();

    //Array, 0 = browser, 1 = version
    var agent = navigator.agentDetect;
    var reactId;

    switch(agent[0]) {
     case "Firefox":
     reactId = "2";
     break;
     case "Safari":
     reactId = "2";
     break;
     default:
     reactId = "1";
     break;
    }

    var displayVals = '';

    function displayLinks(element, index, array) {
        displayVals += '<li>';
        displayVals += '<a href="' + element.key + '">' + element.val + '</a>';
        displayVals += '</li>';
    }

    trayLinks.forEach(displayLinks);

    var trayHtml = '<div style="position:absolute;background:#fff;" class="ReactTray__Content ReactTray__Content--after-open " tabindex="-1" data-reactid=".' +
reactId + '.0"><div class="ReactTray__layout" data-reactid=".' +
reactId + '.0.0"><div class="ReactTray__primary-content" data-reactid=".' +
reactId + '.0.0.0"><div class="ReactTray__header" data-reactid=".' +
reactId + '.0.0.0.0"><h1 class="ReactTray__headline" data-reactid=".' +
reactId + '.0.0.0.0.0">' +
slide_out_title + '</h1><button class="Button Button--icon-action ReactTray__closeBtn" type="button" data-reactid=".' +
reactId + '.0.0.0.0.1"><i class="icon-x" data-reactid=".' +
reactId + '.0.0.0.0.1.0"></i><span class="screenreader-only" data-reactid=".' +
reactId + '.0.0.0.0.1.1">Close</span></button></div><ul class="ReactTray__link-list" data-reactid=".' +
reactId + '.0.0.0.1">' +
displayVals + '</ul></div><div class="ReactTray__secondary-content" data-reactid=".' +
reactId + '.0.0.1"><div class="ReactTray__info-box" data-reactid=".' +
reactId + '.0.0.1.0">' +
footerContent + '</div></div></div></div>' +
'<script>$(\'.Button.Button--icon-action.ReactTray__closeBtn, .Button.Button--icon-action.ReactTray__closeBtn .icon-x\').click(function () {$(\'.ReactTrayPortal div\').removeAttr(\'style\');$(\'.ReactTrayPortal div\').removeAttr(\'class\');$(\'.ReactTrayPortal div\').html("");$(\'#menu, .menu-item.ic-app-header__menu-list-item a\').removeClass(\'ui-state-disabled\').removeAttr(\'disabled\');$(\'#customTrayOverlay\').hide();$(\'#custom_nav\').css(\'background-color\', \'\');$(\'.icon-resources\').css(\'color\', \'#fff\');});</script>';

    trayHtml = trayHtml.replace(/(?:\r\n|\r|\n| )/g, '');

    var menu = $('#menu');
    if (!menu.length) return;
    var custom_nav = $('<li/>', {
        'id': 'custom_nav',
        'class': 'menu-item ic-app-header__menu-list-item',
        html: '<a id="global_nav_resources_link" href="javascript:void(0)" class="ic-app-header__menu-list-link">' +
        '<div class="menu-item-icon-container" aria-hidden="true">' +
        '<i class="icon-resources"></i>' +
        '<div class="menu-item__text">' + global_nav_name + '</div>' +
        '</div></a></li>'
    });

    menu.append(custom_nav);

    $('body').append('<div id="customTrayOverlay" style="width:' + $('#menu').width() + 'px;height: ' + $('#menu').height() + 'px;position: absolute;left: 0;top: 87px;z-index: 999;display:none;"></div>');

    $('#global_nav_resources_link').click(function () {
        $('.ReactTrayPortal div').addClass('ReactTray__Overlay ReactTray__Overlay--after-open');
        $('.ReactTrayPortal div').css({
            'position' : 'fixed',
            'top' : '0px',
            'left': '0px',
            'right' : '0px',
            'bottom': '0px'
        });

        $('.ReactTrayPortal div').append(trayHtml);
        $('#menu, .menu-item.ic-app-header__menu-list-item a').addClass('ui-state-disabled').attr('disabled', 'disabled');
        $('#customTrayOverlay').show();
        $('#custom_nav').css('background-color', '#fff');

    });
});

I know most of the people on this thread have already re-worked your javascript by now, but I thought this might be helpful to the conversation.

One thing that I've found helpful with custom Global Navigation items is to add them as a fake LTI tool so the item population in the Global Navigation is taken care of by Canvas. This has the benefit of removing the delay of the menu item being added on each page load. You can do this easily by adding a custom LTI by slightly modifying the below XML (adjust the urls to point to one of your institution's websites that will return a page with a 404 Not Found page incase Javascript overrides aren't working for the user). 

Note: The following XML adds a Global Nav icon like the image on the right. It is only visible to Admins and Teachers. Remove line 28 to let all users see the item. And if you want to change the icon, replace the SVG path on line 21. Also customize the navigation item text by editing lines 23 & 24

272504_pastedImage_2.png

<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0" xmlns:blti="http://www.imsglobal.org/xsd/imsbasiclti_v1p0" xmlns:lticm="http://www.imsglobal.org/xsd/imslticm_v1p0" xmlns:lticp="http://www.imsglobal.org/xsd/imslticp_v1p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
<blti:title>PD Catalog</blti:title>
<blti:description>
Add links to external web resources that show up as navigation items in course, user or account navigation. Whatever URL you specify is loaded within the content pane when users click the link.
</blti:description>
<blti:launch_url>https://yourUrlHere</blti:launch_url>
<blti:custom>
<lticm:property name="new_tab">1</lticm:property>
<lticm:property name="url">https://yourUrlHere</lticm:property>
</blti:custom>
<blti:extensions platform="canvas.instructure.com">
<lticm:property name="icon_url">
https://www.edu-apps.org/assets/lti_redirect_engine/redirect_icon.png
</lticm:property>
<lticm:property name="link_text"/>
<lticm:property name="privacy_level">anonymous</lticm:property>
<lticm:property name="tool_id">redirect</lticm:property>
<lticm:options name="global_navigation">
<lticm:property name="display_type">full_width</lticm:property>
<lticm:property name="icon_svg_path_64">
M23.5,58.83H5.5a4.48,4.48,0,0,1-4.4-4.54V5.53A4.47,4.47,0,0,1,5.5,1H51.32a4.48,4.48,0,0,1,4.4,4.54V24h-4.4V5.53L5.5,5.39v48.9l18,.14v4.4ZM11.84,11.68H42.79v4.4H11.84v-4.4Zm0,10.69H36.79v4.4H11.84Zm0,10.69H28.59v4.4H11.84Zm0,10.69H28.59v4.4H11.84ZM62.76,56.52,56.1,44.11a12.57,12.57,0,1,0-22.94,0L26.39,56.37A1.14,1.14,0,0,0,27.64,58l5.74-1.3,1.94,5.48a1.15,1.15,0,0,0,1,.76h.09a1.14,1.14,0,0,0,1-.6l5.92-10.93a11.63,11.63,0,0,0,1.25.13c.39,0,.76-.08,1.15-.11l6,11a1.12,1.12,0,0,0,1,.6h.09a1.15,1.15,0,0,0,1-.74l2-5.46,5.73,1.33a1.15,1.15,0,0,0,1.28-1.65ZM36.35,55l-.71-2a.56.56,0,0,0-.67-.37l-2.13.48,3-5.42A12.24,12.24,0,0,0,39.12,50Zm8.23-8a8,8,0,1,1,8.05-8A8,8,0,0,1,44.58,47Zm9.84,6.5a.68.68,0,0,0-.79.43l-.85,2.38-3.23-5.95a14.76,14.76,0,0,0,3.85-2.7l3.54,6.41Z" transform="translate(-1.1 -1)
</lticm:property>
<lticm:property name="text">PD Catalog</lticm:property>
<lticm:property name="label">PD Catalog</lticm:property>
<lticm:property name="url">
https://yourUrlHere
</lticm:property>
<lticm:property name="visibility">admins</lticm:property>
</lticm:options>
</blti:extensions>
</cartridge_basiclti_link>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I then use the following javascript to find it and replace the global nav code with whatever I want. I haven't done this with the slide out tray, but it should work and avoid you having to rely on element classes and id's of items in the global nav. Instead it just relies on the global launch url (which is less likely to change than an id or class).

Note: This particular script only modifies the PD Catalog LTI Global Navigation item for Admins and Teachers as the LTI is managing the permissions for the tool. It takes users to Canvas Network.

  1. Remove lines 12 and 23 to make the script modify the LTI url for all users if you want.
  2. Replace the url on line 18 with the native global launch url from the LTI tool from your institution's Canvas site.
  3. Update the ID selector on lines 15, 16, and 20.
  4. Customize the code for the variable portal link on line 19. 
var fixGlobalNavURL = function() {
    function onElementRendered(selector, cb, _attempts) {
        var el = $(selector);
        _attempts = ++_attempts || 1;
        if (el.length) return cb(el);
        if (_attempts == 100) return;
        setTimeout(function () {
            onElementRendered(selector, cb, _attempts);
        }, 50);
    };

    if (ENV['current_user_roles'].indexOf('admin') > -1 || ENV['current_user_roles'].indexOf('teacher') > -1) {
        // START - Change URL of PD Catalog LTI

        onElementRendered('#context_external_tool_132_menu_item', function () {
            global_nav_link = document.querySelector("#context_external_tool_132_menu_item > a").href;

            if (global_nav_link === "https://jperkins.instructure.com/accounts/1/external_tools/132?launch_type=global_navigation") {
                var portal_link = $('<li id="context_external_tool_132_menu_item" class="menu-item ic-app-header__menu-list-item"> <a class="ic-app-header__menu-list-link" target="_blank" rel="noopener noreferrer" href="https://www.canvas.net"> <svg version="1.1" class="ic-icon-svg ic-icon-svg--lti menu-item__icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64 64"> <path d="M23.5,58.83H5.5a4.48,4.48,0,0,1-4.4-4.54V5.53A4.47,4.47,0,0,1,5.5,1H51.32a4.48,4.48,0,0,1,4.4,4.54V24h-4.4V5.53L5.5,5.39v48.9l18,.14v4.4ZM11.84,11.68H42.79v4.4H11.84v-4.4Zm0,10.69H36.79v4.4H11.84Zm0,10.69H28.59v4.4H11.84Zm0,10.69H28.59v4.4H11.84ZM62.76,56.52,56.1,44.11a12.57,12.57,0,1,0-22.94,0L26.39,56.37A1.14,1.14,0,0,0,27.64,58l5.74-1.3,1.94,5.48a1.15,1.15,0,0,0,1,.76h.09a1.14,1.14,0,0,0,1-.6l5.92-10.93a11.63,11.63,0,0,0,1.25.13c.39,0,.76-.08,1.15-.11l6,11a1.12,1.12,0,0,0,1,.6h.09a1.15,1.15,0,0,0,1-.74l2-5.46,5.73,1.33a1.15,1.15,0,0,0,1.28-1.65ZM36.35,55l-.71-2a.56.56,0,0,0-.67-.37l-2.13.48,3-5.42A12.24,12.24,0,0,0,39.12,50Zm8.23-8a8,8,0,1,1,8.05-8A8,8,0,0,1,44.58,47Zm9.84,6.5a.68.68,0,0,0-.79.43l-.85,2.38-3.23-5.95a14.76,14.76,0,0,0,3.85-2.7l3.54,6.41Z&quot; transform=&quot;translate(-1.1 -1)"></path> </svg> <div class="menu-item__text"> PD Catalog </div></a></li>');
                $('#context_external_tool_132_menu_item').replaceWith(portal_link); //
            };
        });
    };
};

$(document).ready(function () {
    fixGlobalNavURL();
});
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Disclaimer: And like all custom javascript, THIS IS NOT SUPPORTED BY INSTRUCTURE. But if you want to use it at your own risk you may.

themidiman
Community Champion

Thanks for posting the global nav customization code,  @jperkins 

This gives me food for thought on how to improve what we already have if we wanted to go outside the bounds of the instruction icon set. SVG is awesome!

I had a question about what line in your LTI XML config code is the "global launch url". Is it line 6 or line 9? 

I have the full destination url on lines 6, 9 and 26. Anywhere it says "https://yourUrlHere" in the xml file. Pretty sure it isn't necessary in all places to work, but I haven't spent the time to dig any deeper. 

msl_adm
Community Contributor

Thanks  @jperkins  for this. That's an interesting way to deal with this issue, and I'll have to file that away for later.

0 Kudos

That is AWESOME!!! Love your work  @jperkins ‌!

akinsey
Community Contributor

So. After a lot of blood, sweat, and tears, we've figured it out. The "undocumented changes" that occurred in the latest production release seems to have changed the inheritance of the code. Things that were not connected previously became connected. Because of this, we've had to change the following issues today:

  • Student grades became hidden because we hide the To-Do List
  • Videos recorded inside of Canvas became invisible because we hide the To-Do List
  • The slide out tray for a customized button was removed, as well as all the inherent links within it.

We've drastically changed the CSS/Js code, so here's hoping no more of these pushes will break our Canvas experience.

jacob_standish
Community Participant

Hi Alan,

We're having the same problem.  Any chance you could share how you solved it?

akinsey
Community Contributor

Sure. Basically, our programmer pulled up the Canvas page we were having issues with and backtracked the inherited code by inspecting the page element. So he compared our CSS/Js code to that and found where to place our qualifiers so those items would not disappear. 

robotcars
Community Champion

The custom tray code is pretty special, any way you'd be willing to share it to the community, or commit an update to the original repo?

akinsey
Community Contributor

Well, we weren't able to fix the custom tray, unfortunately. We shifted some things around to make what we're doing "work" without breaking other parts of Canvas. I'll see if we can get the code posted today.

jill_delcambre
New Member

We are having the same issue. Any help someone can provide would be helpful.

0 Kudos

This seems to be affecting a lot of institutions, here's another thread...

https://community.canvaslms.com/thread/6105#comment-100241

syeo
New Member

We would like to reach out to any institutions who are using EvalutionKit (EK) as an LTI tool in Canvas.  The latest Canvas production release causes our EK item to be hidden from the Navigation.

We appreciate any inputs.

0 Kudos
dgrobani
Community Participant

Thanks for your post. We just checked and seem to be having this issue as well. We just emailed our EK rep to see what's up.

0 Kudos

I have touch base with them since April 6th....Not much progress!

0 Kudos

You may add this code (highlighted in red color) after the URL to see the EK link in the Navigation

https://~~~~~~/courses/id#/settings?global_includes=0

0 Kudos
themidiman
Community Champion

2 Questions:

  1. Is the EK integration broken as in the Navigation on the left hand side of courses won't show tabs for student surveys? This is pretty huge as we're in the middle of running our regular end of semester evaluations soon if not now.
  2. Is this only happening if your institution makes use of custom JS to extend a custom slide out menu as the original poster of this question was asking?
0 Kudos
  1. Is the EK integration broken as in the Navigation on the left hand side of courses won't show tabs for student surveys? This is pretty huge as we're in the middle of running our regular end of semester evaluations soon if not now. Ans: Yes, the EK link is missing from the Navigation.
  2. Is this only happening if your institution makes use of custom JS to extend a custom slide out menu as the original poster of this question was asking?
    Ans: No, we have removed the Resources menu from the Navigation, that was previously a custom slide out menu. We decided that the customize Resources menu has caused too much issues from the Canvas Release on April 4th. Therefore, we migrated our links into the HELP menu.
0 Kudos

A big relief!  Our LTI-EK is functioning now.  Thanks to EK team and their effort. The issue was caused by the script.

ryan
Instructure
Instructure

Hey Everyone,


I'm an Engineer that works on canvas and I wanted to help clear up what changed and how to fix it going forward here so I made a quick screencast.

Basically the issue was that we used to use a JavaScript library we created called "ReactTray" which was a precursor to the one we officially added to InstructureUI. The latter is better because it fixes a bunch of bugs, has better screenreader and Right-to-Left language support and there was no point in loading 2 tray javascript libraries on the page since all of the other trays we use in canvas are all already using the InstructureUI one.

but the good news is that you really shouldn't have to use custom JavaScript or CSS to make custom help links,  or to change the help menu's name and icon.  those are all things that are officially supported right in the canvas UI. just click the "Customize this menu" link at the bottom of the tray when it pops open and it will take you to an account settings page where you can create as many custom links as you'd like (see screencast).

And even if you want to add some kind of custom JavaScript behavior when you click on one of those links you can use the officially supported way to add them and add something like this to your custom JavaScript file to handle clicking on them (also see screencast):

// this is not supported by Instructure, I'm just providing it as a reference in case it is helpful
// Replace "http://example.com/test" in the selector with whatever url you use in the link you want to add custom behavior to
$(document.body).on('click', '#help_tray a[href="http://example.com/test"]', function(event) {
event.preventDefault()
alert('do something special')
})‍‍‍‍‍‍‍

Hopefully that helps clear things up. If there is anything any of you are needing that is not possible ‍‍‍‍using the officially supported way of adding custom links, we'd be interested to hear what you are doing. The hope in creating that feature was that there wouldn't be an need to use custom JS for that anymore and that people could do the same thing in a way that was easier, less-brittle, and officially supported.

PS:  I just want to add another reminder to people that are using a Custom JavaScript override file that those modifications are not officially supported and that you should make sure to check beta before every release to make sure your stuff is going to work when it goes to production.

MattHanes
Community Champion

Thank you for this explanation, Deactivated user!. It's super helpful. We appreciate you taking the time to help us understand what happened and why.

0 Kudos
akinsey
Community Contributor

Thanks, Deactivated user‌! This was very helpful and informative.

0 Kudos
JACOBSEN_C
Community Contributor

Thanks, Deactivated user!  This helps, but a second global nav option helps us separately 'chunk' Instructure Tier I support, Canvas Guides, & etc. links away from links to more drawn-out, but related, trainings (material curations in institutionally visible, not enrollable course shells), 3rd party LTI guides, and campus relevant resources (online tutoring, TItle IX resources, information security awareness information, etc.).  We've found it's very handy to keep our faculty and students still logged into and looking at our Canvas instance for these trainings and guides; keeping them w/in short reach & at their fingertips because they pertain immediately to their use of and experiences w/in the LMS, may share single sign on/CAS, and address issues that should be in the forefront when working with the LMS.  A second help menu option not labeled "Help" with an icon differentiating it from immediate support for using Canvas is pretty ideal...

The image below is of what our list of links in our "Help" menu has become for instructors since the custom option "broke".  All of our faculty are also students in trainings as well... Paring "Help" down to the top 4 links would be great.  The second nav. option would accomodate the links following; though, these would still be further streamlined to only show respective of course role...

Feel free to ask me questions about this.  Thanks for reading/making it all of the way through the above wall of text.

273098_Screen Shot 2018-04-16 at 1.41.04 PM.png

qnguyen
Community Contributor

Hi Clint,

Is there a way to add something like your Bookstore icon to the Global Menu. WE are looking for a way to do it but there is only 1 way is changing JS, I looked at the current one we have and here is the only thing we got, can you share with us how you did for the Bookstore icon? Thanks

$(document).ready(function(){
// set timeout
var tid = setTimeout(mycode, 250);
function mycode() {
  //Hide Report a Problem Link from everyone regardless of role
  $('#help-dialog-options a[href=#create_ticket]').parent() .hide();
   tid = setTimeout(mycode, 250); // repeat myself
}
});

0 Kudos
robotcars
Community Champion

Hi Quan,

Are you looking for a tray menu with multiple links, or just 1 icon link?

qnguyen
Community Contributor

Hi Robert,

I just need to add another link to the Global which linked to a training course for everyone, like in the white area under HELP in this image. Thanks

344014_Screen Shot 2020-04-06 at 2.25.00 PM.png

0 Kudos
robotcars
Community Champion

Hi Quan,

I've found that this example posted by  @garrett_william ‌ here #comment-111883, works pretty well for a quick setup.

The icon options are from Instructure icons, but you can add a custom image if you want. I haven't tried that part.

Icons you can use are here, instructure-ui - A design system by Instructure Inc. (6.23.0) 

Try not to use icons that have meaning in other parts of the UI.

$(document).ready(function () {

var styleAdded = false;

function addMenuItem(linkText, linkhref, icon, target) {
var iconHtml = '',
itemHtml,
linkId = linkText.split(' ').join('_'),
iconCSS = '<style type="text/css">' +
' i.custom_menu_list_icon:before {' +
' font-size: 27px;' +
' width: 27px;' +
' line-height: 27px;' +
' }' +
' i.custom_menu_list_icon {' +
' width: 27px;' +
' height: 27px;' +
' }' +
' body.primary-nav-expanded .menu-item__text.custom-menu-item__text {' +
' white-space: normal;' +
' padding: 0 2px;' +
' }' +
'</style>';
if (icon !== '') {
// If it is a Canvas icon
if (icon.indexOf('icon') === 0) {
iconHtml = '<div class="menu-item-icon-container" role="presentation"><i class="' + icon + ' custom_menu_list_icon"></i></div>';
// for an svg or other image
} else if (icon !== '') {
iconHtml = '<div class="menu-item-icon-container" role="presentation">' + icon + '</div>';
}
}
// Build item html
itemHtml = '<li class="ic-app-header__menu-list-item ">' +
' <a id="global_nav_' + linkId + '" href="' + linkhref + '" class="ic-app-header__menu-list-link">' + iconHtml +
' <div class="menu-item__text custom-menu-item__text">' + linkText + '</div>' +
' </a>' +
'</li>';
$('#menu .ic-app-header__menu-list-item').last().before(itemHtml);
// Add some custom css to the head the first time
if (!styleAdded) {
$('head').append(iconCSS);
styleAdded = true;
}

}

addMenuItem('Training Course', 'https://edu.instructure.com/courses/123', 'icon-certified', '_blank');
});

Additionally, you mentioned hiding the Canvas Report a Problem option in the help menu. It's easiest to do that with CSS, not JavaScript. You can add this to your CSS file in your themes.

/* hard-code kill the canvas help item */
#help-dialog-options a[href='#create_ticket'], a[href='#create_ticket'] {
display:none !important;
}

Hope this helps, let me know if you have any questions.

qnguyen
Community Contributor

Hi Robert,

I amusing this for my Global Navigation but seems to be too small comparing to others, do you know where I can get the bigger icon? ( attached)

Thanks

344188_pastedImage_1.png

0 Kudos
robotcars
Community Champion

Are you using an Instructure icon or a custom svg?

0 Kudos
qnguyen
Community Contributor

Hi,

I am using Instructure icon but need to be as big as others. I used the code you sent starting with icon-xxxx

  addMenuItem('Training Course', 'https://edu.instructure.com/courses/123', 'icon-certified', '_blank');
0 Kudos
robotcars
Community Champion

I'm looking into it.

The icon in your screenshot isn't the icon-certified.

Are you loading any other custom css or javascript?

0 Kudos