nathananderson nathananderson - 4 months ago 6
Javascript Question

Jquery custom sorting issue

I have a page that loads photos on page load from an API.

** Edit: Here is a CodePen with the page, error happing there: http://codepen.io/nathan-anderson/pen/GqXbvK

When initially loading the page I use this to call on the info and use the lightgallery plugin:

// ----------------------------------------------------------------//
// ---------------// Unsplash Photos //---------------//
// ----------------------------------------------------------------//
function displayPhotos(data) {
var photoData = '';
$.each(data, function (i, photo) {
photoData += '<a class="tile"' + 'data-sub-html="#' + photo.id + '"'+ 'data-src="' + photo.urls.regular + '">' + '<img alt class="photo" src="' + photo.urls.regular + '">' + '<div class="caption-box" id="' + photo.id + '">' + '<h1 class="photo-title">' + 'Photo By: ' + photo.user.name + '</h1>' + '<p class="photo-description"> Description: Awesome photo by ' + photo.user.name + ' (aka:' + '<a target="_blank" href="' + photo.links.html + '">' + photo.user.username + ')</a>' + ' So far this photo has ' + '<span>' + photo.likes + '</span>' + ' Likes.' + ' You can download this photo if you wish, it has a free <a target="_blank" href="https://unsplash.com/license"> Do whatever you want </a> license. <a target="_blank" href="' + photo.links.download + '"><i class="fa fa-download" aria-hidden="true"></i> </a> </p>' + '</div>' + '</a>';
});
// Putitng into HTML
$('#photoBox').html(photoData);

//--------//
// Calling Lightbox
//--------//
$('#photoBox').lightGallery({
selector: '.tile',
download: false,
counter: false,
zoom: false,
thumbnail: false,
mode: 'lg-fade'
});
} // End Displayphotos function

// Show popular photos on pageload
$.getJSON(unsplashAPI, popularPhotos, displayPhotos);


I have multiple buttons for showing different orders of the photos. The API grabs different photos based on the "order_by" option.

This is my code to show the different sections:

var popularPhotos = {
order_by: "popular",
format: "json"
};
var latestPhotos = {
order_by: "latest",
format: "json"
};
var oldestPhotos = {
order_by: "oldest",
format: "json"
};
// Button Click Changes
$('button').click(function () {
$('button').removeClass("active");
$(this).addClass("active");
}); // End button

// Show Popular Photos
$('#popular').click(function () {
$.getJSON(unsplashAPI, popularPhotos, displayPhotos);
}); // End button
// Show latest Photos
$('#latest').click(function () {
$.getJSON(unsplashAPI, latestPhotos, displayPhotos);
}); // End button
// Show oldest Photos
$('#oldest').click(function () {
$.getJSON(unsplashAPI, oldestPhotos, displayPhotos);
}); // End button


This does load the new photos on button click but it breaks the function of the lightbox plugin.

Any thoughts? Anyone else running into this?

-- Thanks

Answer

So, the reason is a known issue with the library when attaching lightGallery without properly destroying previous listeners:

A soln in this case is a simple destroy before reinitialising it inside the displayPhotos function.

Just declare a variable gallery in outside scope like : var gallery;

then update the displayPhotos function reinit like:

//destroy if existing
if(gallery) gallery.data('lightGallery').destroy(true);
//initialise the plugin
gallery = $('#photoBox').lightGallery({
    selector: '.tile',
    download: false,
    counter: false,
    zoom: false,
    thumbnail: false,
    mode: 'lg-fade'
});

Updated CodePen: http://codepen.io/alokrajiv/pen/pbOXmp

WORKING SNIPPET HERE:

// ----------------------------------------------------------------//
// ---------------// Variables //---------------//
// ----------------------------------------------------------------//
var unsplashAPI = "https://api.unsplash.com/users/nathananderson/photos/?client_id=1fc3cf0554dd08f8491af5cd37ac945bebde6b5032613d61419f2b92ddde1d9a&per_page=20";
var popularPhotos = {
  order_by: "popular",
  format: "json"
};
var latestPhotos = {
  order_by: "latest",
  format: "json"
};
var oldestPhotos = {
  order_by: "oldest",
  format: "json"
};

// ----------------------------------------------------------------//
// ---------------// Unsplash Photos //---------------//
// ----------------------------------------------------------------//
var gallery;

function displayPhotos(data) {
    var photoData = '';
    $.each(data, function(i, photo) {
      photoData += '<a class="tile"' + 'data-sub-html="#' + photo.id + '"' + 'data-src="' + photo.urls.regular + '">' + '<img alt class="photo" src="' + photo.urls.regular + '">' + '<div class="caption-box" id="' + photo.id + '">' + '<h1 class="photo-title">' + 'Photo By: ' + photo.user.name + '</h1>' + '<p class="photo-description"> Description: Awesome photo by ' + photo.user.name + ' (aka:' + '<a target="_blank" href="' + photo.links.html + '">' + photo.user.username + ')</a>' + ' So far this photo has ' + '<span>' + photo.likes + '</span>' + ' Likes.' + ' You can download this photo if you wish, it has a free <a target="_blank" href="https://unsplash.com/license"> Do whatever you want </a> license. <a target="_blank" href="' + photo.links.download + '"><i class="fa fa-download" aria-hidden="true"></i> </a> </p>' + '</div>' + '</a>';
    });
    // Putitng into HTML
    $('#photoBox').html(photoData);
    //-----------------------------------//
    // -------  Calling Lightbox ------- //
    //-----------------------------------//
    if (gallery) gallery.data('lightGallery').destroy(true);
    gallery = $('#photoBox').lightGallery({
      selector: '.tile',
      download: false,
      counter: false,
      zoom: false,
      thumbnail: false,
      mode: 'lg-fade'
    });
  } // End Displayphotos function

// Show popular photos on pageload
$.getJSON(unsplashAPI, popularPhotos, displayPhotos);


// Button Click Changes
$('button').click(function() {
  $('button').removeClass("active");
  $(this).addClass("active");
}); // End button

// Show Popular Photos
$('#popular').click(function() {
  $.getJSON(unsplashAPI, popularPhotos, displayPhotos);
}); // End button
// Show latest Photos
$('#latest').click(function() {
  $.getJSON(unsplashAPI, latestPhotos, displayPhotos);
}); // End button
// Show oldest Photos
$('#oldest').click(function() {
  $.getJSON(unsplashAPI, oldestPhotos, displayPhotos);
}); // End button
html {
  box-sizing: border-box;
}
*,
*::after,
*::before {
  box-sizing: inherit;
}
/* Generated by Font Squirrel (https://www.fontsquirrel.com) on July 25, 2016 */

@font-face {
  font-family: 'courier_primeregular';
  src: url("../fonts/courier_prime-webfont.woff2") format("woff2"), url("../fonts/courier_prime-webfont.woff") format("woff");
}
@font-face {
  font-family: 'courier_primeitalic';
  src: url("../fonts/courier_prime_italic-webfont.woff2") format("woff2"), url("../fonts/courier_prime_italic-webfont.woff") format("woff");
}
@font-face {
  font-family: 'courier_primebold';
  src: url("../fonts/courier_prime_bold-webfont.woff2") format("woff2"), url("../fonts/courier_prime_bold-webfont.woff") format("woff");
}
body,
.filter-box .filter:hover,
.filter-box .filter.active,
.lg-actions .lg-prev:after,
.lg-actions .lg-next:before {
  font-family: 'courier_primeregular', sans-serif;
  font-weight: 400;
  font-style: normal;
  font-stretch: normal;
}
.filter-box .filter,
.photo-description span {
  font-family: 'courier_primebold', sans-serif;
  text-weight: 600;
}
header span {
  font-family: 'courier_primeitalic', sans-serif;
}
html,
body {
  margin: 0;
  padding: 0;
}
a:hover {
  cursor: pointer;
}
p {
  margin-top: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: inherit;
  line-height: inherit;
  font-weight: inherit;
  margin-top: 0;
}
img {
  vertical-align: middle;
}
figure {
  margin: 0;
}
/* Global Layout Set-up */

* {
  box-sizing: border-box;
}
.justify-end {
  justify-content: flex-end;
}
.no-grow {
  flex-grow: 0;
}
/* Because... Fun */

::selection {
  background: #000000;
  color: #FFFFFF;
}
/* Becuase I can't stand these */

*:focus {
  outline: none;
}
body {
  margin: 0;
  padding: 0;
  height: 100vh;
  background-color: #FFFFFF;
  color: #000000;
}
#top,
#bottom,
#left,
#right {
  background: #000000;
  position: fixed;
}
#left,
#right {
  top: 0;
  bottom: 0;
  width: 10px;
}
#left {
  left: 0;
}
#right {
  right: 0;
}
#top,
#bottom {
  left: 0;
  right: 0;
  height: 10px;
}
#top {
  top: 0;
}
#bottom {
  bottom: 0;
}
a {
  color: #000000;
}
.current a {
  color: #000000;
  text-decoration: underline;
}
header {
  display: flex;
  padding: 1.5em 1.5em 0 1.5em;
  flex-direction: column;
}
header h1 {
  color: #000000;
  text-align: left;
  font-size: 2em;
}
@media only screen and (min-width: 480px) {
  header h1 {
    margin-bottom: 0;
  }
}
header span {
  display: none;
}
@media only screen and (min-width: 480px) {
  header span {
    display: inline;
    text-align: left;
  }
}
@media only screen and (min-width: 480px) {
  header {
    padding: 2.5em 2.5em 1em 2.5em;
  }
}
.filter-box {
  display: flex;
  align-content: flex-start;
  flex-wrap: wrap;
  padding: 0 1.5em;
}
.filter-box .filter {
  font-size: 1em;
  background: #FFFFFF;
  color: #000000;
  border: 3.5px solid #000000;
  padding: 0.35em 2.25em;
  margin: 0.5em 0.5em;
  cursor: pointer;
  transition: background 0.2s;
}
.filter-box .filter:first-of-type {
  padding: 0.35em 1.5em;
}
.filter-box .filter:hover {
  color: #FFFFFF;
  background: #000000;
  cursor: pointer;
}
@media only screen and (min-width: 480px) {
  .filter-box .filter {
    margin: 1em 1em;
  }
}
.filter-box .filter.active {
  color: #FFFFFF;
  background: #000000;
}
@media only screen and (min-width: 480px) {
  .filter-box {
    padding-left: 1.5em;
  }
}
/* Edits for styles on lightgallery plugin */

