Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Implementing Product metafield definition to get Product information boxes

Implementing Product metafield definition to get Product information boxes

marianneahug
Visitor
1 0 0

Hello! Made a new code page- selections/avatar-carousel.liquid. It uses product metafield to fetch information. For some reason it is not working and get the error metafield null, like there is no metafield at all. I tried to rewrite the code in different ways to see the issue as well as checked the custom metafield Product Avatars but it's not working. 

I am adding how the code looks currently. 

Also the new metafield is Product metafield definition, Name: Avatar Products, Namespace and Key: custom.avatar_products, Type: Multi Line but before it was JSON otherwise same. 

Avatars are saved as avatar1,avatar2, avatar3... avatar10

Can you please see why it won't fetch information? 

 

 

{% comment %}

  Avatar Carousel with Metafield-based Product Association

{% endcomment %}

 

<div class="avatar-carousel">

  <div class="loading-indicator">Loading...</div>

 

  <div class="avatar-container">

    {% for i in (1..10) %}

      {% assign avatar_products = product.metafields.custom.avatar_products | default: "" | split: "," %}

      

      <div class="avatar-slide {% if forloop.index == 2 %}active{% elsif forloop.index == 1 %}prev{% elsif forloop.index == 3 %}next{% endif %}" data-index="{{ forloop.index }}">

        <img src="{{ 'avatar' | append: i | append: '.png' | asset_url }}" alt="Avatar {{ i }}" class="avatar-image">

        

        <div class="product-labels">

          {% for product_handle in avatar_products %}

            {% assign product = all_products[product_handle] %}

            {% if product != blank %}

              <div class="product-label" data-product-id="{{ product.id }}">

                <div class="product-name">{{ product.title }}</div>

                <a href="{{ product.url }}" class="product-info-link">View Product</a>

              </div>

            {% endif %}

          {% endfor %}

        </div>

      </div>

    {% endfor %}

  </div>

 

  <div class="outfit-details-text">

    Click the avatar to view outfit details.

  </div>

 

  <button class="nav-button prev" aria-label="Previous avatar">&lt;</button>

  <button class="nav-button next" aria-label="Next avatar">&gt;</button>

</div>

 

{% schema %}

{

  "name": "Avatar Carousel",

  "settings": []

}

{% endschema %}

 

<style>

.outfit-details-text {

  position: absolute;

  bottom: 1vw;

  left: 50%;

  transform: translateX(-50%);

  width: 30%;

  text-align: center;

  padding: 0.5em 1em;

  background-color: rgba(245, 245, 245, 0.9);

  color: #A9A9A9;

  font-size: clamp(10px, 2vw, 14px);

  border-radius: 25px;

  font-family: Arial, sans-serif;

  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);

  white-space: nowrap;

  overflow: hidden;

  text-overflow: ellipsis;

}

 

@media (max-width: 768px) {

  .outfit-details-text {

    bottom: 3%;

    width: 80%;

    font-size: clamp(8px, 3vw, 12px);

    padding: 0.7em 1em;

    white-space: normal;

    max-height: 4.2em;

    display: -webkit-box;

    -webkit-line-clamp: 2;

    -webkit-box-orient: vertical;

    text-overflow: clip;

    line-height: 1.4;

  }

}

 

