0
votes

Updated (see bottom)

I'm creating a testimonial slider with slick slider, but I need a modal inside every slide.

I have a custom post type 'Testimonials' (English for 'getuigenissen') that has multiple ACF: title, name, function, image and video. I want to show a button on every slide that opens a modal with the video attached to that specific testimonial. The only way I could think of to do this, is to create a modal-div for every testimonial, but I think that creates a lot of unnecessary code.

PHP-code (I display the testimonials with a shortcode)

function dfib_getuigenissen_shortcode( $atts ) {
    ob_start();
    $query = new WP_Query( array(
        'post_type' => 'getuigenissen',
        'posts_per_page' => -1,
        'order' => 'ASC',
        'orderby' => 'rand',
    ) );
    if ( $query->have_posts() ) { ?>
        <div class="block__getuigenissen">
            <div class="getuigenissen__wrapper">
                <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                    <div class="getuigenis__item" style="background-image: url('<?php the_field('getuigenis_foto') ?>');">
                        <h2><?php _e( 'Getuigenissen', 'copro' ) ?></h2>
                        <div class="getuigenis__inner">
                            <p class="getuigenis__quote"><?php the_field('getuigenis_getuigenis'); ?></p>
                            <p class="getuigenis__info"><?php the_field('getuigenis_naam');?>, <?php the_field('getuigenis_functie'); ?></p>
                            <a class="getuigenis__video" href=""><?php _e( 'Bekijk de volledige video-getuigenis', 'copro' ) ?></a>
                        </div>
                        <div class="getuigenis_modal">
                        <div class="modal__inner">
                            <?php the_field('getuigenis_video'); ?>
                        </div>
                    </div>
                    </div>

                <?php endwhile;
                wp_reset_postdata(); ?>
            </div>
        </div>

    <?php $myvariable = ob_get_clean();
    return $myvariable;
    }
}
add_shortcode( 'getuigenissen', 'dfib_getuigenissen_shortcode' );

What is the best way to set this up and how can I get the right modal to open?

Update: This is what I have so far, the modal works, but the src returns unknown. see demo: https://copro-staging.dfib.be/

Testimonials.php

function dfib_getuigenissen_shortcode( $atts ) {
ob_start();
$query = new WP_Query( array(
    'post_type' => 'getuigenissen',
    'posts_per_page' => -1,
    'order' => 'ASC',
    'orderby' => 'rand',
) );
if ( $query->have_posts() ) { ?>
    <div class="block__getuigenissen">
        <div class="getuigenissen__wrapper">
            <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                <?php $videosrc = get_field('getuigenis_video'); ?>
                <div class="getuigenis__item" style="background-image: url('<?php the_field('getuigenis_foto'); ?>');">
                    <svg class="arrow-prev" width="62px" height="124px" viewBox="0 0 62 124" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                        <g id="design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                            <path d="M0,0 C34.2416545,0 62,27.7583455 62,62 C62,96.2416545 34.2416545,124 0,124 L0,124 Z" id="Combined-Shape" fill="#93C119"></path>
                            <polyline id="Path-3" stroke="#FFFFFF" stroke-width="2.4" transform="translate(26.500000, 61.000000) scale(-1, 1) translate(-26.500000, -61.000000) " points="19 47 34 61 19 75"></polyline>
                        </g>
                    </svg>
                    <div class="getuigenis__inner">
                        <p class="getuigenis__info"><strong><?php the_field('getuigenis_naam');?></strong> - <?php the_field('getuigenis_functie'); ?></p>
                        <p class="getuigenis__quote"><?php the_field('getuigenis_getuigenis'); ?></p>
                        <a class="getuigenis__video" href="#" data-toggle="modal" data-src="<?php the_field('getuigenis_video'); ?>" data-target="#myModal">
                            <svg width="59px" height="59px" viewBox="0 0 59 59" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                                <circle id="Oval" stroke="#58595B" stroke-width="1.27776" fill="#FFFFFF" cx="29.5" cy="29.5" r="28.86112"></circle>
                                <polygon id="Triangle" fill="#58595B" transform="translate(34.000000, 29.000000) rotate(-270.000000) translate(-34.000000, -29.000000) " points="34 20 43 38 25 38"></polygon>
                            </svg>
                            <?php _e( 'ontdek mijn verhaal', 'copro' ) ?>
                        </a>
                    </div>
                    <svg class="arrow-next" width="62px" height="124px" viewBox="0 0 62 124" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                        <g id="design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                            <path d="M62,0 L62,124 C27.7583455,124 0,96.2416545 0,62 C0,27.7583455 27.7583455,0 62,0 L62,0 Z" id="Combined-Shape" fill="#93C119"></path>
                            <polyline id="Path-3" stroke="#FFFFFF" stroke-width="2.4" points="31 47 46 61 31 75"></polyline>
                    </svg>
                </div>

            <?php endwhile;
            wp_reset_postdata(); ?>
        </div>
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-content">                  
              <div class="modal-body">
               <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>        
                  <iframe class="embed-responsive-item" width="560" height="315" src="" id="video" allowscriptaccess="always" allowfullscreen="allowfullscreen" allow="autoplay"></iframe>      
              </div>
            </div>
        </div> 
    </div>

<?php $myvariable = ob_get_clean();
return $myvariable;
}
}
add_shortcode( 'getuigenissen', 'dfib_getuigenissen_shortcode' );

