cancel
Showing results for 
Search instead for 
Did you mean: 
anna_selway
Community Member

Canvas Badges New UI

Jump to solution

Hello I am not a coder and am still learning Canvas so any help would be very much appreciated. I am using the new interface.

I have set up CanvasBadges following the  instructions on Canvabadges, ideally I would like the badges displayed on User Profiles which involves adding some JavaScript(which is on the Canvabadges instructions).  I have already uploaded a Javascript file to add a new item to the global navigation, so I added the javascript from Canvasbadges to this script and uploaded.  Unfortunately the badges are not showing on user profiles.

Any advice would be wonderful.

Thank you so much

1 Solution

Accepted Solutions

Okay, here is another attempt at the code. Please test it out and let me know. I added lines 28-32 and then changed line 36.

$(function() {

  console.log("CANVABADGES: Loaded!");

  // NOTE: if pasting this code into another script, you'll need to manually change the

  // next line. Instead of assigning the value null, you need to assign the value of

  // the Canvabadges domain, i.e. "https://www.canvabadges.org". If you have a custom

  // domain configured then it'll be something like "https://www.canvabadges.org/_my_site"

  // instead.

  var protocol_and_host = "https://www.canvabadges.org";

  if(!protocol_and_host) {

    var $scripts = $("script");

    $("script").each(function() {

      var src = $(this).attr('src');

      if(src && src.match(/canvas_profile_badges/)) {

        var splits = src.split(/\//);

        protocol_and_host = splits[0] + "//" + splits[2];

      }

      var prefix = src && src.match(/\?path_prefix=\/(\w+)/);

      if(prefix && prefix[1]) {

        protocol_and_host = protocol_and_host + "/" + prefix[1];

      }

    });

  }

  if(!protocol_and_host) {

    console.log("CANVABADGES: Couldn't find a valid protocol and host. Canvabadges will not appear on profile pages until this is fixed.");

  }

  var match = location.href.match(/\/(users|about)\/(\d+)$/);

  var profileMatch = location.href.match(/\/(profile)$/);

  var userID = ENV.current_user_id;

  if (match) {

    var urlParts = location.href.split('/');

    userID = urlParts[urlParts.length-1];

  }

  if((match || profileMatch) && protocol_and_host) {

    console.log("CANVABADGES: This page shows badges! Loading...");

    var domain = location.host;

    var url = protocol_and_host + "/api/v1/badges/public/" + userID + "/" + encodeURIComponent(domain) + ".json";

    $.ajax({

      type: 'GET',

      dataType: 'jsonp',

      url: url,

      success: function(data) {

        console.log("CANVABADGES: Data retrieved!");

        if(data.objects && data.objects.length > 0) {

          console.log("CANVABADGES: Badges found! Adding to the page...");

          var $box = $("<div/>", {style: 'margin-bottom: 20px;'});

          $box.append("<h2 class='border border-b'>Badges</h2>");

          for(idx in data.objects) {

            var badge = data.objects[idx];

            var $badge = $("<div/>", {style: 'float: left;'});

            var link = protocol_and_host + "/badges/criteria/" + badge.config_id + "/" + badge.config_nonce + "?user=" + badge.nonce;

            var $a = $("<a/>", {href: link});

            $a.append($("<img/>", {src: badge.image_url, style: 'width: 72px; height: 72px; padding-right: 10px;'}));

            $badge.append($a);

            $box.append($badge);

          }

          $box.append($("<div/>", {style: 'clear: left'}));

          $("#edit_profile_form,fieldset#courses,.more_user_information + div").after($box);

        } else {

          console.log("CANVABADGES: No badges found for the user: " + ENV.current_user_id + " at " + domain);

        }

      },

      error: function(err) {

        console.log("CANVABADGES: Badges failed to load, API error response");

        console.log(err);

      },

      timeout: 5000

    });

  } else {

    console.log("CANVABADGES: This page doesn't show badges");

  }

});

View solution in original post

20 Replies
MattHanes
Navigator

We are not on the new UI yet, but maybe I can help you diagnose the problem. Could you perform the following steps to get some more information?

  1. Navigate to a profile that has badges in Google Chrome.
  2. Right click in a blank area and choose the option to "Inspect Element".
  3. Click on the tab that says "Console"
  4. Take a screenshot of what's in the console. There should be messages about Canvabadges. It should look like this screenshot:
    canvabadges.jpg

Hello thank you so much for taking the time to help me - it is so very much appreciated.

Unfortunately since I turned on the new UI, none of the profiles have a badge displayed.

On the old UI I copied the URL which I found in this discussion Re: Badges into the  custom javascript box which seemed to work.

With the new interface I created a js script and uploaded to the theme editor.  The script also adds a item to the global navigation   Links new Canvas UI  which Kenneth Larsen helped me with.

Badges are now not visible on any profiles in my test environment.

The JS file I uploaded is:

function addMenuItem (linkText, linkhref, icon) {

    'use strict';

    var iconHtml = '',

        itemHtml,

        linkId = linkText.split(' ').join('_');

    if (icon !== '') {

     iconHtml = '<i class=" + icon + "></i> ';

    }

    itemHtml = '<li class="ic-app-header__menu-list-item ">' +

        '  <a id="global_nav_' + linkId + '" href="' + linkhref + '" class="ic-app-header__menu-list-link">' +

        '       <div class="menu-item__text">' + iconHtml + linkText + '</div>' +

        '  </a>' +

        '</li>';

    $('#menu').append(itemHtml);

}

addMenuItem('Induction', '#', 'icon-discussion-check');

$(function() {

  console.log("CANVABADGES: Loaded!");

  // NOTE: if pasting this code into another script, you'll need to manually change the

  // next line. Instead of assigning the value null, you need to assign the value of

  // the Canvabadges domain, i.e. "https://www.canvabadges.org". If you have a custom

  // domain configured then it'll be something like "https://www.canvabadges.org/_my_site"

  // instead.

  var protocol_and_host = "https://www.canvabadges.org";

  if(!protocol_and_host) {

    var $scripts = $("script");

    $("script").each(function() {

      var src = $(this).attr('src');

      if(src && src.match(/canvas_profile_badges/)) {

        var splits = src.split(/\//);

        protocol_and_host = splits[0] + "//" + splits[2];

      }

      var prefix = src && src.match(/\?path_prefix=\/(\w+)/);

      if(prefix && prefix[1]) {

        protocol_and_host = protocol_and_host + "/" + prefix[1];

      }

    });

  }

  if(!protocol_and_host) {

    console.log("CANVABADGES: Couldn't find a valid protocol and host. Canvabadges will not appear on profile pages until this is fixed.");

  }

  var match = location.href.match(/\/(users|about)\/(\d+)$/);

  if(match && protocol_and_host) {

    console.log("CANVABADGES: This page shows badges! Loading...");

    var user_id = match[2];

    var domain = location.host;

    var url = protocol_and_host + "/api/v1/badges/public/" + user_id + "/" + encodeURIComponent(domain) + ".json";

    $.ajax({

      type: 'GET',

      dataType: 'jsonp',

      url: url,

      success: function(data) {

        console.log("CANVABADGES: Data retrieved!");

        if(data.objects && data.objects.length > 0) {

          console.log("CANVABADGES: Badges found! Adding to the page...");

          var $box = $("<div/>", {style: 'margin-bottom: 20px;'});

          $box.append("<h2 class='border border-b'>Badges</h2>");

          for(idx in data.objects) {

            var badge = data.objects[idx];

            var $badge = $("<div/>", {style: 'float: left;'});

            var link = protocol_and_host + "/badges/criteria/" + badge.config_id + "/" + badge.config_nonce + "?user=" + badge.nonce;

            var $a = $("<a/>", {href: link});

            $a.append($("<img/>", {src: badge.image_url, style: 'width: 72px; height: 72px; padding-right: 10px;'}));

            $badge.append($a);

            $box.append($badge);

          }

          $box.append($("<div/>", {style: 'clear: left'}));

          $("#edit_profile_form,fieldset#courses,.more_user_information + div").after($box);

        } else {

          console.log("CANVABADGES: No badges found for the user: " + user_id + " at " + domain);

        }

      },

      error: function(err) {

        console.log("CANVABADGES: Badges failed to load, API error response");

        console.log(err);

      },

      timeout: 5000

    });

  } else {

    console.log("CANVABADGES: This page doesn't show badges");

  }

});

Many thanks for taking the time out to look at this for me.

Right, even if there are no badges showing, that console information should still show up. That will help us narrow down whether the badge code is even working or not.

Hello please see below.  Thanks again 🙂

91439_pastedImage_0.png

Well it appears that CanvaBadges is loading but it thinks that profile page does not show badges. Unfortunately, I can't really think of a way to troubleshoot the problem without switching us over to the Beta interface. I'm like 80% sure it has something to do with the regular expression in this statement:

var match = location.href.match(/\/(users|about)\/(\d+)$/);

But I'm not a programmer and I don't know how to decipher that particular regular expression. I think that the javascript is checking to see if you're on a page that says users|about and if that is false, it displays "This page doesn't show badges".

I have not used CanvaBadges but I can help with the code that you posted.

It looks like the regular expression that  @MattHanes ​ pointed out takes the url for the current page and breaks it up to identify the page and the user id. The part with (users|about) means that the code will look for the word "users" or the word "about" in the url. The (\d+) suggests that we should be looking for one or more digits.

So for example, when I pull up my profile in the old UI, I see something like https://usu.instructure.com/about/1234567. This code identifies the "about" followed by a "/" followed by a user ID.

The code then breaks up that result to get the students ID to pull all of their badges.

In the new UI when I go to my profile, I see https://usu.beta.instructure.com/profile. No "about", no "users" and no user ID. When I view a student in a course it appears to still load "users/1234567".

Here is an adaptation of the code you posted that should account for the "profile" page without a user id.

$(function() {

  console.log("CANVABADGES: Loaded!");

  // NOTE: if pasting this code into another script, you'll need to manually change the

  // next line. Instead of assigning the value null, you need to assign the value of

  // the Canvabadges domain, i.e. "https://www.canvabadges.org". If you have a custom

  // domain configured then it'll be something like "https://www.canvabadges.org/_my_site"

  // instead.

  var protocol_and_host = "https://www.canvabadges.org";

  if(!protocol_and_host) {

    var $scripts = $("script");

    $("script").each(function() {

      var src = $(this).attr('src');

      if(src && src.match(/canvas_profile_badges/)) {

        var splits = src.split(/\//);

        protocol_and_host = splits[0] + "//" + splits[2];

      }

      var prefix = src && src.match(/\?path_prefix=\/(\w+)/);

      if(prefix && prefix[1]) {

        protocol_and_host = protocol_and_host + "/" + prefix[1];

      }

    });

  }

  if(!protocol_and_host) {

    console.log("CANVABADGES: Couldn't find a valid protocol and host. Canvabadges will not appear on profile pages until this is fixed.");

  }

  var match = location.href.match(/\/(users|about)\/(\d+)$/);

  var profileMatch = location.href.match(/\/(profile)$/);

  if((match || profileMatch) && protocol_and_host) {

    console.log("CANVABADGES: This page shows badges! Loading...");

    var domain = location.host;

    var url = protocol_and_host + "/api/v1/badges/public/" + ENV.current_user_id + "/" + encodeURIComponent(domain) + ".json";

    $.ajax({

      type: 'GET',

      dataType: 'jsonp',

      url: url,

      success: function(data) {

        console.log("CANVABADGES: Data retrieved!");

        if(data.objects && data.objects.length > 0) {

          console.log("CANVABADGES: Badges found! Adding to the page...");

          var $box = $("<div/>", {style: 'margin-bottom: 20px;'});

          $box.append("<h2 class='border border-b'>Badges</h2>");

          for(idx in data.objects) {

            var badge = data.objects[idx];

            var $badge = $("<div/>", {style: 'float: left;'});

            var link = protocol_and_host + "/badges/criteria/" + badge.config_id + "/" + badge.config_nonce + "?user=" + badge.nonce;

            var $a = $("<a/>", {href: link});

            $a.append($("<img/>", {src: badge.image_url, style: 'width: 72px; height: 72px; padding-right: 10px;'}));

            $badge.append($a);

            $box.append($badge);

          }

          $box.append($("<div/>", {style: 'clear: left'}));

          $("#edit_profile_form,fieldset#courses,.more_user_information + div").after($box);

        } else {

          console.log("CANVABADGES: No badges found for the user: " + ENV.current_user_id + " at " + domain);

        }

      },

      error: function(err) {

        console.log("CANVABADGES: Badges failed to load, API error response");

        console.log(err);

      },

      timeout: 5000

    });

  } else {

    console.log("CANVABADGES: This page doesn't show badges");

  }

});

I can verify from the console that it should check for that user's badges, but not having used CanvaBadges, I am not positive if everything else is working. Give it a shot and let me know.

I'm so glad a real programmer stepped in to clarify that expression. I learned a lot from your explanation, thanks!

Thank you so much - it works.  I cannot express how grateful I am 🙂 ty.

That is great, I was a little nervous posting the code without really being able to test it.