2
votes

I am trying to create a modal window for viewing videos in Blazor using this template - https://codepen.io/JacobLett/pen/xqpEYE

I have put the function in jsfunctions.js file and I have a reference to it - <script src="jsfunctions.js"></script> inside the Head tag in index.html

function ModalShow() {
  $(document).ready(function() {
    // Gets the video src from the data-src on each button
    var $videoSrc;
    $('.video-btn').click(function() {
      $videoSrc = $(this).data("src");
    });
    console.log($videoSrc);

    // when the modal is opened autoplay it  
    $('#myModal').on('shown.bs.modal', function(e) {
      // set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
      $("#video").attr('src', $videoSrc + "?autoplay=1&amp;modestbranding=1&amp;showinfo=0");
    })

    // stop playing the youtube video when I close the modal
    $('#myModal').on('hide.bs.modal', function(e) {
      // a poor man's stop video
      $("#video").attr('src', $videoSrc);
    })

    // document ready
  });
}

However, I do not know how to initialize the javascript function. I have tried using the following method inside the blazor component

protected override async Task OnInitializedAsync()
{
  await JSRuntime.InvokeAsync<object>("ModalShow").AsTask();
}

However, I get this error:

Unhandled exception rendering component: $ is not defined
    ReferenceError: $ is not defined
        at ModalShow (https://localhost:5001/jsfunctions.js:10:5

I am new to Blazor and I have no knowledge of JavaScript. Is there a pure Blazor way of displaying a modal video?

Thank you.

Later edit: The HTML code for the buttons:

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary video-btn" data-toggle="modal" data-src="https://www.youtube.com/embed/Jfrjeg26Cwk" data-target="#myModal">
  Play Video 1 - autoplay
</button>

<!-- Modal -->
<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>
        <!-- 16:9 aspect ratio -->
        <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>

The CSS:

body {
  margin: 2rem;
}

.modal-dialog {
  max-width: 800px;
  margin: 30px auto;
}

.modal-body {
  position: relative;
  padding: 0px;
}

.close {
  position: absolute;
  right: -30px;
  top: 0;
  z-index: 999;
  font-size: 2rem;
  font-weight: normal;
  color: #fff;
  opacity: 1;
}
1

1 Answers

2
votes

Like that:

window.modalVideo = {
   init: () => {
        // Gets the video src from the data-src on each button
        var $videoSrc;
        $('.video-btn').click(function() {
          $videoSrc = $(this).data("src");
        });
        console.log($videoSrc);

        // when the modal is opened autoplay it  
        $('#myModal').on('shown.bs.modal', function(e) {
          // set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
          $("#video").attr('src', $videoSrc + "?autoplay=1&amp;modestbranding=1&amp;showinfo=0");
        });

        // stop playing the youtube video when I close the modal
        $('#myModal').on('hide.bs.modal', function(e) {
          // a poor man's stop video
          $("#video").attr('src', $videoSrc);
        });
   }
};

and

protected override async Task OnAfterRenderAsync(bool firstRender)
{
  if (firstRender)
  {
    await JSRuntime.InvokeVoidAsync("modalVideo.init");
  }
}

You also need to load JQuery in your intdex.html : $ is JQuery

<script src="//code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

Bootstrap js to open a bootstrap modal

<script src="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

And Popper, because bootstrap js depends on Popper.js

<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>