.avatar-carousel {

  position: relative;

  width: 100%;

  height: 80vh;

  margin: 0 auto;

  overflow: hidden;

  background: radial-gradient(circle, #ffffff 0%, #f5f5f5 60%, #e0e0e0 80%);

  border-radius: 0px;

  box-shadow: 0 40px 100px rgba(0, 0, 0, 0.5),

              0 20px 50px rgba(0, 0, 0, 0.3) inset;

}

 

.avatar-container {

  display: flex;

  justify-content: center;

  align-items: center;

  width: 100%;

  height: 100%;

}

 

.avatar-slide {

  position: absolute;

  width: 30%;

  height: 80%;

  top: 45%;

  left: 50%;

  transform: translate(-50%, -50%);

  transition: all 0.3s ease;

  cursor: pointer;

  opacity: 0.5;

  filter: blur(5px);

}

 

.avatar-slide.prev,

.avatar-slide.next {

  width: 25.5%;

  height: 68%;

}

 

.avatar-slide.prev {

  left: 20%;

}

 

.avatar-slide.active {

  opacity: 1;

  filter: none;

  z-index: 2;

}

 

.avatar-slide.next {

  right: 20%;

  left: auto;

}

 

.avatar-slide.active.expanded {

  transform: translate(-50%, -50%) scale(1.1);

}

 

@media (max-width: 768px) {

  .avatar-slide {

    width: 60%;

    height: 65%;

    top: 50%;

  }

  .avatar-slide.prev,

  .avatar-slide.next {

    width: 51%;

    height: 55.25%;

  }

  .avatar-slide.prev {

    left: 10%;

  }

  .avatar-slide.next {

    right: 10%;

    left: auto;

  }

}

 

.avatar-image {

  width: 100%;

  height: 100%;

  object-fit: contain;

}

 

.nav-button {

  position: absolute;

  top: 50%;

  transform: translateY(-50%);

  background: rgba(0, 0, 0, 0.5);

  color: white;

  border: none;

  font-size: 24px;

  padding: 15px;

  cursor: pointer;

  z-index: 10;

}

 

.nav-button.prev {

  left: 20px;

}

 

.nav-button.next {

  right: 20px;

}

 

.loading-indicator {

  position: absolute;

  top: 50%;

  left: 50%;

  transform: translate(-50%, -50%);

  font-size: 20px;

  z-index: 5;

}

 

.product-labels {

  position: absolute;

  top: 0;

  left: 0;

  width: 100%;

  height: 100%;

  display: none;

}

 

.product-label {

  position: absolute;

  background-color: rgba(255, 255, 255, 0.8);

  padding: 10px;

  border-radius: 5px;

  font-size: 14px;

  text-align: center;

}

 

.product-name {

  font-weight: bold;

  margin-bottom: 5px;

}

 

.product-info-link {

  display: inline-block;

  color: #007bff;

  text-decoration: underline;

}

</style>

 

<script>

document.addEventListener('DOMContentLoaded', function() {

  const carousel = document.querySelector('.avatar-carousel');

  const slides = carousel.querySelectorAll('.avatar-slide');

  const prevButton = carousel.querySelector('.nav-button.prev');

  const nextButton = carousel.querySelector('.nav-button.next');

  const loadingIndicator = carousel.querySelector('.loading-indicator');

  let currentSlide = 1;

 

  function updateSlides() {

    slides.forEach((slide, index) => {

      slide.classList.remove('prev', 'active', 'next', 'expanded');

      slide.style.opacity = '0.5';

      slide.style.filter = 'blur(5px)';

      

      if (index === currentSlide) {

        slide.classList.add('active');

        slide.style.opacity = '1';

        slide.style.filter = 'none';

      } else if (index === (currentSlide - 1 + slides.length) % slides.length) {

        slide.classList.add('prev');

      } else if (index === (currentSlide + 1) % slides.length) {

        slide.classList.add('next');

      } else {

        slide.style.display = 'none';

      }

    });

    

    slides[currentSlide].style.display = '';

    slides[(currentSlide - 1 + slides.length) % slides.length].style.display = '';

    slides[(currentSlide + 1) % slides.length].style.display = '';

  }

 

  function showNextSlide() {

    currentSlide = (currentSlide + 1) % slides.length;

    updateSlides();

  }

 

  function showPrevSlide() {

    currentSlide = (currentSlide - 1 + slides.length) % slides.length;

    updateSlides();

  }

 

  function toggleExpand(slide) {

    if (slide.classList.contains('active')) {

      slide.classList.toggle('expanded');

      const productLabels = slide.querySelector('.product-labels');

      productLabels.style.display = slide.classList.contains('expanded') ? 'block' : 'none';

      slides.forEach(s => {

        if (s !== slide) {

          s.style.opacity = slide.classList.contains('expanded') ? '0.2' : '0.5';

        }

      });

    }

  }

 

  prevButton.addEventListener('click', showPrevSlide);

  nextButton.addEventListener('click', showNextSlide);

 

  // Event listeners for side avatar clicks

  slides.forEach(slide => {

    slide.addEventListener('click', () => {

      if (slide.classList.contains('prev')) {

        showPrevSlide();

      } else if (slide.classList.contains('next')) {

        showNextSlide();

      } else {

        toggleExpand(slide);

      }

    });

  });

 

  // Keyboard navigation (left and right arrows)

  document.addEventListener('keydown', (event) => {

    if (event.key === 'ArrowLeft') {

      showPrevSlide();

    } else if (event.key === 'ArrowRight') {

      showNextSlide();

    }

  });

 

  // Hide loading indicator when all images are loaded

  Promise.all(Array.from(carousel.querySelectorAll('img')).map(img => {

    if (img.complete) return Promise.resolve();

    return new Promise(resolve => { img.onload = img.onerror = resolve; });

  })).then(() => {

    loadingIndicator.style.display = 'none';

    updateSlides();

  });

});

</script>



Replies 0 (0)