Magnific Popup fails to work with multiple galleries on a page - magnific-popup

I am using magnific popup on a new website that i am building but i am running into a problem getting it to work when multiple galleries on the same page.
I'm using wordpress, Slick Slider to display a slider full of thumbnails and when one of the thumbnails is clicked it should open the larger version of the image in the Magnific Popup.
My HTML looks like this:
<div class="media-carousel slick-initialized slick-slider" id="carousel-links">
<div class="slick-list draggable" tabindex="0">
<div class="slick-track" style="opacity: 1; width: 1152px; transform: translate3d(0px, 0px, 0px);">
<div class="slick-slide slick-active" data-slick-index="0" style="width: 288px;">
<div class="standard_media_element media_title">
<a href="image1-large.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal">
<img src="image1.jpg" alt="" class="standard-image"></a>
</div>
</div>
<div class="slick-slide slick-active" data-slick-index="1" style="width: 288px;">
<div class="standard_media_element media_title">
<a href="image2-large.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal">
<img src="image2.jpg" alt="" class="standard-image"></a>
</div>
</div>
<div class="slick-slide slick-active" data-slick-index="2" style="width: 288px;">
<div class="standard_media_element media_title">
<a href="image3-large.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal">
<img src="image3.jpg" alt="" class="standard-image"></a>
</div>
</div>
<div class="slick-slide slick-active" data-slick-index="3" style="width: 288px;">
<div class="standard_media_element media_title">
<a href="image4-large.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal">
<img src="image4.jpg" alt="" class="standard-image"></a>
</div>
</div>
</div>
</div>
I have a site.js file that contains all of the javascript for my site in it. I'm calling magnific popup using the following function. I've added some extra stuff in it to add effects.
jQuery('#carousel-links').each(function() {
jQuery(this).magnificPopup({
delegate: 'a',
type: 'image',
tClose: 'Close (Esc)',
tLoading: '',
preload: [1,4],
gallery:{
enabled:true,
tPrev: 'previous',
tNext: 'next',
tCounter: '%curr% of %total%'
},
image: {
verticalFit: true,
titleSrc: function(item) {
return item.el.attr('title') + ' ยท <a class="image-source-link" href="'+item.src+'" target="_blank"><i class="fa fa-file-image-o"></i> open original</a>';
}
},
closeBtnInside: false,
closeOnContentClick: false,
mainClass: 'mfp-zoom-in',
removalDelay: 300, //delay removal by X to allow out-animation
callbacks: {
lazyLoad: function (item) {
console.log(item); // Magnific Popup data object that should be loaded
},
beforeOpen: function() {
jQuery('#carousel-links a').each(function(){
jQuery(this).attr('title', $(this).find('img').attr('alt'));
});
},
open: function() {
//overwrite default prev + next function. Add timeout for css3 crossfade animation
jQuery.magnificPopup.instance.next = function() {
var self = this;
self.wrap.removeClass('mfp-image-loaded');
setTimeout(function() { jQuery.magnificPopup.proto.next.call(self); }, 120);
}
jQuery.magnificPopup.instance.prev = function() {
var self = this;
self.wrap.removeClass('mfp-image-loaded');
setTimeout(function() { jQuery.magnificPopup.proto.prev.call(self); }, 120);
}
},
imageLoadComplete: function() {
var self = this;
setTimeout(function() { self.wrap.addClass('mfp-image-loaded'); }, 16);
}
}
});
});
I have the same exact HTML code building different galleries outputting on the same page and for some reason the first carousel with lightbox works great. But for whatever reason, the second gallery does not work. The carousel works fine, but Magnific Popup does not fire. When i click on one of the thumbnails, it opens the larger image in the browser window.
I tested my js function by adding a "console.log("clicked");" after the .each. I see the console that the thumbnail is being clicked and that part is working.
Any idea how i can get the multiple sliders to work on my page?
I've tried the example from the documentation for the multiple galleries by removing everything from the function and making it as barebone as possible. I get the same result, the first lightwindow works but the second one does not.
I'm not seeing any js errors on the console either.
UPDATE #1
This isn't an ideal solution, but i did find a way to make this work. I had to use unique IDs on each slider in order to get the lightbox to work if multiple sliders were on the same page using the same ID value. In this case, I was using #carousel-links for all of the sliders. I guess you can't share the same ID for sliders across the board and get this lightbox to work?
I also moved the javascript code to be right after the carousel in the module template page. I removed it for now from my site.js file.
I'm not looking for a way to optimize the code so i can put it in my site.js. I'll try to grab that ID value by using the class on each carousel. I'll report back if i can get that to work.
UPDATE #2 - OMG
Could the problem i was having when the lightbox only worked with the first instance of the lightbox be because i was an ID instead of a CLASS as my selector for the lightbox? I changed to the CLASS and now they are all working.

