Perdixo
Perdixo

Reputation: 1289

Tabs to accordion (Woocommerce)

I'm trying to convert the product-page tabs to an accordion on my Woocommerce store, but things won't work. When i click on my links, the dropdown doesn't show, it doesn't do nothing ... The height should animate as well as my "+" icon, but nothing happens. It looks like it doens't wnat to add the "is-open" class on the clicked element. So i think my error lies in my js, but i don't see where!

Here's my tabs.php file :

<?php

/**
 * Single Product tabs
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/single-product/tabs/tabs.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see     https://docs.woocommerce.com/document/template-structure/
 * @package WooCommerce\Templates
 * @version 3.8.0
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Filter tabs and allow third parties to add their own.
 *
 * Each tab is an array containing title, callback and priority.
 *
 * @see woocommerce_default_product_tabs()
 */
$product_tabs = apply_filters('woocommerce_product_tabs', array());

if (!empty($product_tabs)) : ?>

    <div class="c-accordion">
        <div class="c-accordion__wrapper">
            <div class="c-accordion__content-wrapper">
                <?php foreach ($product_tabs as $key => $product_tab) : ?>
                    <div class="c-accordion__content js-accordion">
                        <div class="c-accordion__content-title">
                            <span class="c-accordion__plus"></span>
                            <p class="u-a1">
                                <?php echo wp_kses_post(apply_filters('woocommerce_product_' . $key . '_tab_title', $product_tab['title'], $key)); ?>
                            </p>
                        </div>
                        <div class="c-accordion__content-main js-content">
                            <?php
                            if (isset($product_tab['callback'])) {
                                call_user_func($product_tab['callback'], $key, $product_tab);
                            }
                            ?>
                        </div>
                    </div>
                <?php endforeach; ?>
            </div>
        </div>
    </div>

<?php endif; ?>

Here's my js :

// Custom Tabs
('use strict');
var Accordion = /** @class */ (function () {
  function Accordion() {
    this.items = document.querySelectorAll('.js-accordion');
    this.itemClass = '.js-accordion';
    this.contentWrapperClass = '.js-content';
    this.css = {
      open: 'is-open',
    };
    if (this.items.length > 0) {
      this.init();
    }
  }
  Accordion.prototype.init = function () {
    var _this = this;
    for (var i = 0; i < this.items.length; i++) {
      this.items[i].addEventListener('click', function (ev) {
        ev.preventDefault();
        var current = ev.currentTarget;
        var contentWrapper = current.querySelector(_this.contentWrapperClass);
        if (!current.classList.contains(_this.css['open'])) {
          _this.slideDown(current, contentWrapper);
          return;
        }
        _this.closeItem();
      });
    }
  };
  Accordion.prototype.getActiveElement = function () {
    var accordionItems = document.querySelectorAll('' + this.itemClass);
    var active = null;
    for (var i = 0; i < accordionItems.length; i++) {
      if (accordionItems[i].classList.contains(this.css['open'])) {
        active = accordionItems[i];
      }
    }
    return active;
  };
  Accordion.prototype.slideDown = function (element, content) {
    var _this = this;
    var contentHeight = 0;
    var active = this.getActiveElement();
    for (var i = 0; i < this.items.length; i++) {
      this.items[i].classList.remove(this.css['open']);
    }
    element.classList.add(this.css['open']);
    if (active) {
      var activeContent = active.querySelector(this.contentWrapperClass);
      TweenMax.to(activeContent, 0.6, {
        height: 0,
        onStart: function () {
          _this.openItem(content, contentHeight);
        },
      });
      return;
    }
    // else
    this.openItem(content, contentHeight);
  };
  Accordion.prototype.openItem = function (content, contentHeight) {
    TweenMax.set(content, {
      height: 'auto',
      onComplete: function () {
        contentHeight = content.clientHeight;
        TweenMax.set(content, {
          height: 0,
          onComplete: function () {
            TweenMax.to(content, 0.4, {
              height: contentHeight,
              onComplete: function () {
                TweenMax.set(content, {
                  height: 'auto',
                });
              },
            });
          },
        });
      },
    });
  };
  Accordion.prototype.closeItem = function () {
    var active = this.getActiveElement();
    if (active) {
      var activeContent = active.querySelector(this.contentWrapperClass);
      active.classList.remove(this.css['open']);
      TweenMax.to(activeContent, 0.6, {
        height: 0,
      });
    }
  };
  return Accordion;
})();
new Accordion();

and here's my css (scss) :

.c-accordion {
    max-width: 100%;
    width: 100%;
    font-family: helvetica;


    &__wrapper {

        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        height: auto;
    }

    &__content-wrapper {

        flex: 1 0 100%;
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        justify-content: flex-start;
        align-items: stretch;
        align-content: stretch;
    }

    &__content-title {
        position: relative;
        transition: 0.3s;
        padding-top: 10px;
        padding-bottom: 10px;
        padding-left: percentage(1/15);
    }

    &__content-main {
        height: 0;
        overflow: hidden;
        padding-left: percentage(1/15);
        display: flex;
        flex-wrap: wrap;

        p {
            max-width: 300px;
        }
    }

    &__content {
        position: relative;
        overflow: hidden;
        cursor: pointer;
        flex: 1 0 auto;

        &:first-of-type {
            &:before {
                display: none;
            }
        }

        &:before {
            content: '';
            width: 100%;
            border-top: 2px solid $black;
            position: absolute;
            left: 0;
            top: 0;
        }

        &:last-child {
            &:after {

                content: '';
                width: 100%;
                border-top: 2px solid $black;
                position: absolute;
                left: 0;
                bottom: 0;
            }
        }


        &__text {
            padding-top: 10px;
            padding-bottom: 20px;
            line-height: 1.38;

        }


        &:hover {}

        &.is-open {
            transition: 0.3s;

            .c-accordion {
                &__plus {
                    transform: translateY(-50%) rotate(90deg);

                    &:after {
                        opacity: 0;
                    }
                }

                &__content-main {
                    height: auto;
                }
            }
        }
    }

    &__plus {
        width: 3vh;
        height: 3vh;
        position: absolute;
        left: 0px;
        top: 50%;
        cursor: pointer;
        opacity: 1;
        transform: translateY(-50%) rotate(0deg);
        transition: 0.4s;

        &:before {
            content: '';
            height: 100%;
            border-left: 2px solid $black;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            opacity: 1;
        }

        &:after {
            content: '';
            width: 100%;
            border-top: 2px solid $black;
            position: absolute;
            opacity: 1;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            transition: opacity 0.2s;
        }
    }

    &__left {
        padding-top: 10px;
        padding-bottom: 75px;
        width: percentage(6/14);
        padding-right: 10px;
    }

    &__right {
        padding-top: 10px;
        padding-bottom: 75px;
        width: percentage(8/14);
        padding-right: 10px;
    }
}

Does someone have any idea what i'm doing wrong ? Thanks a lot !

Upvotes: 0

Views: 4184

Answers (1)

Perdixo
Perdixo

Reputation: 1289

Fixed, the error wasn't with this JS but there was a conflict with another plugin. Solved

Upvotes: 0

Related Questions