Struggling with DOM traversing. How can I select the "#img" element? - javascript

I am trying to attach an event listener to multiple buttons, using a for loop. The event function will "flip" my card by hiding the front side.
<div class="team__box">
<div class="front" id="front">
<img
src="/assets/avatar-drake.jpg"
alt="headshot"
class="front__img"
/>
<h3 class="front__name">Drake Heaton</h3>
<p class="front__info">Business Development Lead</p>
</div>
<div class="back hide" id="back">
<h3 class="back__name">Drake Heaton</h3>
<p class="back__quote">
“Hiring similar people from similar backgrounds is a surefire way
to stunt innovation.”
</p>
<div class="back__social">
<a href="#" class="back__social-link"
><img
src="/assets/icon-twitter.svg"
alt="twitter"
class="back__social-img"
/></a>
<a href="#" class="back__social-link"
><img
src="/assets/icon-linkedin.svg"
alt="linkedin"
class="back__social-img"
/></a>
</div>
</div>
<button class="team__btn front__btn" id="btn">
<img
src="/assets/icon-cross.svg"
alt="close button"
class="btn__img"
id="img"
/>
</button>
</div>
<div class="team__box">
<div class="front" id="front">
<img
src="/assets/avatar-griffin.jpg"
alt="headshot"
class="front__img"
/>
<h3 class="front__name">Griffin Wise</h3>
<p class="front__info">Lead Marketing</p>
</div>
<div class="back hide" id="back">
<h3 class="back__name">Griffin Wise</h3>
<p class="back__quote">
“Unique perspectives shape unique products, which is what you need
to survive these days.”
</p>
<div class="back__social">
<a href="#" class="back__social-link"
><img
src="/assets/icon-twitter.svg"
alt="twitter"
class="back__social-img"
/></a>
<a href="#" class="back__social-link"
><img
src="/assets/icon-linkedin.svg"
alt="linkedin"
class="back__social-img"
/></a>
</div>
</div>
<button class="team__btn front__btn" id="btn">
<img
src="/assets/icon-cross.svg"
alt="close button"
class="btn__img"
id="img"
/>
</button>
</div>
Javascript below. It is almost all working, except when I click directly on the "#img" element. I would assume
const btn = document.getElementsByClassName("team__btn");
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function (e) {
console.log(e.target);
let front = e.target.closest("div").firstElementChild;
let back = e.target.closest("div").children[1];
if (e.target !== "img") {
img = e.target.firstElementChild;
} else {
img = e.target;
}
front.classList.toggle("hide");
back.classList.toggle("hide");
if (front.classList.contains("hide")) {
img.src = "./assets/icon-close.svg";
} else {
img.src = "./assets/icon-cross.svg";
}
});
}
Assuming I am clicking directly on the '#img" element, I tried to assign that targetted element to img variable through an if/else statement. Using that, I would expect to be able to reassign the src property of the img variable, depending on whether the front or backside of the card is hidden.
However, when I click directly on the img element I receive the following error:
"Uncaught TypeError: Cannot set properties of null (setting 'src')
at HTMLButtonElement."
What gives?

