The Easy Way: Dynamic Playlist and Progress Bar (Javascript, JQuery, Bootstrap)

S. Jackson
6 min readJan 3, 2020

--

Creating a dynamic playlist and progress bar doesn’t have to be a daunting task. I’ve created a rather simple way to implement a dynamic music playlist along with a progress bar from bootstrap. To start, make sure bootstrap is imported in your project — this is for the progress bar. You also need to make sure JQuery is imported.

Let’s jump straight into it..

First, create an audio element with a blank src and also a div that holds the play/pause and forward buttons and title so we can dynamically add text, like the song title, to it once a song is played like so:

<div class="alert text-center" role="alert"><i class="fas fa-volume-mute pause-btn" id="volume-toggler"></i><span id="song">DaBaby - BOP</span><i class="fas fa-forward forward"></i></div>
<audio id=”audio” preload=auto>
<source src=”” type=”audio/mpeg”> Your browser does not support the audio element.</audio>

It’s up to you whether or not to add text to the span, keep in mind though, if you don’t, the user will not see anything but the play and forward button. That’s not ideal (imo). Since we know what the first song is, we can just put it in the span so it’s clear to the user what’s going on. Okay since we’ve got that out the way.. NEXT

You’re leaving the audio src blank because you will dynamically change that with Javascript.

First, we want to target the audio element in our js file so that we can use it later:

let song = document.getElementById(‘audio’);

And while we are at it, lets initialize other variables we will need like the title span, which has an ID of ‘song’, a song counter — so we can keep track of the position of the playlist, and a nested array of songs.

let title = document.getElementById(‘song’);let numberOfSong = 0;let playlist = [ [‘path-to-mp3’, ‘artist info’], [‘path-to-mp3’, ‘artist-info’]];

Now on to the functions…

We want our playlist to play a song when a button is clicked, and the way I have it set up, the button is an icon which is first in a mute state and when clicked transforms to a sound state (simply, toggling icons). So, when the user clicks the mute button, I want the song to play and change the icon to sound. Now, you could easily do that this way (keep in mind the mute/sound icons have a class of pause-btn):

function play(){song.play();}$('.pause-btn').click(() => {play();})

But, that wouldn’t be very effective because our goal is to make a playlist that handles multiple songs, a truly dynamic playlist. With this approach, you’d have to write multiple functions that test which song is playing, if a song is playing at all, and etc. Instead, we want to keep the click handler for pause-btn, but we would like to know what ‘state’ it’s in. We can tell this by the icon. If the icon is the mute icon, then the song is not playing. If the icon is the sound icon, then the song is playing. So, we can test this by calling the hasClass method on the class pause-btn in an if statement — then make it do something. Like this:

$(‘.pause-btn’).click(() => {let pauseOrPlay = $(‘.pause-btn’);if(pauseOrPlay.hasClass(‘fas fa-volume-up’) || pauseOrPlay.hasClass(‘fa-volume-up fas’) {//do something}})

Next, we want to make it do something. First and foremost, we want to change the icons, so we can do that with the toggleClass method. Next, we want to know if the song has been paused or not played at all. This is important because if the song has been paused, we want to start from where it last ended once the user hits the pause-btn again. We can see this by using an if statement and checking the duration of the audio element. If the audio element’s duration is greater than 0, then we know the music has been paused and the user would like to play it again. If the audio element’s duration is equal to 0, then this is the first time the user has clicked the pause-btn and we would like to start from the beginning of the playlist. So, you can do this:

$(‘.pause-btn’).click(() => {let pauseOrPlay = $(‘.pause-btn’);if(pauseOrPlay.hasClass(‘fas fa-volume-mute’) || pauseOrPlay.hasClass(‘fa-volume-mute fas’) {if(song.duration > 0){playCurrentSong();} else {next();}}})

Next, using the same click handler, we want to write an if statement if the pause-btn is in a mute state. If it’s in a mute state, all we want to do is change the icon and pause the song. Like so:

$(‘.pause-btn’).click(() => {let pauseOrPlay = $(‘.pause-btn’);if (pauseOrPlay.hasClass(‘fas fa-volume-mute’) || pauseOrPlay.hasClass(‘fa-volume-mute fas’)) {$(‘.pause-btn’).toggleClass(‘fas fa-volume-up fas fa-volume-mute’);if (song.duration > 0) {playCurrentSong();} else {next();}} else if (pauseOrPlay.hasClass(‘fas fa-volume-up’) || pauseOrPlay.hasClass(‘fa-volume-up fas’)) {$(‘.pause-btn’).toggleClass(‘fas fa-volume-up fas fa-volume-mute’);pauseSong();}});

Before we write our main functions, lets get the JQuery out of the way. Lets make the forward button functional. Once the user clicks the forward button, it will fire a ‘next’ function.

$(‘.forward’).click(() => {next();});

Now onto the most important function to make this playlist work. The next function. First, we want to check if the numberOfSong variable is equal to the playlist’s length. If it is, we want the playlist to start from the beginning. Since the numberOfSong variable is basically our counter for our playlist array, we use it to manipulate which song is playing. So, we change the src using the counter, but since it’s a nested array, we need to explicitly state which index in the array we are trying to access. Since we know each nested array only has two values, then we can access each value by explicitly pointing to it by it’s index — which in this case is either a 0 or a 1. In this case, 0 would always be the song while 1 will always be the title of the song. Next, we want to change the title of the song dynamically, and we can do this by changing the innerHTML of the variable title, which is the song class in HTML (remember that span we were talking about? If not, scroll up to see the variables we created at the beginning of the tutorial). Next, we want to increase the counter variable numberOfSong everytime this function is called. We also need to load the audio file and then lastly play it.

function next() {if (numberOfSong === playlist.length) {numberOfSong = 0;}song.src = playlist[numberOfSong][0];title.innerHTML = playlist[numberOfSong][1];numberOfSong++;song.load();song.play();}

Next, we have two smaller functions that basically pause the song or continue playing the current song. I’ve called these functions playCurrentSong and pauseSong.

function pauseSong() {song.pause();}function playCurrentSong() {song.play();}

Now, for the last part.. it just wouldn’t be right if we didn’t have a progress bar right? So we need to add a progress bar element to our HTML. Anywhere you want it to be honestly, preferably in view. For my project, I have it fixed to the top along with the song.

<div class=”progress”><div class=”progress-bar” role=”progressbar” aria-valuenow=”30" aria-valuemin=”0" aria-valuemax=”100"></div></div>

Now, all we need to do is increase the width of the progress bar dynamically everytime the time is updated. We can do that by adding an event listener…

song.addEventListener(‘timeupdate’, onLoadProgress);

and a function that calculates the time the audio has been playing:

function onLoadProgress(){var progress = parseInt(((song.currentTime / song.duration) * 100), 10);var progressToString = ‘’ + progress + ‘%’;$(‘.progress-bar’).attr(‘aria-valuenow’, progressToString);$(‘.progress-bar’).css(‘width’, progressToString);}

Tada! You now have a dynamic playlist. Pat yourself on the back, and if you read this whole document — thank you much. If you found it helpful, give me a clap or two :) Hope this helps someone. Until next time, happy coding.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

S. Jackson
S. Jackson

Written by S. Jackson

Database Administrator | Web Developer | Software Developer

No responses yet

Write a response