testimonials.js

jQuery(document).ready(function($) {
    $(window).on('resize', function() {
        prefooterHeight = $('.block__prefooter').outerHeight();
        prefooterTop = prefooterHeight / 2;
        $('.block__prefooter').css('top', prefooterTop);
    }).trigger('resize');

    $('.getuigenissen__wrapper').slick({
        slidesToShow: 1,
        slidesToScroll: 1,
        fade: true,
        infinite: true,
        autoplay: true,
        autoplaySpeed: 7000,
        adaptiveHeight: true,
        prevArrow: $('.arrow-prev'),
        nextArrow: $('.arrow-next'),
    });

    var videosrc;
    $('.getuigenis__video').click(function() {
        videosrc = $(this).data( "src" );
        console.log(videosrc);
        url = "https://player.vimeo.com/video/" + videosrc + "?title=0&byline=0&portrait=0";
        console.log(url);
    });

    if ( $('#myModal').hasClass('in') ) {
        $("#video").attr('src',url );
        $('html').css('overflow', 'hidden');
    } else {
        $("#video").attr('src',videosrc);
        $('html').css('overflow', 'visible');
    }
});
2
you can make one modal and change the video dynamically with JSMatan Sanbira
Could you give some example code on how to do this?Thessa Verbruggen
By multiple you mean using an ACF repeater field containing multiple Videos... ?Bilel

2 Answers

1
votes

you can make one modal and change the video dynamically with JS.

POC: https://codepen.io/MSanbira/pen/NWqqZGW

const videos = {
  title1: "https://www.youtube.com/embed/dQw4w9WgXcQ",
  title2: "https://www.youtube.com/embed/eRBOgtp0Hac"
}

const modal = document.querySelector(".video-modal");

document.addEventListener("click", (e) => {
  if (e.target.classList.contains("open-modal")) {
    modal.innerHTML = `<iframe width="560" height="315" src="${videos[e.target.getAttribute("data-video")]}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`;
    modal.classList.add("show");
  }
});
.open-modal {
  border: solid;
  padding: 10px;
  margin: 10px;
  cursor: pointer;
}

.video-modal {
  display: none;
  position: absolute;
  top: 100px;
  left: 10px;
  right: 10px;
  z-index: 100;
}

.video-modal.show {
  display: block;
}
<div class="open-modal" data-video="title1">video 1</div>
<div class="open-modal" data-video="title2">video 2</div>

