Multiple Featherlight galleries on one page without unique classes - javascript

How can I call multiple galleries using Featherlight Gallery without having to use unique classes?
I tried
if($('.image-gallery').length) {
$('.image-gallery').featherlightGallery({
variant: 'gal',
filter: $(this).find('.featured-image')
});
}
but I don't think filter works the way I think it does.
Currently - it loads each item on the page in the same gallery lightbox. I want a unique lightbox gallery for each parent .image-gallery. In otherwords, clicking the arrows in the first lightbox gallery should not show me photos from the second one.
<div class="image-gallery">
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
</div>
<div class="image-gallery">
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
<div class="featured-image" data-featherlight="http://imgurl"><img /></div>
</div>
Here is a Fiddle.

You're pretty close. Problem is that by using data-featherlight, you are using the auto binding, which is not what you want. Turn the auto binding off, or change your markup, like this
Best way is to bind them individually. I didn't test (since you didn't provide a working example), but this should work:
$('.image-gallery).each(function(_i, gallery)) {
$(gallery).featherlightGallery({
variant: 'gal',
filter: '.featured-image'
});
})
Note: filter is a jQuery selector (string).

Related

How should I not load the images with broken link?

I'm working on a feature, in which images are being rendered from the servers. I was working on aligning the images but found that there is a lot of white space. This was the reason, due to loading of images with a broken link.
HTML :
<div class="image-result" *ngIf="Display('images')">
<div class="col-sm-3" *ngFor="let item of items$|async">
<a href="{{item.link}}">
<figure>
<img class="res-img" src="{{item.link}}" onerror="this.style.display='none'">
</figure>
</a>
</div>
</div>
I have used onerror="this.style.display='none'" to solve the problem, but leaves a lot of white space when images are being loaded from the server. Is there any solution for it like to remove img tag whenever a image with a broken link has been detected ? I have gone through stackoverflow before asking question, but I'm not able to solve this problem. It would be great if someone can help me out. Thanks! :)
Instead of onerror="this.style.display='none'" to hide an image, you can use onerror="this.parentNode.removeChild(this)" to remove the image tag altogether.
If you want to remove the entire column, in your specific case you can do the following.
var colEl = this.parentNode.parentNode.parentNode;
colEl.parentNode.removeChild(colEl);
Or, in your HTML:
onerror="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode)"
You should probably move that to some JavaScript function and attach your handler by saying
element.addEventListener('error', function() { /* ... */ });
References: parentNode, removeChild, addEventListener.
If you don't care about supporting Internet Explorer, you can also use remove instead of doing the parentNode.removeChild trickery. That would be particularly useful for reducing the code length in your onerror attribute, would you choose to use it, but I don't recommend that.
A more angular-way of doing this would be:
<img src="{{item.link}}" (error)="item.brokenImage=true">
So you would have:
<div class="col-sm-3" *ngFor="let item of items$|async">
<div *ngIf="!item.brokenImage">
<a href="{{item.link}}">
<figure>
<img class="res-img" [src]="item.link" (error)="item.brokenImage=true">
</figure>
</a>
</div>
</div>
You need to listen for the error event of the image element, and assign a boolean on whether the image loaded successfully or not. Then, depending on that value angular will either show the image with the div, or remove it from the DOM.

Angular: Using $last to get last element visible using ng-show

So I have an ng-repeat container div inside which I have a bunch of images.
For each image, there is a div next to it. I want only the div of the final image to be visible and I achieve this using $last. This works like a charm.
Now I have a filter button in the page also, and when this button is clicked some of these images get hidden. This show/hide is done using ng-show on the image tag.
What I want is that when the filter button is clicked and some of the images are hidden, I want the div next to the final visible image to get shown. Seems like $last is not aware of the ng-show/hide value. How can I handle it so that the div next to the last visible image is still shown?
<div class='container' ng-repeat="image in album">
<div class='wrapper' ng-show="getFilterValue(image.imageId)">
<div><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>
Any help is greatly appreciated!
Instead of using ng-show you could filter the ng-repeat using angular's built in ng-repeat filter. If your getFilterValue function returns a boolean this should work for you. Then your $last should know what is truly last based on what meets the filter criteria.
<div class='container' ng-repeat="image in album | filter:getFilterValue(image.imageId)">
<div class='wrapper'>
<div><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>
Try putting the ng-show on the image rather than the whole div wrapper:
<div class='container' ng-repeat="image in album">
<div class='wrapper'>
<div ng-show="getFilterValue(image.imageId)"><img src='{{image.src}}'></div>
<div class='embellish-end' ng-class='{'hidden':!$last}'>The End</div>
</div>
</div>
Unrelated: use ng-src rather than src when using angularized image sources to avoid browser errors.

