Skip to content

Commit

Permalink
Separate photo gallery captions (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
amaisano authored Sep 25, 2019
1 parent f782444 commit 6954a0a
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 72 deletions.
29 changes: 23 additions & 6 deletions apps/cms/lib/field/image.ex
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
defmodule CMS.Field.Image do
@moduledoc """
Represents an image field in the Drupal CMS. This image field is embedded
in other content types like CMS.Page.NewsEntry.
in other content types like CMS.Page.NewsEntry. Captions only used on galleries.
"""
alias Phoenix.HTML

import CMS.Helpers, only: [rewrite_url: 1]
import CMS.Helpers,
only: [
field_value: 2,
handle_html: 1,
rewrite_url: 1
]

defstruct url: "", alt: ""
defstruct url: "",
alt: "",
caption: nil

@type t :: %__MODULE__{
url: String.t(),
alt: String.t()
alt: String.t(),
caption: HTML.safe() | nil
}

@spec from_api(map) :: t
def from_api(%{"alt" => alt, "url" => url}) do
%__MODULE__{alt: alt, url: rewrite_url(url)}
def from_api(%{"alt" => alt, "url" => url} = data) do
%__MODULE__{
url: rewrite_url(url),
alt: alt,
caption: data |> field_value("field_image_caption") |> handle_caption()
}
end

@spec handle_caption(String.t() | nil) :: HTML.safe() | nil
defp handle_caption(nil), do: nil
defp handle_caption(caption), do: handle_html(caption)
end
86 changes: 57 additions & 29 deletions apps/site/assets/js/photo-gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export default function photoGallery($) {

/* DATA FUNCTIONS */
function initializeData($) {
let output = {};
let $galleryEl, galleryId, images;
const output = {};
let $galleryEl;
let galleryId;
let images;

$('[data-component="photo-gallery"]').each((_offset, el) => {
$galleryEl = $(el);
Expand All @@ -27,8 +29,8 @@ function initializeData($) {
galleryId = guid();
$galleryEl.attr("data-gallery-id", galleryId);

// find all images that belong to a gallery
images = $galleryEl.find("img").get();
// find all images/captions that belong to a gallery
images = $galleryEl.find("figure").get();

// create an object to keep track of image gallery parameters
output[galleryId] = makeGallery($galleryEl, images);
Expand All @@ -39,7 +41,7 @@ function initializeData($) {

const makeGallery = ($el, images) => ({
el: $el,
images: images,
images,
imageOffset: 0,
pageOffset: 0,
lastPage: calculateLastPage(images.length)
Expand Down Expand Up @@ -82,7 +84,6 @@ function handleClickImage(ev) {
ev.preventDefault();
const id = ev.currentTarget.getAttribute("data-gallery");
const offset = ev.currentTarget.getAttribute("data-offset");
const photoId = ev.currentTarget.getAttribute("id");
const actualOffset = setGalleryImageOffset(id, offset);
replaceActiveImage(id, getGalleryImageByOffset(id, actualOffset));
}
Expand All @@ -92,7 +93,7 @@ function handleClickNavigation(ev) {
const id = ev.currentTarget.getAttribute("data-gallery");
const increment = parseInt(ev.currentTarget.getAttribute("data-increment"));
const focusEl = increment === 1 ? "next" : "prev";
const isDesktop = isVisible(id + "images");
const isDesktop = isVisible(`${id}images`);

// when on desktop: navigate between sets of images
// when on mobile: navigate between images
Expand All @@ -115,10 +116,14 @@ const guid = () =>
/* RENDERING FUNCTIONS */
function render(id, focusId) {
// get main image
const mainImage = galleries[id].images
const main = galleries[id].images
.filter((_el, offset) => offset == galleries[id].imageOffset)
.pop();

const mainImage = main.querySelectorAll("img").item(0);

const mainCaption = main.querySelectorAll("figcaption").item(0);

// get pages of images
const firstImage = galleries[id].pageOffset * PAGE_SIZE;
const lastImage = firstImage + PAGE_SIZE;
Expand All @@ -130,19 +135,19 @@ function render(id, focusId) {
// render group of images
const markUp = `
<div class="c-photo-gallery__main-container">
<div class="c-photo-gallery__main-window">
<img class="c-photo-gallery__main-image"
id="${id + "primary"}"
alt="${mainImage.getAttribute("alt")}"
src="${mainImage.getAttribute("src")}">
<figure>
<div class="c-photo-gallery__main-window">
<img class="c-photo-gallery__main-image"
id="${`${id}primary`}"
alt="${mainImage.getAttribute("alt")}"
src="${mainImage.getAttribute("src")}">
</div>
<div id="${id +
"name"}" class="c-photo-gallery__main-title">${mainImage.getAttribute(
"alt"
)}</div>
<figcaption id="${`${id}name`}" class="c-photo-gallery__main-title">${
mainCaption.innerHTML
}</figcaption>
</figure>
</div>
<div id="${id +
"images"}" class="c-photo-gallery__thumbnails c-thumbnail-count--${
<div id="${`${id}images`}" class="c-photo-gallery__thumbnails c-thumbnail-count--${
images.length
}">
${renderImages(images, firstImage, id)}
Expand All @@ -163,14 +168,14 @@ function renderNavigation(id, pagination) {
<a href="#gallery-previous"
title="previous photos"
role="navigation"
id="${id + "prev"}"
id="${`${id}prev`}"
data-gallery="${id}"
data-image="navigation"
data-increment="-1"><i class="fa fa-caret-left" aria-hidden="true"></i> Previous</a>
<a href="#gallery-next"
title="next photos"
role="navigation"
id="${id + "next"}"
id="${`${id}next`}"
data-gallery="${id}"
data-image="navigation"
data-increment="1">Next <i class="fa fa-caret-right" aria-hidden="true"></i></a>
Expand All @@ -186,20 +191,43 @@ function renderImages(images, firstImage, id) {
data-gallery="${id}"
id="${id + (firstImage + offset)}"
role="navigation"
title="change photo to ${image.getAttribute("alt")}"
title="change photo to ${image
.querySelectorAll("img")
.item(0)
.getAttribute("alt")}"
data-offset="${firstImage + offset}">
<img
class="c-photo-gallery__thumbnail"
alt="${image.getAttribute("alt")}"
src="${image.getAttribute("src")}"></a>`
alt="${image
.querySelectorAll("img")
.item(0)
.getAttribute("alt")}"
src="${image
.querySelectorAll("img")
.item(0)
.getAttribute("src")}"></a>`
)
.join("");
}

function replaceActiveImage(id, image) {
const activeImage = document.getElementById(id + "primary");
const activeImageName = document.getElementById(id + "name");
activeImage.setAttribute("src", image.getAttribute("src"));
activeImage.setAttribute("alt", image.getAttribute("alt"));
activeImageName.innerHTML = image.getAttribute("alt");
const activeImage = document.getElementById(`${id}primary`);
const activeImageName = document.getElementById(`${id}name`);
activeImage.setAttribute(
"src",
image
.querySelectorAll("img")
.item(0)
.getAttribute("src")
);
activeImage.setAttribute(
"alt",
image
.querySelectorAll("img")
.item(0)
.getAttribute("alt")
);
activeImageName.innerHTML = image
.querySelectorAll("figcaption")
.item(0).innerHTML;
}
102 changes: 68 additions & 34 deletions apps/site/assets/js/test/photo-gallery_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,72 +12,106 @@ describe("photo-gallery", () => {
$("body")
.append(`<div class="photo-gallery clearfix" data-component="photo-gallery">
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="E74C3C.png"><img alt="Red" class="img-thumbnail" src="E74C3C.png"></a></div>
<div class="photo-name">Red</div>
<figure>
<a href="E74C3C.png"><img alt="Red" class="img-thumbnail" src="E74C3C.png"></a>
<figcaption class="photo-name">Red</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="5499C7.png"><img alt="Blue" class="img-thumbnail" src="5499C7.png"></a></div>
<div class="photo-name">Blue</div>
<figure>
<a href="5499C7.png"><img alt="Blue" class="img-thumbnail" src="5499C7.png"></a>
<figcaption class="photo-name">Blue</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="7E5109.png"><img alt="Brown" class="img-thumbnail" src="7E5109.png"></a></div>
<div class="photo-name">Brown</div>
<figure>
<a href="7E5109.png"><img alt="Brown" class="img-thumbnail" src="7E5109.png"></a>
<figcaption class="photo-name">Brown</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="212F3C.png"><img alt="Gray" class="img-thumbnail" src="212F3C.png"></a></div>
<div class="photo-name">Gray</div>
<figure>
<a href="212F3C.png"><img alt="Gray" class="img-thumbnail" src="212F3C.png"></a>
<figcaption class="photo-name">Gray</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="F1C40F.png"><img alt="Yellow" class="img-thumbnail" src="F1C40F.png"></a></div>
<div class="photo-name">Yellow</div>
<figure>
<a href="F1C40F.png"><img alt="Yellow" class="img-thumbnail" src="F1C40F.png"></a>
<figcaption class="photo-name">Yellow</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="1D8348.png"><img alt="Green" class="img-thumbnail" src="1D8348.png"></a></div>
<div class="photo-name">Green</div>
<figure>
<a href="1D8348.png"><img alt="Green" class="img-thumbnail" src="1D8348.png"></a>
<figcaption class="photo-name">Green</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="A569BD.png"><img alt="Purple" class="img-thumbnail" src="A569BD.png"></a></div>
<div class="photo-name">Purple</div>
<figure>
<a href="A569BD.png"><img alt="Purple" class="img-thumbnail" src="A569BD.png"></a>
<figcaption class="photo-name">Purple</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="922B21.png"><img alt="Maroon" class="img-thumbnail" src="922B21.png"></a></div>
<div class="photo-name">Maroon</div>
<figure>
<a href="922B21.png"><img alt="Maroon" class="img-thumbnail" src="922B21.png"></a>
<figcaption class="photo-name">Maroon</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="E59866.png"><img alt="Yucky" class="img-thumbnail" src="E59866.png"></a></div>
<div class="photo-name">Yucky</div>
<figure>
<a href="E59866.png"><img alt="Yucky" class="img-thumbnail" src="E59866.png"></a>
<figcaption class="photo-name">Yucky</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="A9CCE3.png"><img alt="Light Blue" class="img-thumbnail" src="A9CCE3.png"></a></div>
<div class="photo-name">Light Blue</div>
<figure>
<a href="A9CCE3.png"><img alt="Light Blue" class="img-thumbnail" src="A9CCE3.png"></a>
<figcaption class="photo-name">Light Blue</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="fff.png"><img alt="White" class="img-thumbnail" src="fff.png"></a></div>
<div class="photo-name">White</div>
<figure>
<a href="fff.png"><img alt="White" class="img-thumbnail" src="fff.png"></a>
<figcaption class="photo-name">White</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="E74C3C_0.png"><img alt="page 2 red" class="img-thumbnail" src="E74C3C_0.png"></a></div>
<div class="photo-name">page 2 red</div>
<figure>
<a href="E74C3C_0.png"><img alt="page 2 red" class="img-thumbnail" src="E74C3C_0.png"></a>
<figcaption class="photo-name">page 2 red</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="5499C7_0.png"><img alt="page 2 blue" class="img-thumbnail" src="5499C7_0.png"></a></div>
<div class="photo-name">page 2 blue</div>
<figure>
<a href="5499C7_0.png"><img alt="page 2 blue" class="img-thumbnail" src="5499C7_0.png"></a>
<figcaption class="photo-name">page 2 blue</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="7E5109_0.png"><img alt="page 2 brown" class="img-thumbnail" src="7E5109_0.png"></a></div>
<div class="photo-name">page 2 brown</div>
<figure>
<a href="7E5109_0.png"><img alt="page 2 brown" class="img-thumbnail" src="7E5109_0.png"></a>
<figcaption class="photo-name">page 2 brown</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="212F3C_0.png"><img alt="page 2 dark" class="img-thumbnail" src="212F3C_0.png"></a></div>
<div class="photo-name">page 2 dark</div>
<figure>
<a href="212F3C_0.png"><img alt="page 2 dark" class="img-thumbnail" src="212F3C_0.png"></a>
<figcaption class="photo-name">page 2 dark</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="F1C40F_0.png"><img alt="page 2 yellow" class="img-thumbnail" src="F1C40F_0.png"></a></div>
<div class="photo-name">page 2 yellow</div>
<figure>
<a href="F1C40F_0.png"><img alt="page 2 yellow" class="img-thumbnail" src="F1C40F_0.png"></a>
<figcaption class="photo-name">page 2 yellow</figcaption>
</figure>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div><a href="1D8348_0.png"><img alt="page 2 green" class="img-thumbnail" src="1D8348_0.png"></a></div>
<div class="photo-name">page 2 green</div>
<figure>
<a href="1D8348_0.png"><img alt="page 2 green" class="img-thumbnail" src="1D8348_0.png"></a>
<figcaption class="photo-name">page 2 green</figcaption>
</figure>
</div>
</div>`);
photoGallery($);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
<div class="c-photo-gallery clearfix" data-component="photo-gallery">
<%= for image <- @content.images do %>
<div class="col-xs-12 col-sm-6 col-md-4 photo-item">
<div>
<figure>
<%= link to: image.url do %>
<%= img_tag(image.url, alt: image.alt, class: "img-thumbnail") %>
<% end %>
</div>
<div><%= image.alt %></div>
<figcaption>
<%= if image.caption do %>
<%= image.caption %>
<% else %>
<p><%= image.alt %></p>
<% end %>
</figcaption>
</figure>
</div>
<% end %>
</div>
Expand Down

0 comments on commit 6954a0a

Please sign in to comment.