Forum Discussion

OwenHolt's avatar
OwenHolt
Super Hero
7 years ago

Bootstrap Progress Meter

I recently discovered some progress meters on the w3schools.com website and wondered if I could leverage them in a StorLine project. The meters are part of a library of code called Bootstrap. I had no idea what bootstrap was, but I discovered on the site that "Bootstrap is the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first web sites." Sounded like a good thing to leverage. Here is how I went about it:

  1. I located the code for several bootstrap meters here on the w3schools site. There are 2 parts to the code, the first goes in the head of your html document and the second creates the actual bar/meter. I copied both parts.
  2. In StoryLine (3 or 360) I added a trigger to fire at the 1st slide's timeline start that executes JavaScript. The script essentially adds the required html code to the header of the HTML5 player document then adds the code that creates the actual progress bar/meter directly in the StoryLine player.
    Here is the code:

    // Load required bootstrap references into a variable to facilitate appending the html player document.
    var appendHeader = '<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>';

    // Append the header with the code contained in the variable.
    $('head').append(appendHeader);

    // Load the required progress bar html code into a single variable.
    var progressBar = '<div class="progress" style="width:200px; position: absolute; margin: auto; right: 0; left: 0; top: 0px; bottom: 0px"><div class="progress-bar progress-bar-success progress-bar-striped active" id="my_progress" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%"></div></div>';

    // Add the code to the html player document after the title.
    $(".presentation-title").after(progressBar);

  3. Added 2 variables in SL: one to track progress as a number between 0 and 100 and another to track the color of the bar (red or green).
  4. For this demo, I added 2 buttons to modify both the variables in the prior step and to execute some code that uses these variables to modify/adjust the progress meter. Button one 1st adds 5 to the progress variable and then executes the following JS:

    // Establish StoryLine player connection and get current completion and current color of the bar
    var player=GetPlayer();
    var myProgress = player.GetVar("Progress");
    var barColor = player.GetVar("Color");

    // Check the color of the bar and change it to green if it is currently red.
    // Progress-bar-success is the green bar and progress-bar-danger is the red one.
    function toggleColor() {
         $("#my_progress").toggleClass("progress-bar-success");
         $("#my_progress").toggleClass("progress-bar-danger");
    };
    if (barColor == "Red"){
         toggleColor();
    };

    // Update the progress bar with the new value.
    $('.progress-bar').css('width', myProgress+'%').attr('aria-valuenow', myProgress);

    player.SetVar("Color", "Green");

    Button 2 is identical to button 1 except that it subtracts 5 from the progress variable and changes the meter to red if it is green. The code is identical to above except it replaces the word red with green and the word green with red.

Link to YouTube video instructions.

Link to published file for review.

