
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
Diacart is a shopping cart based on localStorage. It provides a declarative interface that allows you to fully customize the cart.
npm install diacart -S
<div data-diacart-container></div>
Add two attributes to the button:
data-diacart-add-to-cart - Defines the function of the button.
data-diacart-item-json - Defines JSON with the following product properties:
Escape quotes in JSON before inserting it into the data-diacart-item-json attribute.
<button
type="button"
data-diacart-add-to-cart
data-diacart-item-json='{"id": 46, "name": "Aliquam vehicula dui purus (id46)", "price": 1300, "image": "https://picsum.photos/300/200?image=513"}'
>Add to cart</button>
import Diacart from "diacart";
import { html, render } from "lit-html"; // in case you want to change the default templates
// All parameters are optional. You can omit the option parameter in Diacart, then the default options will be used.
const diacart = new Diacart({
name: "diacart",
title: "Shopping cart",
totalPriceText: "Total amount",
totalQuantityText: "Total quantity",
removeFromCartBtnText: "",
emptyCartText: "Your shopping cart is empty",
orderBtnText: "Checkout",
clearBtnText: "Clear cart",
currency: "$",
groupBy: "id", // 'null', 'undefined' or false to not group
itemHasQuantity: true, // 'true' or 'false'
itemHasPrice: true, // 'true' or 'false'
// selectors
containerSelector: "[data-diacart-container]", // here will be rendered template
miniContainerSelector: "[data-diacart-mini-container]", // here will be rendered miniTemplate
totalPriceContainerSelector: "[data-diacart-total-price-container]", // here will be rendered totalPriceTemplate
totalQuantityContainerSelector: "[data-diacart-total-quantity-container]", // here will be rendered totalQuantityTemplate
addToCartBtnSelector: "[data-diacart-add-to-cart]", // the 'add' function will be attached to them
removeFromCartBtnSelector: "[data-diacart-remove-from-cart]", // the 'remove' function will be attached to them
quantityInputSelector: "[data-diacart-quantity-input]",
orderBtnSelector: "[data-diacart-order]", // the 'order' function will be attached to them
clearBtnSelector: "[data-diacart-clear]", // the 'clear' function will be attached to them
// template rendering functions
templateTagFunction: html, // MUST specify these parameters if you want to override templates!
templateRenderFunction: render, // MUST specify these parameters if you want to override templates!
// template functions
template: diacartObject => {
const { options, storage, totalPrice } = diacartObject;
return html`
<div class="diacart-wrapper">
<section class="diacart">
<div class="diacart__header">
<div class="diacart-grid">
<div
class="diacart-grid-col diacart-grid-col--flex diacart__header-col"
>
<div class="diacart__title">${options.title || ""}</div>
</div>
<div
class="diacart-grid-col diacart-grid-col--auto diacart__header-col${!storage.length
? " diacart-hidden"
: ""}"
>
<button
class="diacart__clear-btn diacart-btn diacart-btn--default diacart-btn--medium"
data-diacart-clear
>
${options.clearBtnText || ""}
</button>
</div>
</div>
</div>
<div class="diacart__items">
${!storage.length
? html`
<div class="diacart-empty">
<h2 class="diacart-empty__title">
${options.emptyCartText}
</h2>
</div>
`
: storage.map((item, id) =>
options.itemTemplate({ id, item, options })
)}
<div
class="diacart__footer${!storage.length ? " diacart-hidden" : ""}"
>
<div class="diacart__footer-container">
<div class="diacart__total-price">
${options.totalPriceText
? options.totalPriceText + ": "
: ""}<span class="diacart__total-price-accent"
>${options.totalPriceTemplate({
options,
totalPrice
})}</span
>
</div>
<button
class="diacart__order-btn diacart-btn diacart-btn--primary diacart-btn--medium"
data-diacart-order
>
${options.orderBtnText || ""}
</button>
</div>
</div>
</div>
</section>
</div>
`;
}, // cart template as a function
itemTemplate: ({ id, item, options }) => {
return html`
<div
class="diacart-item"
data-diamodal-item
data-diacart-item-id="${id || ""}"
>
<div class="diacart-grid">
${!item.image
? ""
: html`
<div
class="diacart-grid-col diacart-grid-col--v-gutter diacart-grid-col--auto diacart-item__image-col"
>
<a
href="${item.link || ""}"
title="${item.name || ""}"
class="diacart-item__image"
style="background-image: url('${item.image || ""}');"
></a>
</div>
`}
<div
class="diacart-grid-col diacart-grid-col--v-gutter diacart-grid-col--flex diacart-item__text-col"
>
<div class="diacart-grid">
<div class="diacart-grid-col diacart-grid-col--flex">
<a href="${item.link || ""}" class="diacart-item__title"
>${item.name || ""}</a
>
</div>
<div class="diacart-grid-col diacart-grid-col--auto">
<button
class="diacart-item__remove-btn"
data-diacart-remove-from-cart
data-diacart-item-id="${id || ""}"
>
${options.removeFromCartBtnText || ""}
</button>
</div>
</div>
<div class="diacart-item__options diacart-grid diacart-grid--v-end">
${options.itemHasQuantity && item.quantity
? html`
<div
class="diacart-grid-col diacart-grid-col--auto diacart-item-option"
>
<div class="diacart-item__quantity diacart-counter">
<div class="diacart-item-option__title">
${options.totalQuantityText}:
</div>
<div
class="diacart-item-option__value diacart-counter__container diacart-grid diacart-grid--no-gutter"
>
<button
class="diacart-grid__col diacart-grid__col--auto diacart-counter__btn diacart-counter__plus-btn"
>
+
</button>
<input
class="diacart-grid__col diacart-grid__col--flex diacart-counter__input"
type="number"
name="quantity"
data-diacart-quantity-input
data-diacart-item-id="${id || ""}"
.value="${item.quantity || 1}"
/>
<button
class="diacart-grid__col diacart-grid__col--auto diacart-counter__btn diacart-counter__minus-btn"
>
-
</button>
</div>
</div>
</div>
`
: ""}
<div class="diacart-grid-col diacart-grid-col--flex">
${options.itemHasPrice && item.price
? html`
<div class="diacart-item__price">
${options.currency || ""} ${item.price || ""}
</div>
`
: ""}
</div>
</div>
</div>
</div>
</div>
`;
}, // cart item template as a function, used in 'template' function
miniTemplate: diacartObject => html``, // mini cart template as a function
totalPriceTemplate: diacartObject => {
const { options, totalPrice } = diacartObject;
return (options.currency + " " || "") + parseFloat(totalPrice).toFixed(2);
}, // total price template as a function
totalQuantityTemplate: diacartObject => {
const { totalQuantity } = diacartObject;
return parseInt(totalQuantity);
} // total quantity template as a function
});
// events
function onAdd(addedItemId) {
console.log("onAdd arguments: ", addedItemId);
}
function onUpdate(updatedItemId, updateObj) {
console.log("onUpdate arguments: ", updatedItemId, updateObj);
}
function onStorageUpdate(newValue, prevValue) {
console.log("onStorageUpdate arguments: ", newValue, prevValue);
}
function onRemove(removedItemObj) {
console.log("onRemove arguments: ", removedItemObj);
}
function onOrder(items) {
console.log("onOrder arguments:", items);
}
function onClear() {
console.log("onClear has no arguments");
}
function onRender() {
console.log("onRender has no arguments");
}
diacart.on("add", onAdd); // will be called at every product adding
diacart.on("update", onUpdate); // will be called at every product updating
diacart.on("storageUpdate", onStorageUpdate); // will be called at every storage updating
diacart.on("remove", onRemove); // will be called at every removing product from cart
diacart.on("order", onOrder); // will be called at every ordering
diacart.once("clear", onClear); // will be called only once when clearing the cart
diacart.on("render", onRender); // will be called at every rerendering
const productData = {
id: 46,
name: "Aliquam vehicula dui purus (id46)",
price: 1300,
image: "https://picsum.photos/300/200?image=513"
};
const cartItemId = diacart.add(productData); // add product, triggers 'add' event
diacart.update(cartItemId, { name: "New name" }); // update product by id, triggers 'update' event
console.log(diacart.hasItem({ name: "New name" })); // check on whether a product exists on a specific query
diacart.remove(cartItemId); // remove product by id, triggers 'remove' event
console.log(diacart.hasItem({ name: "New name" }));
diacart.add(productData); // add product, triggers 'add' event
diacart.order(); // order cart, triggers 'order' event
diacart.clear(); // clear cart, triggers 'clear' event
diacart.removeListener("order", onOrder); // remove event listener
FAQs
Simple shopping cart based on localStorage
We found that diacart demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.