Add To Cart Button


Components:
First, you need to create your AddToCart
component which will be responsible for the logic and import withHandlers
from recompose.js
. It will help us increase rendering speed and avoid memory leaks in the future.
We will also use axios in this example, so let's add it as well.
import { withHandlers } from 'recompose';
import axios from 'axios';
The AddToCartButton component could look like this:
const AddToCartButton = withHandlers({
onClick: ({ item }) => async (event) => {
// Prevent clicking item
event.stopPropagation();
const item_id = item.get('id');
const variant_item_id = item.get('selected_variant_id');
// Send events
await item.analytics.sendEvent('add-to-cart', { item_id, variant_item_id, quantity: 1, rid: item.meta.toJS().rid });
await item.analytics.sendEvent('click-item', { item_id, variant_item_id, rid: item.meta.toJS().rid });
// Your code
...
}
})(({ onClick }) =>
<button className='YOUR CSS CLASS' onClick={onClick}>
Add to cart
</button>
)
const AddToCartButton = withHandlers({
onClick: ({ item }) => async (event) => {
// Prevent clicking item
event.stopPropagation();
const item_id = item.get('id');
const variant_item_id = item.get('selected_variant_id');
// Send events
await item.analytics.sendEvent('add-to-cart', { item_id, variant_item_id, quantity: 1, rid: item.meta.toJS().rid });
await item.analytics.sendEvent('click-item', { item_id, variant_item_id, rid: item.meta.toJS().rid });
window.location.href = `/cart.php?action=add&product_id=${item_id}`;
}
})(({ onClick }) =>
<button className='YOUR CSS CLASS' onClick={onClick}>
Add to cart
</button>
)
import axios from 'axios';
const AddToCartButton = withHandlers({
onClick: ({ item }) => async (event) => {
// Prevent clicking item
event.stopPropagation();
const item_id = item.get('id');
const variant_item_id = item.get('selected_variant_id');
// Send events
await item.analytics.sendEvent('add-to-cart', { item_id, variant_item_id, quantity: 1, rid: item.meta.toJS().rid });
await item.analytics.sendEvent('click-item', { item_id, variant_item_id, rid: item.meta.toJS().rid });
await axios.post('/cart/add', {
quantity: 1,
id: item.getIn(['variants_ids', 0]) // //SET CORRECT VARIANT ID IF THERE ARE MULTIPLE
})
}
})(({ onClick }) =>
<button className='YOUR CSS CLASS' onClick={onClick}>
Add to cart
</button>
)
Result
The final markup of your component could look like this:
/**
* @module components/Cards/Product
*/
import React from 'react'
import classNames from 'classnames'
import Image from 'components/common/Image'
import Truncate from 'components/common/Truncate'
import Text from 'components/Text'
import Rating from 'components/Cards/Product/Rating';
import Price from 'components/Cards/Product/Price';
import template from 'helpers/template';
import { DiscountSticker, OutOfStockSticker } from 'components/Cards/Product/Stickers';
import { Map, List } from 'immutable'
import { IProduct, MJSConfiguration, ThemedSFCProps } from 'types';
import { withHandlers } from 'recompose' // <= Import helper
import axios from 'axios' // <= Import axios if you need to send request
const Title: any = ({ text, theme, ...rest }) => (
<Text display-if={!!text} className={theme.title} {...rest}>{text}</Text>
);
const Description: any = ({ text, theme, ...rest }) => (
<p
display-if={!!text}
className={theme.description}
{...rest}
>
<Truncate>{text}</Truncate>
</p>
);
export interface IProductCardProps extends ThemedSFCProps {
item: IProduct;
config: MJSConfiguration;
}
// Your Button component
const AddToCartButton = withHandlers({
onClick: ({ item }) => async (event) => {
// Prevent clicking item
event.preventDefault();
event.stopPropagation();
const item_id = item.get('id');
const variant_item_id = item.get('selected_variant_id');
// Send events
await item.analytics.sendEvent('add-to-cart', { item_id, variant_item_id, quantity: 1, rid: item.meta.toJS().rid });
await item.analytics.sendEvent('click-item', { item_id, variant_item_id, rid: item.meta.toJS().rid });
// Your code
...
}
})(({ onClick }) =>
<button className='YOUR CSS CLASS' onClick={onClick}>
Add to cart
</button>
)
const ProductCardView: React.SFC<IProductCardProps> = ({
item,
config,
theme,
}: any) => (
<a
onClick={item.onClick}
href={item.get('product_url')}
className={classNames(
theme.root,
config.get('simple') && theme.simple,
theme.productCard,
)}
>
<div className={classNames(theme.imageWrap)}>
<Image
className={classNames(theme.image)}
aspectRatio={config.getIn(['product', 'image', 'aspectRatio'], 1)}
thumbnail={item.get('thumbnail_url')}
src={item.get('image_url') || item.get('thumbnail_url')}
alt={item.get('title')}
/>
<div display-if={config.getIn(['product', 'stickers', 'display'])}>
<DiscountSticker
config={config}
className={theme.discountSticker}
discount={item.get('discount')}
display-if={
config.getIn(['stickers', 'discount']) &&
config.getIn(['product', 'stickers', 'display']) &&
item.get('discount', List()).size &&
item.getIn(['stickers', 'discount'])
} />
</div>
</div>
<div display-if={config.getIn(['product', 'reviews', 'display']) && !!item.getIn(['reviews', 'count'])} className={theme.rating}>
<Rating value={item.getIn(['reviews', 'average_score'])} count={item.getIn(['reviews', 'count'])} />
</div>
<div
className={theme.variants}
display-if={
config.getIn(['product', 'variants', 'display']) &&
item.get('variants', List()).size > 1
}
>
{
template(config.getIn(['product', 'i18n', 'variants'], 'Available in %s variants'))(
item.get('variants', List()).size
)
}
</div>
<div className={theme.content}>
<Title
theme={theme}
display-if={config.getIn(['product', 'title', 'display'])}
text={item.get('title')}
config={config.getIn(['product', 'title'])} />
<Description
theme={theme}
display-if={config.getIn(['product', 'description', 'display'])}
text={item.get('description')}
config={config.getIn(['product', 'description'])} />
<Price
className={theme.priceWrapper}
display-if={config.getIn(['product', 'price', 'display'])}
price={item.get('price')}
oldPrice={item.get('compare_at')}
discount={item.get('discount')}
currency={config.get('currency').toJS()} />
<OutOfStockSticker
display-if={item.getIn(['stickers', 'out-of-stock'])}
config={config} />
{
// Add your component somewhere in the markup
}
<AddToCartButton item={item} />
</div>
</a>
)
export default ProductCardView;
Add to Cart custom functionality
Since Findify is a third-party application, we have no connection to the Cart components of your store. This means that in order to integrate your Add to Cart solution with the subsequent frontend actions on your store (adding the product to the Cart through API, opening the mini-carts, showing messages once the product is added etc), you need to setup a function that can then be utilized in Findify customizations.
Requirements: We suggest to come up with the simplest functions available in the global (window) scope across all possible pages where Findify widgets are present:
window.addToCart('some variant/product id', 1);
Where the first parameter is either a variant or a product id of the product and the second one is the quantity of product that needs to be added to the cart.
The first argument has to be a variant id in case you have some kind of variant selectors implementation.
Updated 7 months ago