<div class="video-modal"></div>
1
votes

This a tested code using your snippet. In this solution like in Matan Sanbira' Answer, I use a data-src attribute to change the modal block content. So we don't generate a hard-coded Modal in the loop. You may be using Oembed enabled service like Youtube, Vimeo... But this Method could work even on self-hosted videos. You just need to change the iFrame code in your modal container to fit to video service requirements.

The php Code:

function dfib_getuigenissen_shortcode( $atts ) {
  //PLZ Verify your Assets path for the script
    wp_enqueue_script( 'getuigenissenjs', get_stylesheet_directory_uri().'/inc/assets/js/getuigenissen.js' );
    ob_start();
    $query = new WP_Query( array(
        'post_type' => 'getuigenissen',
        'posts_per_page' => -1,
        'order' => 'ASC',
        'orderby' => 'rand',
    ) );
    if ( $query->have_posts() ) { ?>
        <div class="block__getuigenissen">
            <div class="getuigenissen__wrapper">
                <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                    <?php 
                    //Just in case you are using an Ombed field not a URL field or simple text
                    //In this example We don't need Iframe formatting
                    //So we get only the ACF field URL
                    //That's why I added false here
                    $videosrc=get_field('getuigenis_video',false, false);
                    $foto= get_field('getuigenis_foto');
                    ?>
                    <div class="getuigenis__item" style="background-image: url('<?php echo esc_url($foto['url']); ?>');">
                        <h2><?php _e( 'Getuigenissen', 'copro' ) ?></h2>
                        <div class="getuigenis__inner">
                            <p class="getuigenis__quote"><?php the_field('getuigenis_getuigenis'); ?></p>
                            <p class="getuigenis__info"><?php the_field('getuigenis_naam');?>, <?php the_field('getuigenis_functie'); ?></p>
                            <a class="getuigenis__video" href="#" data-toggle="modal" data-src="<?php echo $videosrc ?>" data-target="#myModal"><?php _e( 'Bekijk de volledige video-getuigenis', 'copro' ) ?></a>
                        </div>
                        <!--I removed your modal code here-->
                    </div>

                <?php endwhile;
                wp_reset_postdata(); ?>
            </div>
            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
              <div class="modal-dialog" role="document">
                <div class="modal-content">                  
                  <div class="modal-body">
                   <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>        
                    <div class="embed-responsive embed-responsive-16by9">
                      <iframe class="embed-responsive-item" src="" id="video"  allowscriptaccess="always" allow="autoplay"></iframe>
                    </div>                    
                  </div>

                </div>
              </div>
            </div> 

        </div>

    <?php $myvariable = ob_get_clean();
    return $myvariable;
    }
}
add_shortcode( 'getuigenissen', 'dfib_getuigenissen_shortcode' );

getuigenissen.js

function checkYoutube(url) {
    var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
    var matches = url.match(p);
    if(matches){
        return 'https://youtube.com/embed/'+matches[1];
    }
    return false;
}

    $(document).ready(function() {
    var videosrc;  
    $('.getuigenis__video').click(function() {
    validsrc=checkYoutube(videosrc);
    console.log(validsrc);
    });

    $('#myModal').on('shown.bs.modal', function (e) {
    $("#video").attr('src',validsrc+ "?autoplay=1&amp;modestbranding=1&amp;showinfo=0" ); 
    })


    $('#myModal').on('hide.bs.modal', function (e) {
//I forgot to add this line to stop the player
//Otherwise it's done player.stop() using Youtube Js API
$("#video").attr("src","");
        $("#video").attr('src',validsrc); 
    }) 
    });

If the document ready call is already being used, then you can change it here by a function like function __videoModal() and somewhere in your main.js or where you load slick.js, near the document ready you just easily call it by __videoModal()

$(document).ready(function() {
__videoModal();
//other stuff
});

You can inspect js codes in this Working Demo