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);