Replace your line e.target !== "img" to e.target.nodeName !== "IMG".
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", function (e) {
console.log(e.target);
let front = e.target.closest("div").firstElementChild;
let back = e.target.closest("div").children[1];
let img;
if (e.target.nodeName !== "IMG") {
img = e.target.firstElementChild;
} else {
img = e.target;
}
console.log();
front.classList.toggle("hide");
back.classList.toggle("hide");
if (front.classList.contains("hide")) {
img.src = "./assets/icon-close.svg";
} else {
img.src = "./assets/icon-cross.svg";
}
});
}
<div class="team__box">
<div class="front" id="front">
<img src="/assets/avatar-drake.jpg" alt="headshot" class="front__img" />
<h3 class="front__name">Drake Heaton</h3>
<p class="front__info">Business Development Lead</p>
</div>
<div class="back hide" id="back">
<h3 class="back__name">Drake Heaton</h3>
<p class="back__quote">
“Hiring similar people from similar backgrounds is a surefire way
to stunt innovation.”
</p>
<div class="back__social">
<a href="#" class="back__social-link"><img src="/assets/icon-twitter.svg" alt="twitter"
class="back__social-img" /></a>
<a href="#" class="back__social-link"><img src="/assets/icon-linkedin.svg" alt="linkedin"
class="back__social-img" /></a>
</div>
</div>
<button class="team__btn front__btn" id="btn">
<img src="/assets/icon-cross.svg" alt="close button" class="btn__img" id="img" />
</button>
</div>
<div class="team__box">
<div class="front" id="front">
<img src="/assets/avatar-griffin.jpg" alt="headshot" class="front__img" />
<h3 class="front__name">Griffin Wise</h3>
<p class="front__info">Lead Marketing</p>
</div>
<div class="back hide" id="back">
<h3 class="back__name">Griffin Wise</h3>
<p class="back__quote">
“Unique perspectives shape unique products, which is what you need
to survive these days.”
</p>
<div class="back__social">
<a href="#" class="back__social-link"><img src="/assets/icon-twitter.svg" alt="twitter"
class="back__social-img" /></a>
<a href="#" class="back__social-link"><img src="/assets/icon-linkedin.svg" alt="linkedin"
class="back__social-img" /></a>
</div>
</div>
<button class="team__btn front__btn" id="btn">
<img src="/assets/icon-cross.svg" alt="close button" class="btn__img" id="img" />
</button>
</div>

Related

onClick Event Listener inside a while