What fixed my problem is I changed the selector from the ID to a class on the same element. This allowed for multiple galleries on the same page to work together with no problem.

Related

Image disappears when adding event directly on image

I am adding an event this image and it just disappears when adding said even i wonder if i use an icon and css it would show up
here is the component
#inherits SelectUserListComponentBase
<h3>Selected User List</h3>
<div class="container-fluid">
#if(!SelectedUsers.Any())
{
<div>No Users</div>
}
else
{
<div>
<ul class="ppt">
#foreach(var u in SelectedUsers.Keys)
{
<li>#u</li>
<image id="#u" #onclick="async ()=>{ await this.DeleteuserEvent.InvokeAsync(u);}" src="/images/icons/icons-remove.png"></image>
}
</ul>
</div>
}
</div>
even adding as an icon and directly linking to said image it not showing up
cs
<i style="background-image:url('/images/icons/icons-remove.png')" #onclick="async ()=>{ await this.DeleteuserEvent.InvokeAsync(u);}" ></i>```

ie11 caching background images while changing styles

I have a DIV which holds background images, and I change them by bootstrap carousel item change by passing data-bg attribute like below:
HTML
<div class="bg-holder" data-bg="bg-1">
<div id="carousel">
<div class="carousel-item active" data-bg="bg-1">
.... some slider content
</div>
<div class="carousel-item" data-bg="bg-2">
.... some slider content
</div>
</div>
</div>
JS
const bgHolder= document.querySelector(".bg-holder");
$('#carousel').on('slide.bs.carousel', function (e) {
bgHolder.dataset.bg = e.relatedTarget.dataset.bg;
})
CSS
.bg-holder[data-bg="bg-1"] {
background-image: url(image1.jpg)
}
.bg-holder[data-bg="bg-2"] {
background-image: url(image2.jpg)
}
I set data-bg="bg-1" by default and then on every carousel change i pass the new data-bg value. it works great in all modern browsers except IE11 which do not refresh the images from css, and it keeps displaying the one i loaded by default. When I open developers tools and uncheck/check the declaration it displays the proper image. Any ideas ?
I test in IE and reproduce the issue. As a workaround, you could set the background-image as inline style of bg-holder and change it on every carousel change according to bg value. The sample code is like below:
HTML:
<div class="bg-holder" style="background-image: url(image1.jpg)">
<div id="carousel">
<div class="carousel-item active" data-bg="bg-1">
.... some slider content
</div>
<div class="carousel-item" data-bg="bg-2">
.... some slider content
</div>
</div>
</div>
JS:
$('#carousel').on('slide.bs.carousel', function (e) {
if (e.relatedTarget.dataset.bg == "bg-2") {
$(".bg-holder").css("background-image", "url(image2.jpg)");
}
else {
$(".bg-holder").css("background-image", "url(image1.jpg)");
}
})
You could also check this online demo in IE 11.

Load div "data" on load