Fading Images with links

I have this code for the header
<div id="header">
<IMG SRC="http://danithemes.fanscity.eu/shugar/wp-content/uploads/2014/11/header-principal.png">
</div>
And this code for the main menu
<div id="menu">
Link One,
Link Two,
Link Three
</div>
I want the header image to fade into another image through the main menu links. Is this possible? Thanks.
First of all most W3C folks will get mad at you for this line <div id="header">
Anything syntactically named with an id the same as a generic HTML object tag needs to just be that tag. Anything good enough to give an id of id='header' should probably just be a <header> tag.
Secondly, I am unsure what the question is asking fully so let's go with something not yet said. #Parody showed a fiddled way of having the images change on click. The part of your question that said I want the header image to fade into another image through the main menu links. Is this possible? is difficult to understand so I am going to assume that you want some kind of event to trigger the changing of the images? There are many ways to do this but the best of which (especially for beginning programmers) is to use Bootstrap version 3.0+ since it comes with HTML driven stuff that usually requires JavaScript/JQuery to accomplish.
If you don't want to use Bootstrap then that's fine here is an example of how to use a hover event to trigger the change using JQuery...
HTML
<div id="header">
<img src="http://danithemes.fanscity.eu/shugar/wp-content/uploads/2014/11/header-principal.png" />
</div>
<div id="menu">
Link One
Link Two
Link Three
</div>
JAVASCRIPT/JQUERY
$(".navLink").each(function() {
$(this).hover(function() {
$("#header img").css({"background-image":"url($(this).attr('data-image'))"});
});
});

jQuery click function affecting multiple divs

I'm trying to use jQuery's click function to apply a hover state to a selected div, without differentiating the div's in the JavaScript. I'm currently using:
$(document).ready(function(){
$(".project").click(function() {
$("a.expand").removeClass("hovered");
$("a.expand").addClass("hovered");
$(".project_full").hide();
var selected_tab = $(this).find("a").attr("href");
$(selected_tab).fadeIn();
return false;
});
With the HTML:
<div class="project first project_gizmoscoop">
<div class="title">
GizmoScoop!
<div class="date">2012</div>
</div>
<a class="expand" title="(Caption)" href="#project_1">GizmoScoop!</a>
</div>
<div class="project project_sc">
<div class="title">
Striking Code
<div class="date">2011</div>
</div>
<a class="expand" title="(Caption)" href="#project_2">Striking Code</a>
</div>
The .hovered class is applied to the clicked link (specific styles from an external CSS file). However, everything is being chosen. (See http://www.codeisdna.com for an example).
I know what I'm doing wrong (I should be specifying the individual ID's or using HTML5 data attributes), but I'm stuck unnecessarily. I feel like a complete newb right now, that I can't do something this simple (although I've done more advanced stuff).
You simply need to take advantage of jQuery's flexibility (and good programming practice) and reduce your scope accordingly. You're already doing something similar with your variable definition. For example, to target only those a.expand elements inside the instance of .project that's clicked:
$(".project").click(function() {
$(this).find("a.expand").removeClass("hovered");
...
});
$(".expand").click(function() {
$(this).addClass("hovered");
..
});

jQuery Masonry remove function example

I have implemented jQuery masonry to our site and it works great. Our site is dynamic and users must be able to add/remove masonry box's. The site has an add example but no remove example. Our db is queried returning x number of items. Looping through they are loaded and displayed. Here's a code sample: (we are use F3 framework and the F3:repeat is it's looping mechanism.).
<div id="container" class="transitions-enabled clearfix" style="clear:both;">
<F3:repeat group="{{#productItems}}" value="{{#item}}">
<div id="{{#item.itemId}}">
<div class="box">
<div class="view"> <!-- for css -->
<a onclick='quickRemove("{{#item.itemId}}")>
<img src="{{#item.pic}}" />
</a>
</div>
<p>
{{#item.title}}
</p>
</div>
</div>
</F3:repeat>
</div>
In the javascript code the item id number is unique and is passed into the function. It's also the div id# to distinguish each box. I've tried various combinations and methods but can't seem to get this to work.
function quickRemove(item){
var obj = $('#'+item+'').html(); // item is the product id# but also the div id#
$('#container').masonry('remove',obj);
$('#container').masonry('reloadItems');
$('#container').masonry('reload');
}
Has anyone out there successfully removed an item and how did you do it?
Thx.
Currently you appear to be passing a string full of html to the masonry remove method. Pass it the actual jQuery wrapped element by not including .html()
function quickRemove(item){
var obj = $('#'+item+''); // item is the product id# but also the div id#
$('#container').masonry('remove',obj);
$('#container').masonry('reloadItems');
$('#container').masonry('reload');
}

Categories

Resources