enter code here
classesFilterWerke = [
'skulptur',
'malerei',
'druck',
'neueMedien',
'sozialkritischs',
'performance',
'installation',
'kunstImÖffentlichenRaum'
];
for( var i = 0; i < classesFilterWerke.length; i++ ) {
iNthChild = i+2
$('.werke-filter button:nth-child('+ iNthChild +')').click(function(){
$('.'+ classesFilterWerke[i] +'').toggle();
})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="werke-filter filter-wrapper">
<p class="float-left">Filter:</p>
<button class="active btn btn-primary-outline">Skulptur</button>
<button class="active btn btn-primary-outline">Malerei</button>
<button class="btn btn-primary-outline">Druck</button>
<button class="btn btn-primary-outline">Neue Medien</button>
<button class="btn btn-primary-outline">Sozialkritisches</button>
<button class="btn btn-primary-outline">Performance</button>
<button class="btn btn-primary-outline">Installation</button>
<button class="btn btn-primary-outline">Kunst im öffentlichen Raum</button>
</div>
<a href="werk-baldachin.php?id=8" class="karte skulptur" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-longboard.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Longboard</h4>
<h5>Skulptur</h5>
</a>
<a href="werk-baldachin.php" class="karte druck" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-schale.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Keramikton Arbeiten</h4>
<h5>Skulptur</h5>
</a>
<a href="werk-baldachin.php" class="karte malerei" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-stehleuchte.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Stehleuchte</h4>
<h5>Skulptur</h5>
</a>
I want to make a filter which toggles elements with a certain class. My problem now is that if I use the jQuery .click Event Listener inside a while loop it doesn't work. If I get the jQuery statement outside of the while loop it works.
NOTE: I haven't used the i variable and the classesFilterWerke (Array) inside the loop because it doesn't work even without.
Relying on index is not the best thing. Your code already had things out of order so it would have a bug. So if you add an attribute we can simplify this code to just select that element.
I am not sure the end goal so I am just toggling a class to show it working.
$('.werke-filter').on("click", "button", function () {
var button = $(this)
var toggles = button.data("toggles")
button.toggleClass("selected")
$(toggles).toggleClass("selected")
})
.selected {
background-color: yellow;
}
.karte {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="werke-filter filter-wrapper">
<p class="float-left">Filter:</p>
<button class="active btn btn-primary-outline" data-toggles=".karte.skulptur">Skulptur</button>
<button class="active btn btn-primary-outline" data-toggles=".karte.malerei">Malerei</button>
<button class="btn btn-primary-outline" data-toggles=".karte.druck">Druck</button>
</div>
<a href="werk-baldachin.php?id=8" class="karte skulptur" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-longboard.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Longboard</h4>
<h5>Skulptur</h5>
</a>
<a href="werk-baldachin.php" class="karte druck" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-schale.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Keramikton Arbeiten</h4>
<h5>Skulptur</h5>
</a>
<a href="werk-baldachin.php" class="karte malerei" data-aos="fade-up">
<div class="karte-img">
<img src="../assets/img/werke/thumb-skulptur-stehleuchte.jpg" alt="">
</div>
<div class="stroke-bottom"></div>
<h4>Stehleuchte</h4>
<h5>Skulptur</h5>
</a>

how to use same jQuery function on multiple group of lists

I have Unordered list, and each item of the list has a list of images. I wrote a jQuery function to operate slider using prev and next. The function working write when there is only one list of images. Nonetheless, when I have list and each item has list of images when ever I clicked on any slider only the first slider is working regardless on which slider I clicked. my question is, How can I modify the jQuery function to operate only for the slider that I clicked on and not other sliders for other group of images.
Here is the html code:
<ul class="results">
<li class="result-row">
<!-- image box -->
<a href="#">
<div class="result-image-act" >
<img src="1.jpg" class="active">
<img src="2.jpg">
<img src="3.jpg">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
</div>
<div class="swipe-wrap">
<div class="swipe-wrap-lef">
<a href="#">
<div class="swipe-prev">
<p><</p>
</div>
</a>
</div>
<div class="swipe-wrap-rig">
<a href="#">
<div class="swipe-next">
<p>></p>
</div>
</a>
</div>
</div>
</a>
</li>
<!-- -->
<li class="result-row">
<a href="#">
<div class="result-image-act">
<img src="1.jpg" class="active">
<img src="2.jpg">
<img src="3.jpg">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
</div>
<div class="swipe-wrap">
<div class="swipe-wrap-lef">
<a href="#">
<div class="swipe-prev">
<p><</p>
</div>
</a>
</div>
<div class="swipe-wrap-rig">
<a href="#">
<div class="swipe-next">
<p>></p>
</div>
</a>
</div>
</div>
</a>
</li>
</ul>
Here is the jQuery function:
$(document).ready(function() {
$('.swipe-prev').click(function(){
console.log("Prev"); // Print "Prev" on click swipe-prev
var prevImg = $('img.active').prev('.result-image-act img');
if(prevImg.length == 0) {
prevImg = $('.result-image-act img:last');
}
$('img.active').removeClass('active');
prevImg.addClass('active');
});
$('.swipe-next').click(function() {
console.log("Next"); // Print "Next" on click swipe-next
var nextImg = $('img.active').next('.result-image-act img');
if(nextImg.length == 0) {
nextImg = $('.result-image-act img:first');
}
$('img.active').removeClass('active');
nextImg.addClass('active');
});
});
You may reduce everything to only one event handler.
$('.swipe-prev, .swipe-next').on('click', function (e) {
var op = ($(this).is('.swipe-prev')) ? 'prev' : 'next';
var firtOrlast = ($(this).is('.swipe-prev')) ? 'last' : 'first';
var imgList = $(this).closest('.result-row');
var currImg = imgList.find('.result-image-act img.active');
var nextImg = currImg[op]();
if (nextImg.length == 0) {
nextImg = imgList.find('.result-image-act img:' + firtOrlast);
}
currImg.removeClass('active');
nextImg.addClass('active');
});
.active {
padding: 3px;
border: 1px solid #021a40;
background-color: #ff0;
}
.swipe-wrap {
display: inline-flex;
}
.swipe-wrap > div {
padding-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="results">
<li class="result-row">
<!-- image box -->
<a href="#">
<div class="result-image-act">
<img src="https://dummyimage.com/100x100/000/fff&text=1" class="active">
<img src="https://dummyimage.com/100x100/000/fff&text=2">
<img src="https://dummyimage.com/100x100/000/fff&text=3">
<img src="https://dummyimage.com/100x100/000/fff&text=4">
</div>
<div class="swipe-wrap">
<div class="swipe-wrap-lef">
<a href="#">
<div class="swipe-prev">
<p><</p>
</div>
</a>
</div>
<div class="swipe-wrap-rig">
<a href="#">
<div class="swipe-next">
<p> ></p>
</div>
</a>
</div>
</div>
</a>
</li>
<!-- -->
<li class="result-row">
<a href="#">
<div class="result-image-act">
<img src="https://dummyimage.com/100x100/000/fff&text=1" class="active">
<img src="https://dummyimage.com/100x100/000/fff&text=2">
<img src="https://dummyimage.com/100x100/000/fff&text=3">
<img src="https://dummyimage.com/100x100/000/fff&text=4">
</div>
<div class="swipe-wrap">
<div class="swipe-wrap-lef">
<a href="#">
<div class="swipe-prev">
<p><</p>
</div>
</a>
</div>
<div class="swipe-wrap-rig">
<a href="#">
<div class="swipe-next">
<p>></p>
</div>
</a>
</div>
</div>
</a>
</li>
</ul>
Your problem is coming from how you find the active image. There are presumably multiples, but you want to find the one related to whatever was clicked. Change lines like this:
$('img.active')
to something like:
$(this).closest("ul.results").find("img.active")
to get the img.active within the clicked ul.

Hide parent div class if child div class does not have content when there are multiple parent divs with the same class name

I have a slider where some of the images in the slider can have an optional photo- credit containing text or link in a popper. I would like to iterate over all of the popper instances and if all of the p tags in the .photo-credit p class are empty, then hide only that instance of the parent popper. I've tried to piece together a solution from some other posts, but have not been able to get it to work. The code I have does not hide a popper if all p tags are empty for that popper. I'm a JavaScript newbie and would appreciate any help.
HTML
<div class="slider-wrapper">
<!--Required Root Element-->
<div class="slider">
<!--Required List Element-->
<div class="slider-list">
<div class="slider-item">
<div class="slider-image-container"><img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/image1.jpg" /></div>
<div class="slider-content-container">
<h1>B LIne: The Place to Be</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p><p>A photo credit.</p></p>
<p></p>
</div>
</div><div class="slider-item">
<div class="slider-image-container"><img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/anotherimage.jpg" /></div>
<div class="slider-content-container">
<h1>July 4th: You missed it!</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p></p>
<p></p>
</div>
</div><div class="slider-item">
<div class="slider-image-container"><img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/anotherimage.jpg" /></div>
<div class="slider-content-container">
<h1>Festival coming Aug. 31st!</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p></p>
<p></p>
</div>
</div>
</div>
</div>
<img src="http://www.someurl.com/images/icons/icon-chevron-left-slider.svg">
<img src="http://www.someurl.com/images/icons/icon-chevron-right-slider.svg">
<p class="slider-pagination"></p>
</div>
JavaScript
$('.popper').each(function () {
//var $thisPopper = $(this);
var hasContent = 0;
$('.photo-credit p').each(function () {
if($(this).html().length > 0) {
hasContent++;
}
});
if(hasContent > 0){
//$thisPopper.hide();
$(this).hide();
}
});
You were on the right direction. However a couple mistakes in your javascript.
You tried to target all the div with "popper" class. However, the div with "popper" and "photo-credit" are on the same level. Why not targeting their parent div instead?
Try this code. It's been tested (Link to jsfiddle)
$('.slider-item').each(function () {
var thisSilerItem = $(this);
var hasContent = 0;
thisSilerItem.find('.photo-credit p').each(function () {
if($(this).html().length > 0) {
hasContent++;
}
});
if(hasContent <= 0){
thisSilerItem.find('.popper').hide();
}
});
Edit:
Bonus:
If your page has a large amount of sliders, this jquery solution will cause some UX issues ("jumpy" div on/after page load)
Try a CSS only solution.
When you render your DOM elements. Add a class to "popper" div if the content of "photo-credit" is empty.
<div class="popper hide">
// img
</div>
Then in your CSS, add
.popper.hide { display: none; }
It's hard to fully gather what you want to do, but if I understand correctly...
$('.popper').each(function () {
var photoCredit = $(this).find(".photo-credit p")
if ( $(photoCredit).is(':empty') ){
$(this).hide();
}
});
It's worth pointing out that CSS4 developers are working on a 'has' selector but as of July 2017 there is no support for any browser just yet.
It is expected to work in the following manner:
.popper:has(> p:empty) { display: none }
I hope this helps... :)
You can check this code.
$.each($('.popper'), function (index, popper) {
var isEmptry = true;
$.each($(popper).next('.photo-credit').children(), function (index, ptag) {
if ($.trim($(ptag).html()) != '')
isEmptry = false;
});
if (isEmptry)
$(popper).hide();
});
Working code
$.each($('.popper'), function (index, popper) {
var isEmptry = true;
$.each($(popper).next('.photo-credit').children(), function (index, ptag) {
if ($.trim($(ptag).html()) != '')
isEmptry = false;
});
if (isEmptry)
$(popper).hide();
});
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div class="slider-wrapper">
<!--Required Root Element-->
<div class="slider">
<!--Required List Element-->
<div class="slider-list">
<div class="slider-item">
<div class="slider-image-container">
<img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/image1.jpg" />
</div>
<div class="slider-content-container">
<h1>B LIne: The Place to Be</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p>
<p>A photo credit.</p>
</p>
<p></p>
</div>
</div>
<div class="slider-item">
<div class="slider-image-container">
<img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/anotherimage.jpg" />
</div>
<div class="slider-content-container">
<h1>July 4th: You missed it!</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p></p>
<p></p>
</div>
</div>
<div class="slider-item">
<div class="slider-image-container">
<img class="slider-image" src="http://www.someurl.com/Images/Homepage Images/Slider/anotherimage.jpg" />
</div>
<div class="slider-content-container">
<h1>Festival coming Aug. 31st!</h1>
<div class="learn-more">Learn More</div>
</div>
<div class="popper">
<img data-toggle="popover" class="photo-credit-icon" src="http://www.someurl.com/icon-photography.svg" alt="photo credit" />
</div>
<div class="photo-credit hide">
<p></p>
<p></p>
</div>
</div>
</div>
</div>
<a href="#" class="slider-control-prev">
<img src="http://www.someurl.com/images/icons/icon-chevron-left-slider.svg"></a>
<a href="#" class="slider-control-next">
<img src="http://www.someurl.com/images/icons/icon-chevron-right-slider.svg"></a>
<p class="slider-pagination"></p>
</div>

Jquery search and display images based on class

I'd like to be able to search and display these based on the class attributes, such as "kitchen". I can't find anything on searching by the class, only text and such. Or if anyone has a recommendation on a better way to search and display images. Any help would be greatly appreciated.
<form id="live-search" method="post">
<fieldset>
<input type="text" class="text-input" id="filter" />
<span id="filter-count"></span>
</fieldset>
</form>
<br/>
<br/>
<div id="gallery">
<div id="item" class="#1 Category-Home Home">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
<div id="item" class="#2 Category-Kitchen Kitchen">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
<div id="item">
<div class="#3 Category-Outdoors Outdoors">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
</div>
<div id="item" class="#4 Category-Sports Sports">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
</div>
$(document).ready(function() {
$("#filter").keyup(function() {
});
});
https://jsfiddle.net/sgrg4b06/
So first, thing, remove all the duplicate ID's all over the place. That will only cause headaches. ID's are unique identifiers. Second, see the below. Pretty well commented. It IS case sensitive.
// then, on entering text...
$("#filter").on("keyup", function() {
if ($(this).val().length > 0) {
// hide everything,
$(".item").hide();
// get the text in the input
var mySelector = $(this).val();
// show any class that contains the input
var myImgs = $("[class*='"+mySelector+"' i]");
myImgs.show();
} else {
$(".item").show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="live-search" method="post">
<fieldset>
<input type="text" class="text-input" id="filter" />
<span id="filter-count"></span>
</fieldset>
</form>
<br/>
<br/>
<div id="gallery">
<div id="image-1" class="item #1 Category-Home Home">
<a target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
<div id="image-2" class="item #2 Category-Kitchen Kitchen">
<a target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
<div id="image-3" class="item #3 Category-Outdoors Outdoors">
<a target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
</div>
<div id="image-4" class="item #4 Category-Sports Sports">
<a target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x150" />
</a>
</div>
Your comment about case insensitivity made me curious. If you google jquery attribute selector case insensitivity, there is a lot of cool stuff to be found. The most simple solution was to change the selector, as above -- note that there is now a
$("[class*='"+mySelector+"' i]")
The i on the tail of the selector indicates case insensitivity.
FURTHER CHANGES -- now, when the input has no value, all image divs are shown. And, by default, they're all visible.
I removed all id, but added classes into divs attr.
Below is working solution (case insensitive).
Also I changed Your images a little bit, for You can see difference.
$(document).ready(function() {
var images = $(".item") //contain all unfiltered images
$("#filter").on("change paste keyup", function(){
$.each(images, function(i, l){
$(l).hide();
}); //hide all images
searchValue = $("#filter").val(); //get entered value of input field
searchValueRE = new RegExp(searchValue, "i"); //convert search value into RegExp
output = $.grep(images, function (n) {return searchValueRE.test(n.className); }); //Returns array that matches input value
$.each(output, function(i, l){
$(l).show();
}); //show matched images
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="live-search" method="post">
<fieldset>
<input type="text" class="text-input" id="filter" />
<span id="filter-count"></span>
</fieldset>
</form>
<br/>
<br/>
<div id="gallery">
<div class="item #1 Category-Home Home">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x151" />
</a>
</div>
<div class="item #2 Category-Kitchen Kitchen">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x152" />
</a>
</div>
<div class="item #3 Category-Outdoors Outdoors">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x153" />
</a>
</div>
<div class="item #4 Category-Sports Sports">
<a id="#image-link" target="_blank" a href="">
<img class="img_item"><img src="http://placehold.it/150x154" />
</a>
</div>
</div>
1) You have ids repeated, ids are unique, I have changed them to class
2) You have:
<img class="img_item"><img src="http://placehold.it/150x150" />
The first img tag doesn't contain and image, either change it to a div (dont forget to close it) or just remove it. (In below example i changed to div)
3) Rather than using a class it makes more sense to use the data attribute. I have added a data attribute to each .item.
4) Using jQuery, we can loop through each item and check if the data-category contains the value of the search field. If it doesn't we hide it.
5) If the search box is empty, we show everything.
Hope this helps.
$("#filter").keyup(function() {
filterString = $("#filter").val().toLowerCase();
if (filterString.length < 1) {
//alert("showing all");
$(".item").slideDown('slow');
} else {
$(".item").each(function() {
if ($(this).data("category").toLowerCase().indexOf(filterString) == -1) {
$(this).slideUp('slow');
} else {
$(this).slideDown('slow');
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<form id="live-search" method="post">
<fieldset>
<input type="text" class="text-input" id="filter" />
<span id="filter-count"></span>
</fieldset>
</form>
<br/>
<br/>
<div id="gallery">
<div class="item" data-category="Home">
<a class="#image-link" target="_blank" a href="">
<div class="img_item"><img src="http://placehold.it/150x150" /></div>
</a>
</div>
<div class="item" data-category="Kitchen">
<a class="#image-link" target="_blank" a href="">
<div class="img_item"><img src="http://placehold.it/150x150" /></div>
</a>
</div>
<div class="item" data-category="Outdoors">
<a class="#image-link" target="_blank" a href="">
<div class="img_item"><img src="http://placehold.it/150x150" /></div>
</a>
</div>
<div class="item" data-category="Sports">
<a class="#image-link" target="_blank" a href="">
<div class="img_item"><img src="http://placehold.it/150x150" /></div>
</a>
</div>
</div>

Adding descriptions inside a blueimp gallery

I am using a BlueImp Gallery to add lightboxes to my image gallery. So, when you click on an image thumbnail, it launches a lightbox with a larger version of the image etc.
I also want to add in some descriptive text and a button to each slide of the lightbox, but I am having trouble making it work. It won't show the placeholder descriptions that I have added in.
Here's what I have so far;
HTML:
<div id="blueimp-gallery" class="blueimp-gallery">
<!-- The container for the modal slides -->
<div class="slides"></div>
<!-- Controls for the borderless lightbox -->
<h3 class="title"></h3>
<p class="description"></p>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" aria-hidden="true">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body next"></div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left prev">
<i class="glyphicon glyphicon-chevron-left"></i>
Previous
</button>
<button type="button" class="btn btn-primary next">
Next
<i class="glyphicon glyphicon-chevron-right"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="links">
<div class="row prints">
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm3.staticflickr.com/2843/10406026526_4cd1b56391.jpg" title="Ballooning" data-description="This is a banana." data-gallery>
<img src="http://farm8.staticflickr.com/7389/10404414563_0914b69e0e.jpg" alt="Ballooning">
</a>
<h3>Ballooning</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm6.staticflickr.com/5547/10406009404_c197c2221b.jpg" title="Clearing" data-description="This is a apple." data-gallery>
<img src="http://farm6.staticflickr.com/5490/10404414523_745ea3065d.jpg" alt="Clearing">
</a>
<h3>Clearing</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm6.staticflickr.com/5510/10406026066_7f95a075ee.jpg" title="Sky/Sea" data-description="This is a cherry." data-gallery>
<img src="http://farm4.staticflickr.com/3769/10404249505_d767f7c420.jpg" alt="Sky/Sea">
</a>
<h3>Sky/Sea</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm4.staticflickr.com/3678/10406009004_5c625e2028.jpg" title="Lights" data-description="This is a grapefruit." data-gallery>
<img src="http://farm3.staticflickr.com/2814/10404249395_9e4cae5bc7.jpg" alt="Lights">
</a>
<h3>Lights</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm6.staticflickr.com/5538/10406019875_8424fbee11.jpg" title="Silhouettes" data-description="This is a orange." data-gallery>
<img src="http://farm8.staticflickr.com/7343/10404255766_d808d1902d.jpg" alt="Silhouettes">
</a>
<h3>Silhouettes</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm4.staticflickr.com/3682/10406009134_3b666324ff.jpg" title="Sway" data-description="This is a kiwi." data-gallery>
<img src="http://farm6.staticflickr.com/5516/10404249545_7efb481042.jpg" alt="Sway">
</a>
<h3>Sway</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm8.staticflickr.com/7425/10406019935_1def1e0c09.jpg" title="Sunset" data-description="This is a grape." data-gallery>
<img src="http://farm3.staticflickr.com/2810/10404249465_0124b7f3e5.jpg" alt="Sunset">
</a>
<h3>Sunset</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm6.staticflickr.com/5532/10406009324_4cd1b56391.jpg" title="Lighthouse" data-description="This is a strawberry." data-gallery>
<img src="http://farm6.staticflickr.com/5543/10404240054_6261498220.jpg" alt="Lighthouse">
</a>
<h3>Lighthouse</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<div class="caption">
<a href="http://farm4.staticflickr.com/3747/10406026506_6a4dbf2df0.jpg" title="Slabs"data-description="This is a pineapple." data-gallery>
<img src="http://farm8.staticflickr.com/7345/10404249655_7512bf6565.jpg" alt="Slabs">
</a>
<h3>Slabs</h3>
<p>from $18.00</p>
<p>Find out more</p>
</div>
</div>
</div>
</div>
</div>
CSS:
.blueimp-gallery > .description {
position: absolute;
top: 30px;
left: 15px;
color: red;
display: none;
}
.blueimp-gallery-controls > .description {
display: block;
}
JS:
blueimp.Gallery(
document.getElementById('links'),
{
onslide: function (index, slide) {
var text = this.list[index].getAttribute('data-description'),
node = this.container.find('.description');
node.empty();
if (text) {
node[0].appendChild(document.createTextNode(text));
}
}
}
);
And in my body (gallery.js is the file where I've added the above JS):
<script src="//code.jquery.com/jquery.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="lib/fancybox/jquery.fancybox.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
<script src="js/bootstrap-image-gallery.min.js"></script>
<script src="js/gallery.js"></script>
Any pointers on where I've gone wrong would be much appreciated!
You can pass any needed data on a element, and then display it in the gallery.
I spend a lot of time trying to find an answer, so I'll leave it here.
Here is an example:
HTML:
<div id="blueimp-gallery" class="blueimp-gallery">
<div class="slides"></div>
<h3 class="title"></h3>
<p class="description"></p>
<p class="example"></p>
...
</div>
------
<div id="links">
Banana
Apple
</div>
JS:
document.getElementById('links').onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement,
link = target.src ? target.parentNode : target,
options = {
index: link, event: event,
onslide: function (index, slide) {
self = this;
var initializeAdditional = function (index, data, klass, self) {
var text = self.list[index].getAttribute(data),
node = self.container.find(klass);
node.empty();
if (text) {
node[0].appendChild(document.createTextNode(text));
}
};
initializeAdditional(index, 'data-description', '.description', self);
initializeAdditional(index, 'data-example', '.example', self);
}
},
links = this.getElementsByTagName('a');
blueimp.Gallery(links, options);
};
CSS:
You can use .scss to refactor it, but it's just for example
.blueimp-gallery > .description, .blueimp-gallery > .example {
position: absolute;
top: 30px;
left: 15px;
color: #fff;
display: none;
}
.blueimp-gallery-controls > .description, .blueimp-gallery-controls > .example {
display: block;
}
Sorry if to late but I find a way to do this, only change the JS from:
blueimp.Gallery(
document.getElementById('links'),
{
onslide: function (index, slide) {
var text = this.list[index].getAttribute('data-description'),
node = this.container.find('.description');
node.empty();
if (text) {
node[0].appendChild(document.createTextNode(text));
}
}
}
);
to this:
blueimp.Gallery(
document.getElementById('links'),
{
onslide: function (index, slide) {
var text = this.list[index].getAttribute('data-description'),
node = this.container.find('.description');
node.empty();
if (text) {
node[0].innerHTML = text;
}
}
}
);
blueimp.Gallery(
document.getElementById('links'), {
onslide: function (index, slide) {
var text = this.list[index].getAttribute('data-description'),
node = this.container.find('.description');
node.empty();
if (text) {
node[0].appendChild(document.createTextNode(text));
}
}
});
http://jsfiddle.net/2B3bN/25/
Have a look at this one, it is a working one.
Just check what you've done wrong compared to mine.
use
document.getElementById('links').getElementsByTagName('a') or .children()
That works only for the first link...
I am trying to get it to work with html in the data-description. I have it working and pulling in the decsription text, but how do you parse the html to work as a link?
http://jsfiddle.net/LXp76/
<img src="http://lorempixel.com/80/80/" alt="" >
here it is working with FancyBox, http://jsfiddle.net/yShjB/2/
but I would much rather use the BlueImp Gallery..

Categories