Get element id from a dmx repeat into javascript

Guys can someone assist please. I can get the audio player to work once I put it inside a dmx-repeat. It works fine when my audio tag is not in the repeat div.
Here is the html code

<div class="row style54" is="dmx-repeat" id="repeat2" dmx-bind:repeat="pagedItemsList.data.Paged_Items.data" key="'itemlist'">
        <audio id="track">
            <source type="audio/mpeg" dmx-bind:src="Description_Audio_file" />
        </audio>
        <div id="player-container">
            <div id="play-pause" class="play">Play</div>
        </div>
    </div>

and here is the javascript code.

<script>
        var track = document.getElementById('track');
var controlBtn = document.getElementById('play-pause');
function playPause() {
    if (track.paused) {
        track.play();
        //controlBtn.textContent = "Pause";
        controlBtn.className = "pause";
    } else { 
        track.pause();
         //controlBtn.textContent = "Play";
        controlBtn.className = "play";
    }
}
controlBtn.addEventListener("click", playPause);
track.addEventListener("ended", function() {
  controlBtn.className = "play";
});
    </script>

My aim here is to play the audio on click of the 'play-pause div

Please check:

I have tried that already, but it’s not working, I may be the one messing around cause I am frankly not good at javascript

I assume you are trying to manually control the audio with javascript as there is no Wappler audio component currently, well at least not a full one like their video component, however as far as I can recall they use projekktor for their controller for video and that is a full media player of audio or video.

So this is what I would do, add a Video component, but give it a source of an mp3, then click controls checkbox on for the component and make it a width of 300 and a height of 55. Make sure your .mp3 is uploaded to the server too and test.
Mine works perfectly, and I can use all the built in video control in wappler like play pause stop etc like you are trying to do.
Using the video component as though its an audio component makes life far simpler and no manual javascript needed.

@Teodor, considering this works, could Wappler not just duplicate the Video component and call it Audio Component too, or is it not quite that simple

1 Like

Thanks Patrick, it works! :slight_smile:
Now I am left to figure out how to only one video to play at a time.

Best compliment i have had all year, I wish I was Patrick, I would never have to ask another question ever again, lol, sadly I am Paul, and still have to ask many questions.

You can set one video to auto play and the others to not auto play, also using the bindings you can select one video and tell it to onplay stop another video from playing.

5 Likes

:grinning: Sorry for confusing you with Patrick)
Alright… thanks again for your tips! :ok_hand:

1 Like

haha, no problem at all.

Here is the code i used from Dynamic Events after selecting a video

<div class="col">
	<video is="dmx-video" id="video1" src="/assetts/%5BLYRICS%5D%20Coldplay%20-%20Adventure%20Of%20A%20Lifetime.mp3" controls width="300" height="55" dmx-on:play="video2.pause()"></video>
</div>
<div class="col">
	<video is="dmx-video" id="video2" src="/assetts/%5BLYRICS%5D%20Coldplay%20-%20Adventure%20Of%20A%20Lifetime.mp3" controls width="300" height="55" dmx-on:play="video1.pause()"></video>
</div>

The only problem is that, I am using a repeat. So in my code view, I am setting up only one video player.
I saw online that it can be done in Javascript, but I will have to target the videos by their IDs which will take me to my original problem :eyes:

Its pretty easy to fix without going through all that, as you can set dynamic ID for each player, give me a moment and i will test that quickly.

Alright.

Well it should work, however I think there is still a small bug in the video player component with dynamic IDs not controlling the player.

this works

<video is="dmx-video" id="video1" src="/assetts/Coldplay.mp3" controls width="300" height="55" dmx-on:play="video2.pause()"></video>
	<video is="dmx-video" id="video2" src="/assetts/Pink.mp3" controls width="300" height="55" dmx-on:play="video1.pause()"></video>

but this does not

<div id="repeat1" is="dmx-repeat" dmx-bind:repeat="serverconnect1.data.folderList1">
	<video dmx-bind:id="'mine'+$index" is="dmx-video" controls width="300" height="55" dmx-bind:src="path" dmx-on:play="'mine'+($index+1).pause()"></video>
</div>

It should work, but it seems like targeting the dynamic ids, maybe @Teodor can make a suggestion to this.

Yes, targeting the dynamic IDs seems to be the issue. By the let way, let me use this opportunity to express my deep gratitude for your videos and tutorials… They have helped me so so much! Gracias! :pray: :wink:

Ahh, absolute pleasure, glad they have helped a bit.

Just a further update on this, if I use a hyphen character in the real ID it also breaks the functionality, even on a static one.

This works fine

<video is="dmx-video" id="video1" src="/assetts/Amnesia-5-Seconds-of-Summer.mp3" controls width="300" height="55" dmx-on:play="video2.pause()"></video>
<video is="dmx-video" id="video2" src="/assetts/Christina-Perri-A-Thousand-Years.mp3" controls width="300" height="55" dmx-on:play="video1.pause()"></video>

This dosn’t

<video is="dmx-video" id="video-1" src="/assetts/Amnesia-5-Seconds-of-Summer.mp3" controls width="300" height="55" dmx-on:play="video-2.pause()"></video>
<video is="dmx-video" id="video-2" src="/assetts/Christina-Perri-A-Thousand-Years.mp3" controls width="300" height="55" dmx-on:play="video-1.pause()"></video>

Only difference is the hypen in the ID and the on-play event.

Noted. Let’s hope @Teodor comes to help

And this is why it is dangerous when i start playing with stuff, I am still fiddling with this.

Besides that I can not get the dynamic ids to work in controlling the audio i was wondering how it could be done even if that was working as expected.

