UPDATED
I have used javascript to create a popup and it\'s working fine. The issue is that i am using iframe embed video code (Facebook) in the model. th
Without an API provided by the third party, in your case Facebook, there is no way to programmatically communicate through an iframe on a different domain. Therefor it would be easier to create and destroy the iframe when opening and closing the modals.
Remove the iframe from your HTML. Move the src
of the iframe to a the modal element and store the value in a data attribute. This enables you to use the value of the attribute whenever you want when creating the iframe.
<a href="#jsModal" id="popup" class="jsModalTrigger">Trigger</a>
<div id="jsModal" class="modal" data-src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2FEasternfabricsstore%2Fvideos%2F691828284946045%2F&show_text=0&width=560">
<div class="modal__overlay jsOverlay"></div>
<div class="modal__container">
<button class="modal__close jsModalClose">✕</button>
</div>
</div>
In your JavaScript create a function which constructs an iframe element with the src and attributes that you currently have in your HTML. This function has to be called whenever the modal is being opened. So it should be called in the onclick
event handlers in the openModal
function. Append the iframe to the modal__container
element and open the modal.
Same goes for the closeModal
function where your should remove the iframe element from the HTML to stop the video from playing in the background, which will solve your issue.
In combination with the creation of the iframe you now can start and stop your iframe video on opening and closing the modal.
/* This script supports IE9+ */
(function() {
function createIframe(src) {
if (typeof src !== 'string') {
throw Error('src argument has to be a valid string');
}
var iframe = document.createElement('iframe');
iframe.src = src;
iframe.width = 560;
iframe.height = 308;
iframe.setAttribute('scrolling', 'no');
iframe.setAttribute('frameBorder', 0);
iframe.setAttribute('allowTransparency', 'true');
iframe.setAttribute('allowFullscreen', 'true');
iframe.style.border = 'none';
iframe.style.overflow = 'hidden';
return iframe;
}
/* Opening modal window function */
function openModal() {
/* Get trigger element */
var modalTrigger = document.getElementsByClassName('jsModalTrigger');
/* Set onclick event handler for all trigger elements */
for(var i = 0; i < modalTrigger.length; i++) {
modalTrigger[i].onclick = function() {
var target = this.getAttribute('href').substr(1);
var modalWindow = document.getElementById(target);
var source = modalWindow.getAttribute('data-src');
var iframe = createIframe(source);
var modalContainer = this.lastElementChild;
modalContainer.appendChild(iframe);
modalWindow.classList ? modalWindow.classList.add('open') : modalWindow.className += ' ' + 'open';
}
}
}
function closeModal(){
/* Get close button */
var closeButton = document.getElementsByClassName('jsModalClose');
var closeOverlay = document.getElementsByClassName('jsOverlay');
/* Set onclick event handler for close buttons */
for(var i = 0; i < closeButton.length; i++) {
closeButton[i].onclick = function() {
var modalContainer = this.parentNode;
var modalWindow = modalContainer.parentNode;
modalContainer.removeChild(modalContainer.firstElementChild);
modalWindow.classList ? modalWindow.classList.remove('open') : modalWindow.className = modalWindow.className.replace(new RegExp('(^|\\b)' + 'open'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
/* Set onclick event handler for modal overlay */
for(var i = 0; i < closeOverlay.length; i++) {
closeOverlay[i].onclick = function() {
var modalWindow = this.parentNode;
modalWindow.classList ? modalWindow.classList.remove('open') : modalWindow.className = modalWindow.className.replace(new RegExp('(^|\\b)' + 'open'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
}
/* Handling domready event IE9+ */
function ready(fn) {
if (document.readyState != 'loading'){
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
/* Triggering modal window function after dom ready */
ready(openModal);
ready(closeModal);
}());
Now your WooCommerce video field is already good, but maybe it's a good idea to indicate that the src
of the iframe is needed as value instead of the a complete <iframe>
tag. This is because we will be building the iframe on the frontend.
add_action( 'woocommerce_product_options_general_product_data', 'product_video_field' );
function product_video_field() {
$args = array(
'id' => 'product_video_field',
'label' => sanitize_text_field( 'Product Video' ),
'placeholder' => 'Place embed src value of video here',
'desc_tip' => true,
'style' => 'height: 120px'
);
echo woocommerce_wp_textarea_input( $args );
}
add_action( 'woocommerce_process_product_meta', 'product_video_field_save' );
function product_video_field_save( $post_id ) {
$product_video_field = $_POST[ 'product_video_field' ];
update_post_meta( $post_id, 'product_video_field', $product_video_field );
}
Your Single Product Image template is also really close. The only thing that you should modify here is the structure of the modal and the output of the video from WooCommerce. The code below will output the src
of the video onto a data-src
attribute which will be read by JavaScript when creating the iframe.
/**
* Single Product Image
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/product-image.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce/Templates
* @version 3.5.1
*/
defined( 'ABSPATH' ) || exit;
// Note: `wc_get_gallery_image_html` was added in WC 3.3.2 and did not exist prior. This check protects against theme overrides being used on older versions of WC.
if ( ! function_exists( 'wc_get_gallery_image_html' ) ) {
return;
}
global $product;
$columns = apply_filters( 'woocommerce_product_thumbnails_columns', 4 );
$post_thumbnail_id = $product->get_image_id();
$wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array(
'woocommerce-product-gallery',
'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ),
'woocommerce-product-gallery--columns-' . absint( $columns ),
'images',
) );
//for video, need to modify the wrapper classes, as they disable click events
$video_wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array(
'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ),
'woocommerce-product-gallery--columns-' . absint( $columns ),
'images',
) );
$product_video = get_post_meta(get_the_ID(), 'product_video_field', true );
$product_sub_image = get_the_post_thumbnail($post, [120]);
?>
<div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $video_wrapper_classes ) ) ); ?>" data-columns="<?php echo esc_attr( $columns ); ?>">
<figure class="woocommerce-product-gallery__wrapper">
<?php //if the product video field is not empty, output the video on the page.
if ( !empty($product_video)) { ?>
<a href="#jsModal" id="popup" class="jsModalTrigger">FEATURED VIDEO</a>
<div id="jsModal" class="modal" data-src="<?php echo $product_video; ?>">
<div class="modal__overlay jsOverlay"></div>
<div class="modal__container">
<button class="modal__close jsModalClose">✕</button>
</div>
</div>
<!--this is optional, display the featured image below the video, IF there is a video -->
<?php } else {
//if no video, output featured image as per default template
if ( $product->get_image_id() ) {
$html = wc_get_gallery_image_html( $post_thumbnail_id, true );
} else {
$html = '<div class="woocommerce-product-gallery__image--placeholder">';
$html .= sprintf( '<img src="%s" alt="%s" class="wp-post-image" />', esc_url( wc_placeholder_img_src( 'woocommerce_single' ) ), esc_html__( 'Awaiting product image', 'woocommerce' ) );
$html .= '</div>';
}
}
?>
</figure>
</div>
I hope it works out. Please let me know if it did.