I'm building an image carousel for for EPiServer, it works, but not exactly how I want it to. The current carousel starts spinning after I click the "next" button, before that it only shows one picture. I want it to start spinning directly when the page's loaded. See code for example. Ideas?
<div id="carousel" class="carousel slide" data-ride="carousel" data-interval="#(Model.Interval.GetValueOrDefault(7) * 1000)" #Html.EditAttributes(m => m.ContentArea)>
<div class="carousel-inner">
#for (var index = 0; index < Model.Slides.Count(); index++)
{
var slide = Model.Slides.ElementAt(index);
<div class="item #(index == 0 ? "active" : string.Empty) animated fadeInRight">
#{
Html.RenderPartial(slide.GetCarouselSlidePartialViewName(Html), slide,
new ViewDataDictionary { { "ImageHeight", Model.ImageHeight.GetValueOrDefault(600) }, { "ImageWidth", Model.ImageWidth.GetValueOrDefault(1889) } });
}
</div>
}
</div>
<button href="#carousel" data-slide="next">CLICK ME</button>
#Html.FullRefreshPropertiesMetaData(new[] { "ContentArea" })
So when I click on the button, it starts spinning with the href to the top div, but I want it to start as soon as the page's loaded.
Thanks/
Fredrik
As Eric's Comment to your question, is this a javascript task to start your image carosel.
All EPiserver does is to render your image-carosel with data. the rest is up to your javascript carosel library to handle the interaction/animation.
There are mostly a property on image-carosel libraries that handles if the carosel should start on load or wait for interaction.
All I can help you with, having only the attached code is to tell the javascript to click your button on load. It's not a recomended way to do it, but it solves your problem.
$(document).ready(function() {
$('button[href=#carousel]').click();
});

Adding Title Overlay to Video.js player

I am new to Video.js, but like what I see so far. One thing I have not seen: How to add a title to the top of the player, which will disappear on play, and reappear on pause.
I can see how to tie an action to these events, and I have read about adding elements to the player. For instance (this example is only halfway done):
var myContainer = videoObj.addChild('button');
myContainer.addClass("myContainer");
which I got from: https://github.com/videojs/video.js/blob/master/docs/api/vjs.Component.md
that snippet adds this code:
<div class="vjs-control myContainer" role="button" aria-live="polite" tabindex="0" style="display: block;">
<div class="vjs-control-content">
<span class="vjs-control-text">Need Text</span>
</div>
</div>
But what I want is a simple DIV that will have a title, with code like this:
<div class="myOverlay">
<h2>Title of Video</h2>
</div>
Am I barking up the wrong tree here? Is there a better way to get what I want done?
Thanks in advance,
Bill
Have you tried this videojs plugin?
https://github.com/brightcove/videojs-overlay
You can choose to show the overlay on certain events like start, playing or end of the video.
player = videojs('/path/to/video', options, function() {});
overlay_content = '<div class="myOverlay"><h2>Title of Video</h2></div>';
player.overlay({
overlays: [{
start: 'loadstart',
content: overlay_content,
end: 'playing',
align: 'top'
}, {
start: 'pause',
content: overlay_content,
end: 'playing',
align: 'top'
}]
});

Need the HTML content of the current JQUERY-UI Tab

<div id="tabs">
<ul>
<li>Tab One</li>
<li>Tab Two</li>
<li>Tab Three</li>
</ul>
</div>
I have a tab widget, displaying content from different urls.
I need an expression, to get the contents (HTML string) of the currently displayed content, in the tab panel. Something like
alert($('tabs').tabs('option', 'selectedpanel').innerHTML);
The only reference I have is the JQuery documentation http://api.jqueryui.com/tabs/ , but I could not get an suitable answer from the API documentation there.
Just use the load event of the tabs as below :
<script>
$(function() {
$( "#tabs" ).tabs({
load: function( event, ui ) {
alert(ui.panel.html());
}
});
});
</script>