This is what I have come up with so far which is kind of working but not quite.

  1. Start off with a server action to list all the .mp3 in a folder, save
  2. Add a video component to the page and add width of 300 and height of 55 to make it look nice, check the controls checkbox.

Now I want as many audio players as there are audio files

  1. Link my server connect file to the page on page load
  2. Surround my video component with a repeat children element with an expression of serverconnect1.data.folderList1
  3. Add a dmx-bind:id="basename" to the video element and remove the static ID attribute.

So far so good, I test my page and have 4 .mp3 files all playable and pause-able in their respective video players, each has an ID attribute which matches the filename of the .mp3 excluding the .mp3 extension.

something like this in the browser inspector

<div id="repeat1" is="dmx-repeat">
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-first-song.mp3" id="my-first-song"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-second-song.mp3" id="my-second-song"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-third-song.mp3" id="my-third-song"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-fourth-song.mp3" id="my-fourth-song"></video>
</div>

Now to add a dmx-on:play="" to this, I need it to stop every audio player besides the one i am clicking play to, so I can ensure 2 audio files can not play at the same time.
So I need something like this as an inspector type output

<div id="repeat1" is="dmx-repeat">
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-first-song.mp3" id="my-first-song" dmx-on:play="my-second-song.pause();my-third-song.pause();my-fourth-song.pause()"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-second-song.mp3" id="my-second-song" dmx-on:play="my-first-song.pause();my-third-song.pause();my-fourth-song.pause()"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-third-song.mp3" id="my-third-song" dmx-on:play="my-first-song.pause();my-second-song.pause();my-fourth-song.pause()"></video>
	<video is="dmx-video" controls="" width="300" height="55" src="/assetts/my-fourth-song.mp3" id="my-fourth-song" dmx-on:play="my-first-song.pause();my-second-song.pause();my-third-song.pause()"></video>
</div>

Note that only 3 .pause() commands are on each line as I can not pause the song that I want to play now, I just want to make sure only 1 song is playing at a time.

To achieve this

  1. Add an array component to the page before the repeat.
  2. Add a dmx-bind:items="" to it with a value of serverconnect1.data.folderList1.values(`basename`)
    Those are backticks surrounding basename by the way. this gives me a comma separated list of all the song basenames inside my folder.

Now all i need to do is remove the current clicked audio players basename from the array when clicking play, and add it back when pause is clicked, like this

<div id="repeat1" is="dmx-repeat" dmx-bind:repeat="serverconnect1.data.folderList1">
	<video is="dmx-video" controls="" width="300" height="55" dmx-bind:src="path" dmx-bind:id="baseneme" dmx-on:play="arr1.remove(basename)" dmx-on:pause="arr1.add(basename)"></video>
</div>

In theory so far it all works pretty well, except for the fact that the dynamic ID currently will not allow control to actually work. My question is now how do I add the entire array of IDs into the dmx-on:play and dmx-on:pause properly. As what I have tried so far is not really working.

Could some of the @wappler_ambassadors possibly give it a try if they have a free moment to spare.
This is my final code currently.

<!doctype html>
<html>

<head>
	<script src="/dmxAppConnect/dmxAppConnect.js"></script>
	<meta charset="UTF-8">
	<title>Untitled Document</title>
	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
	<script src="/dmxAppConnect/dmxVideo/dmxVideo.js" defer=""></script>
	<script src="/dmxAppConnect/dmxFormatter/dmxFormatter.js" defer=""></script>
</head>

<body is="dmx-app" id="folderlistaudio">
	<dmx-serverconnect id="serverconnect1" url="/dmxConnect/api/folder-listing-assets.php"></dmx-serverconnect>
	<div class="container">
		<div class="row">
			<div class="col-6">
				<!-- Replace all hyphen/dashes with nothing and add .pause() to the end -->
				<dmx-array id="arr1" dmx-bind:items="serverconnect1.data.folderList1.values(`basename.replace('-','').concat('.pause()')`)"></dmx-array>
				{{arr1.items}}

				<div id="repeat1" is="dmx-repeat" dmx-bind:repeat="serverconnect1.data.folderList1">
					<video dmx-bind:id="basename.replace('-','')" is="dmx-video" controls width="300" height="55" dmx-bind:src="path" dmx-on:play="arr1.remove(basename.replace('-','').concat('.pause()'));arr1.items"
						dmx-on:pause="arr1.add(basename.replace('-','').concat('.pause()'))"></video>
				</div>

			</div>
			<div class="col-6">
				<!-- Static players with same IDs for testing controls, no hyphens/dashes allowed in the ID or on:play/pause or it breaks control -->
				<video is="dmx-video" id="MyFirstSong" src="/assetts/My-First-Song.mp3" controls width="300" height="55" dmx-on:play="MySecondSong.pause()"></video>
				<video is="dmx-video" id="MySecondSong" src="/assetts/My-Second-Song.mp3" controls width="300" height="55" dmx-on:play="MyFirstSong.pause()"></video>
			</div>
		</div>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>

</html>
1 Like

Wow, Highly appreciate the effort, Paul. I will give a try as soon as I get home in front of my computer. This is amazing. Thanks a million!! :pray:

You puzzled me))

Are you able to launch the player using a dynamic id? I struggled with this problem all night, but I could not solve it.

If there is a way to access the player from outside by dynamic id and start play, the management task is solved very simply without using an array.

The only question is: how can start play the player using a dynamic id???

I have not found a way at all, seems a dynamic ID on a video component can not be stopped and started with the data bindings in any normal way I can find. The ID has to be static set on the video player or it seems to do nothing. I am hoping @patrick will give us some insight on this one.