My asp.net mvc core 2.2 application includes a page where a partial is loaded:
<div class="col-md-9" id="content">
@await Html.PartialAsync("_TrainingContent")
</div>
The partial contains a model and loads a video using the video.js player:
@model Partner2Train.Models.ModuleViewModels.TrainingContentViewModel
@if (Model != null)
{
<li>Do some training stuff for @Model.ModuleId</li>
<div class="row">
<div id="instructions">
<video id="my_video" class="video-js vjs-default-skin" width="640" height="267"
poster=''
data-setup='{ "aspectRatio":"640:267", "playbackRates": [0.5, 1, 2], "controls":true, "preload":"auto", "autoplay":false, "inactivityTimeout":0 }'>
<source src="~/video/sample_video.mp4" type="video/mp4" />
<source src="~/video/sample_video.webm" type="video/webm" />
<source src="~/video/sample_video.ogv" type="video/ogg" />
<p>Your browser does not support HTML5 video.</p>
</video>
</div>
</div>
<div class="row" style="margin-top:25px;">
<div id="db_data">
<label>Current video location: </label> <input type="text" id="watched_value" value="" disabled /><br />
<label>Total video duration: </label> <input type="text" id="total_duration" value="" disabled />
</div>
</div>
<br /><br />
}
else
{
<text>Please select a module</text>
}
Initially, when I have javascript functions running on document ready, the video loads and plays without any issues. However, when I update the partial using an ajax call:
$("#tcontent").click(function () {
$.ajax({
url: "Module/TrainingContent/?id=2",
type: "get",
//data: $("form").serialize(), //if you need to post Model data, use this
success: function (result) {
$("#content").html(result);
}
});
})
The video no longer loads after the ajax call. It seems that the javascript for the video player doesn't trigger again. To address this, I moved the video javascript into separate functions and called them upon a successful ajax call:
$("#tcontent").click(function () {
$.ajax({
url: "Module/TrainingContent/?id=2",
type: "get",
//data: $("form").serialize(), //if you need to post Model data, use this
success: function (result) {
$("#content").html(result);
vidprep();
vidbutton();
}
});
})
Despite this approach, the video controls still don't load correctly after an ajax update. The javascript functions run successfully but don't apply the controls to the video, displaying an unformatted box instead.
If you have any insights on how to make javascript interact with elements in a partial updated via ajax, I would greatly appreciate your assistance as I have been grappling with this issue for several days.
Elements after ajax callhttps://i.sstatic.net/rAJO1.png
Below are the two javascript functions that are running successfully, printing messages to the console:
function vidprep() {
console.log("In partial video function");
// Stop if HTML5 video isn't supported
if (!document.createElement('video').canPlayType) {
$("#video_controls").hide();
console.log("Can't Play Video");
return;
}
var video = document.getElementById("my_video");
// Play/Pause ============================//
$("#play_button").bind("click", function () {
video.play();
});
$("#pause_button").bind("click", function () {
video.pause();
});
$("#play_toggle").bind("click", function () {
if (video.paused) {
video.play();
$(this).html("Pause");
} else {
video.pause();
$(this).html("Play");
}
});
// Play Progress ============================//
$(video).bind("timeupdate", function () {
var timePercent = (this.currentTime / this.duration) * 100;
$("#play_progress").css({ width: timePercent + "%" })
});
// Load Progress ============================//
$(video).bind("progress", function () {
updateLoadProgress();
});
$(video).bind("loadeddata", function () {
updateLoadProgress();
});
$(video).bind("canplaythrough", function () {
updateLoadProgress();
});
$(video).bind("playing", function () {
updateLoadProgress();
});
function updateLoadProgress() {
if (video.buffered.length > 0) {
var percent = (video.buffered.end(0) / video.duration) * 100;
$("#load_progress").css({ width: percent + "%" })
}
}
// Time Display =============================//
$(video).bind("timeupdate", function () {
$("#current_time").html(formatTime(this.currentTime));
$("#watched_value").val(formatTime(this.currentTime));
});
$(video).bind("durationchange", function () {
$("#duration").html(formatTime(this.duration));
$("#total_duration").val(formatTime(this.duration));
});
function formatTime(seconds) {
var seconds = Math.round(seconds);
var minutes = Math.floor(seconds / 60);
// Remaining seconds
seconds = Math.floor(seconds % 60);
// Add leading Zeros
minutes = (minutes >= 10) ? minutes : "0" + minutes;
seconds = (seconds >= 10) ? seconds : "0" + seconds;
return minutes + ":" + seconds;
}
}
function vidbutton() {
var $refreshButton = $('#refresh');
var $results = $('#css_result');
console.log("In video button");
function refresh() {
var css = $('style.cp-pen-styles').text();
$results.html(css);
}
refresh();
$refreshButton.click(refresh);
// Select all the contents when clicked
$results.click(function () {
$(this).select();
});
}