.lg-backdrop {
  background: rgba(0, 0, 0, 0.9);
}
.lg-outer .lg-img-wrap,
.lg-outer .lg-item {
  max-width: 100%;
  height: 100%;
}
.lg-outer .lg-img-wrap .lg-image,
.lg-outer .lg-item .lg-image {
  max-width: 100%;
  border: 10px solid #000000;
  vertical-align: top;
  margin-top: 10%;
}
@media only screen and (min-width: 480px) {
  .lg-outer .lg-img-wrap .lg-image,
  .lg-outer .lg-item .lg-image {
    max-width: 850px;
    margin-top: 0;
    vertical-align: middle;
  }
}
.lg-outer .lg-img-wrap .lg-item,
.lg-outer .lg-item .lg-item {
  background: none;
}
.lg-actions .lg-next,
.lg-actions .lg-prev,
.lg-toolbar {
  background: none;
}
.lg-actions .lg-prev:after {
  content: 'Back';
  right: -100px;
  position: absolute;
  top: 0;
  color: #FFFFFF;
}
.lg-actions .lg-next:before {
  content: 'Next';
  left: -60px;
  position: absolute;
  top: 50%;
  color: #FFFFFF;
}
@media (max-width: 1100px) {
  .lg-actions .lg-next:before {
    color: transparent;
  }
}
@media (max-width: 1100px) {
  .lg-actions .lg-prev:after {
    color: transparent;
  }
}
.lg-sub-html {
  max-width: 850px;
  margin: 0 auto 18.2% auto;
  background: #FFFFFF;
  color: #000000;
  border: 10px solid #000000;
  text-align: left;
  padding-left: 1em;
}
.lg-sub-html p {
  margin: 0;
  font-size: 1em;
}
.lg-sub-html .photo-title {
  margin-bottom: 0em;
  font-size: 2em;
}
.lg-sub-html .photo-description {
  padding: 1em 0;
  line-height: 1.5;
}
@media (max-height: 1250px) {
  .lg-sub-html {
    margin-bottom: 0;
  }
}
@media (min-width: 1250px) {
  .lg-sub-html {
    margin: 0 auto 5% auto;
  }
}
/* Hide toolbar becuase I don't need these right now */

div.lg-toolbar.group {
  display: none;
}
.content {
  column-count: 1;
  column-gap: 0;
  padding: 0 2em;
  padding-bottom: 2em;
}
.content .tile {
  margin-top: 1em;
  display: inline-block;
  width: 100%;
  background-color: #000000;
}
.content .tile:hover {
  opacity: 0.9;
  transition: all 0.2s ease-in-out;
}
.content .tile .photo {
  width: 100%;
}
@media only screen and (min-width: 480px) {
  .content {
    padding-left: 2.5em;
    padding-right: 2.5em;
    column-count: 3;
    column-gap: 1em;
  }
}
.caption-box {
  display: none;
}
.photo-description {
  padding: 0.25em 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="http://nathanworking.com/unsplash/lightgallery-all.min.js"></script>

<link href="http://nathanworking.com/unsplash/lightgallery.min.css" rel="stylesheet" />

<!-- Borders all the way around, all day everyday -->
<div id="left"></div>
<div id="right"></div>
<div id="top"></div>
<div id="bottom"></div>

<header>
  <h1> My Favorite Photos from Unsplash </h1>
  <span> It just so happens they’re  my photos, go figure ;) </span>
</header>

<div class="filter-box">

  <button type="button" id="popular" class="filter active">popular</button>
  <button type="button" id="latest" class="filter">latest</button>
  <button type="button" id="oldest" class="filter">oldest</button>

</div>

<div class="content" id="photoBox"></div>

Comments