commercetools-8.x-1.2-alpha1/modules/commercetools_decoupled/js/molecules/LineItem.js

modules/commercetools_decoupled/js/molecules/LineItem.js
class LineItem extends HTMLElement {
  connectedCallback() {
    this.gridClasses =
      this.lineStyle === 'default'
        ? [['col-md-2'], ['col-md-5'], ['col-md-2'], ['col-md-3']]
        : [
            ['col-md-2'],
            ['col-md-3'],
            ['col-md-3', 'd-flex'],
            ['col-md-3'],
            ['col-md-1'],
          ];
    this.renderLineItem();
  }

  renderLineItem() {
    const productPath = Drupal.url(
      `${drupalSettings.commercetoolsDecoupled.catalogPath.substring(1)}/${this.lineItem.productSlug}?sku=${this.lineItem.variant.sku}`,
    );

    const container = document.createElement('div');
    container.classList.add(
      'row',
      'd-flex',
      'justify-content-between',
      'align-items-center',
      'py-2',
    );
    container.innerHTML = `
      <div class="${this.gridClasses[0].join(' ')} text-center">
        ${!this.lineItem.variant.images ? LineItem.placeholderImage() : `<img class="w-100" src="${this.lineItem.variant.images[0].url}" alt="${this.lineItem.name}"/>`}
      </div>

      <div class="${this.gridClasses[1].join(' ')}">
        <span class="placeholderify-ignore"><a class="fs-5 text-decoration-none fw-bold" href="${productPath}">${this.lineItem.name}</a></span>
        <div>
          ${Object.keys(this.lineItem.variant.attributes)
            .map((attrName) => {
              const { label, labelValue } =
                this.lineItem.variant.attributes[attrName];
              const eventData = { key: attrName, labelValue };
              document.dispatchEvent(
                new CustomEvent('commercetools:productAttributeLabel', {
                  detail: eventData,
                }),
              );
              return `<div><span class="me-2 fw-bold placeholderify-ignore">${label}:</span><span class="placeholderify-ignore">${eventData.labelValue}</span></div>`;
            })
            .join(' ')}
        </div>
      </div>

      <div class="${this.gridClasses[2].join(' ')} text-center">
        ${
          this.lineStyle === 'form' && !this.isLoading
            ? `<button data-mdb-button-init="" data-mdb-ripple-init="" class="btn btn-link quantity-btn quantity-minus px-2" data-mdb-button-initialized="true" data-cart-action="minus-quantity">
                <i class="bi bi-dash-lg"></i>
              </button>
              <input class="line-item-quantity form-number form-control" type="number" name="lineItems[${this.lineItem.id}][quantity]" value="${this.lineItem.quantity}" step="1" min="1">
              <button data-mdb-button-init="" data-mdb-ripple-init="" class="btn btn-link action-button quantity-plus px-2" data-mdb-button-initialized="true" data-cart-action="plus-quantity">
                <i class="bi bi-plus-lg"></i>
              </button>`
            : `<span>${this.lineItem.quantity}</span>`
        }
      </div>

      <div class="${this.gridClasses[3].join(' ')} text-center">
        ${
          this.lineItem.isDiscounted
            ? `<del>${window.commercetools.formatPrice(this.lineItem.originalTotalPrice)}</del>
             <span class="discount text-danger">
               ${window.commercetools.formatPrice(this.lineItem.totalPrice)}
             </span>`
            : `<span>${window.commercetools.formatPrice(this.lineItem.totalPrice)}</span>`
        }
      </div>

      ${
        this.lineStyle === 'form'
          ? `<div class="${this.gridClasses[4].join(' ')} text-end">
          <a href="#" class="text-muted" data-cart-action="remove-line-item"><i class="bi bi-x-lg"></i></a>
          <input class="line-item-remove" type="hidden" name="lineItems[${this.lineItem.id}][remove]" value="0">
        </div>`
          : ''
      }
    `;

    container.querySelectorAll('[data-cart-action]').forEach((actionItem) => {
      actionItem.addEventListener('click', (e) => {
        e.preventDefault();
        const { currentTarget } = e;
        const action = currentTarget.dataset.cartAction;
        const data = { lineItem: this.lineItem };

        switch (action) {
          case 'plus-quantity':
          case 'minus-quantity': {
            const quantityInput = currentTarget.parentElement.querySelector(
              '.line-item-quantity',
            );
            const currentQuantity = parseInt(quantityInput.value, 10);
            data.quantity =
              action === 'plus-quantity'
                ? currentQuantity + 1
                : Math.max(0, currentQuantity - 1);
            quantityInput.value = data.quantity;
            break;
          }

          default:
            container.remove();
            break;
        }
        this.actionHandler(action, data);
      });
    });
    this.append(container);
  }

  static placeholderImage() {
    return `
      <div class="card-img-wrapper" style="aspect-ratio: 304/405;">
        <img src="" alt="" class="card-img card-img-top" style="height: 100%; object-fit: cover;" />
      </div>
    `;
  }
}

customElements.define('ct-line-item', LineItem);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc