0

I'm displaying three posts (custom post types) with a foreach loop, each displaying an audio player and some metadata. The audio is played via JW Player, which I am calling using their api. There is a function in the JW Player code that allows you to stop any other players from playing if you press one player.

Here's the whole loop. It does the job but I would like something more elegant and dynamic:

<?php 
    $posts = get_posts(array(
        'numberposts' => 3,
        'post_type' => 'audio'
    ));
    if( $posts ): 
    $i = 1; 
?>
<?php foreach( $posts as $post ) : ?>
    <div class="media-container audio player-<?php echo $i; ?>">
        <div id="player-<?php echo $i; ?>">Loading this Audio...</div>
<?php 
if ($i == 1) :
    $x1 = 2;
    $x2 = 3;
elseif ($i == 2) :
    $x1 = 1;
    $x2 = 3;
elseif ($i == 3) :
    $x1 = 1;
    $x2 = 2;
endif;
?>
        <script type="text/javaScript">
            var playerInstance = jwplayer("player-<?php echo $i; ?>");
            playerInstance.setup({
                file: '<?php the_field("audio_upload"); ?>',
                image: '<?php the_field("audio_image"); ?>',
                events:{
                    onPlay: function() {
                        jwplayer('player-<?php echo $x1; ?>').stop();
                        jwplayer('player-<?php echo $x2; ?>').stop();
                    }
                }
            });
        </script>

        <div class="media-details">
            <h2 class="audio-title"><?php the_field('name_of_audio'); ?>    </h2>
        </div>
    </div>
<?php $i++; endforeach; wp_reset_postdata(); endif; ?>

I'm wondering if there isn't a way to dynamically get $x1 and $x2 rather than explicitly declaring the values like I am doing. For example if I decide to have 4 or 5 (or 10) posts show up on this page I would like to not have to change the code for $x1 and $x2. Any help would be appreciated.

4
  • hmmm this question has very little to do with wordpress :( Feb 21, 2017 at 14:45
  • Sorry @MarkKaplun I always work with Wordpress and I always post here. Where do you suggest I post?
    – semidivine
    Feb 21, 2017 at 18:02
  • first, no need to appologies ;) stackoverflow is probably a better place. as your question is basically how to generate some semi random numbers. You can just use random number generator for that. (or maybe I misunderstood the question) Feb 21, 2017 at 18:05
  • @MarkKaplun it's not a random number generator, and it is about about working within a Wordpress query, but yes it also could be a question for just stackoverflow. Noted for next time.
    – semidivine
    Feb 21, 2017 at 18:31

2 Answers 2

0

You need a second for loop that will output the stop function for all the players except the current one, like this:

<?php

$posts = get_posts(array(
    'numberposts' => 3,
    'post_type' => 'any'
));

$number_of_posts_returned = count($posts); //because it can be less than the ones we wanted

if ($posts):
    $i = 1;
    ?>
    <?php foreach ($posts as $post) : ?>
        <div class="media-container audio player-<?php echo $i; ?>">
            <div id="player-<?php echo $i; ?>">Loading this Audio...</div>
            <script type="text/javaScript">
                var playerInstance = jwplayer("player-<?php echo $i; ?>");
                playerInstance.setup({
                file: '<?php //the_field("audio_upload"); ?>',
                image: '<?php //the_field("audio_image"); ?>',
                events:{
                    onPlay: function() {
                        <?php 
                        //lets create the stop call for all except the current number
                        for ($x = 1; $x <= $number_of_posts_returned; $x++) { 
                            if($x != $i){
                       ?>
                            jwplayer('player-<?php echo $x; ?>').stop();

                      <?php }//end IF

                        } //end for
                       ?>

                    }
                }
                });
            </script>

            <div class="media-details">
                <h2 class="audio-title"><?php //the_field('name_of_audio'); ?>    </h2>
            </div>
        </div>
        <?php $i++;
    endforeach;
    wp_reset_postdata();
endif; ?>
1
  • 1
    Thanks this worked! And it looks future proof. I learned something new, I did not know you could put PHP inside of Javascript, although I can't see why not now :) Makes total sense. @moraleida thank you too... I tried your version and adding a new class to the player div unfortunately broke the player. JW dynamically loads a bunch of classes of its own. I even tried your way using one of their classes ('jwplayer') that loads for each instance, but it was still broken, not sure why. But I did incorporate your esc_js() into David's code.
    – semidivine
    Feb 21, 2017 at 18:36
0

Here's a simple solution just based on getting the IDs from the current loaded players.

First, add a common class to you player divs:

<div id="player-<?php echo $i; ?>" class="jwplayer-loaded">Loading this Audio...</div>

Then on your script, get all current loaded players and stop them one by one except your current one:

<script type="text/javaScript">
    // don't forget to esc_js() any values you print to javascript code
    // https://developer.wordpress.org/reference/functions/esc_js/
    var playerId = "player-<?php echo esc_js( $i ); ?>",
        playerInstance = jwplayer( playerId );
    playerInstance.setup({
        file: '<?php the_field("audio_upload"); ?>',
        image: '<?php the_field("audio_image"); ?>',
        events:{
            onPlay: function() {
                var playerList = document.querySelectorAll('.jwplayer-loaded');

                [].forEach.call( playerList, function( v ) {
                    if ( v.id !== playerId ) {
                        jwplayer( v.id ).stop();
                    }
                } );
            }
        }
    });
</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.