Feel free to reach out to me with any questions.

  • Hi Owen, this is very cool and helpful.

    Is there a way of customizing the look and feel of the progress bar without using the standard 'success' or 'danger' progress bar?

  • Hi Owen 

    Have you had a chance to try out this Bootstrap progress bar in the context of the new modern player in ST 360?

    Thanks 

    Mala 

     

  • JohnWillis's avatar
    JohnWillis
    Community Member

    Hi All,

    Firstly I want to give a massive thank you to Owen for finding this brilliant way to implement a working progress bar into the storyline player.

    I've been working on customizing the look and feel of the original example Owen created and have managed to do the following:

    1. Remove the need to have a 'Title' in the default storyline player - this can be achieved by replacing "$(".presentation-title").after(progressBar);" with "$(".top-tabs-left").after(progressBar);" - this will move the progress bar down to the 'Menu' bar.

    2. With a little bit of help, I've managed to create the bar where any colour can be used rather than relying on the default settings - this will aid people who are trying to get the progress bar to fit into their own colour schemes.  See below:

    var progressBar = '<div class="progress" style="height:15px; width:150px; position: absolute; margin: auto; right: 0; left: 0; top: 0px; bottom: 15px"><div class="progress-bar progress-bar-info" id="my_progress" role="progressbar" aria-valuenow="0" aria-valuenow="0" aria-valuemax="100" style="width:0%;margin:0 !important;background-color:#C9D140 !important;"></div></div>';

    The bold section tells the css to ignore all previous colours and always use the colour indicated by the hex code.

    3. Removing the blank white space around the progress bar.

    var progressBar = '<div class="progress" style="height:15px; width:150px; position: absolute; margin: auto; right: 0; left: 0; top: 0px; bottom: 15px"><div class="progress-bar progress-bar-info" id="my_progress" role="progressbar" aria-valuenow="0" aria-valuenow="0" aria-valuemax="100" style="width:0%;margin:0 !important;background-color:#C9D140 !important;"></div></div>'; - 

    Again just a simple bit of css that tells the code to ignore the previous information and replace with this.

    4. Remove the colour change, this is personal preference I wasn't keen on the bar changing colour - nor was i keen on the bar dropping back down - I thought this might discourage users from clicking back if they thought they were going backwards. Simple change to the trigger - 

    Adjust Variable 'Progress' = Assignment - Value = XX - When Timeline Starts - Object - Slide - On Condidtion that 'Progress' < less than XX. - If both XX match this will prevent the progress bar from rolling back.

    5. Im currently working on (unsuccessfully) getting text onto the progress bar that is dynamically updated by the myProgress variable. However I've yet to find a solution that will not break the project from working correctly.

     

    If you compare the original code vs mine, you will see I've made other changes such as the height of the bar etc..

     

    If anyone does manage to get the text to dynamically appear on the progress bar please let us know! 

     

    Thanks Guys - Hope this will help someone.

  • JohnWillis's avatar
    JohnWillis
    Community Member

    Hi All,

    After a little bit more work on this, I've managed to now get the player to display the variable as a text overlay on top of the progress bar.

    This can be done by adding a new div to the variable 'progressBar' that is held within the Master Template. - See below:

    var progressBar = '<div class="progress" style="height:21px; width:150px; position: absolute; margin: auto; right: 0; left: 0; top: 0px; bottom: 15px"><div class="progress-bar" id="my_progress" role="progressbar" aria-valuenow="0" aria-valuenow="0" aria-valuemax="100" style="width:0%;margin:0 !important;background-color:#C9D140 !important;"></div><div class="percentage" style="text-align:center; position: absolute; margin-left:43%; top:5px; font-weight:bold; color:#304EA0"></div></div>';

    Within this div you can choose where to display your text, due to the size and width of mine I've opted for 43% left to centre the text. you can also style the text within this div, again changing the colour using a hex code.

    The next thing to do so the text updates dynamically is to add the following:

    //Add numerical value to the progress bar
    $('.percentage').text(myProgress+'%');

    This needs to be added to the JS trigger that is on each slide you are using to amend the variable 'Progress' in Storyline. - This will then take the div 'percentage' and fill it with the variable stored in 'myProgress' that was defined earlier on.

    I've tested this on all the major browsers and it works loverly however due to the styling options chosen it looks a little odd on Firefox so the next task it to get that looking sharp on all browsers.

    Hopefully this will aid someone either who has previously looked into this or at least coming into this fresh.

    Again I've added an updated SL file with all the triggers required.

    • OwenHolt's avatar
      OwenHolt
      Super Hero

      Very Nice Work John; I'm happy you found some inspiration in my original experiment. :-) 

  • Hello Owen thanks for sharing, I am creating a eLearning with progress bar but i can't seem to find any of the examples here but yours is close enough to what i have done so far, my question tho is there anyway to like lock the bar to when you click the go back (red in your example) to not restart? and keep the progress intact? where ever you left it out?

    Thanks in advance for the input and the help

  • JohnWillis's avatar
    JohnWillis
    Community Member

    Hi Kristina,

    This can be done, by removing the following from the code in the javascript for each slide where your progress will change.

    // Establish StoryLine player connection and get current completion and current color of the bar
    var player=GetPlayer();
    var myProgress = player.GetVar("Progress");
    var barColor = player.GetVar("Color");

    // Check the color of the bar and change it to green if it is currently red. 
    // Progress-bar-success is the green bar and progress-bar-danger is the red one.
    function toggleColor() {
         $("#my_progress").toggleClass("progress-bar-success");
         $("#my_progress").toggleClass("progress-bar-danger");
    };
    if (barColor == "Red"){
         toggleColor();
    };

    // Update the progress bar with the new value.
    $('.progress-bar').css('width', myProgress+'%').attr('aria-valuenow', myProgress);

    player.SetVar("Color", "Green");

     

    If you remove the text that is bold and underlined this will remove the colour change.

     

    Then you just need to amend the trigger you use to adjust the variable. This can be done by adding the condition at the end that says change the variable to '10' if the variable "Progress" is less than '10'

    That way it will only update the progress when progress has increased. I've added a picture to this post with the exact settings I've used.

     

    If you look back at the post I added my project file that will only increase the progress even when going back through slides.

     

    Hope this helps.

    • KristinaZamb070's avatar
      KristinaZamb070
      Community Member

      Thank you John for pitching in i will try this =0] i'll let you know all how this goes

  • Thanks Owen, and all who contributed to this! I'll bookmark this page for future use.

  • sofiavalera's avatar
    sofiavalera
    Community Member

    Hi, progress bar doesn't work because of this console error, I think JQuery doesn't work for me but I don't know how to solve it.

    ERROR:

    ds-frame.desktop.min.js:2 could not find slide in string table npnxnanbnsnfns00000000101
    value @ ds-frame.desktop.min.js:2

    6ds-bootstrap.min.js:11 actionator::exeJavaScript - $ is not defined

  • Hi Owen, very good idea, I want to replicate it with my projects but I am having the same issue other person had, I do not see the progress bar, I just downloaded your file (both of them) and after publishing I don't see the progress bar, could you help me understand what I am doing wrong? Storyline 360, working on my laptop

    • OwenHolt's avatar
      OwenHolt
      Super Hero

      This is because my files were created during a time that SL included the jquery library in the published output.  Now that it no longer does, you need to reference the jquery library AND allow some moments for it to load before you use any actions to call on it.

      Add a "pre-loader slide" on to your course and execute the javaScript below at timeline start to modify the DOM and add the library to the page head.  This is similar to the code for adding the bootstrap library.

      //Check if jquery has been loaded and if not, load it
      if (typeof jQuery == 'undefined') { 
      var head = document.getElementsByTagName("head")[0];
      script = document.createElement('script');
      script.onload = function() {
      //jQuery is available now
      };
      script.id = 'jQuery';
      script.type = 'text/javascript';
      script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js';

      head.appendChild(script);
      }

      Put a "page loading" message or gif on your slide and let it run for a second then auto advance to the next slide (at timeline end).