CyberStore Ecommerce 2023 Documentation
Shopping Cart Widget

A shopping cart display widget. Introduced in 2023.1. 

 Remarks

The ShoppingCart widget can be used to display a dynamic shopping cart count badge.

As one adds items to cart the badge can update it's count and highlight the badge. This functinality is provided by the new ShoppingCart widget.

The ShoppingCart widget gets the number of items currently in your cart and displays it as a badge injected into a specified selector. The count is first updated on page load and again when an item is added to the cart. To implement the widget, use the LoadWidgetControl (see example below) and place it into your page, theme or control.

 Widget Option Usage

Widget options provide a way to customize widgets in various ways. Widget options are sent to the widget when loaded with the LoadWidgetControl.

       

The value of the badgeParentSelector option sets the ID, class or HTML element name of the selector in your page where the badge will be inserted. Once on your page the badge will be able to be referenced with the an ID of "spnCartBadge" which loads with the class of "badge cart" and when the cart is updated the "notice" class is appended and then removed after a wait period which allow for highlighting.

By default, the cart will check for updates every 5 seconds, but this can be changed using the checkCartInterval option by supplying a wait time in milliseconds, at 5 seconds, the default then is a value of 5000.

 Example

See an example of how to load and configure this widget in SitePages.config.

<Control src="LoadWidgetControl.ascx"
     FileLocation="ShoppingCart.html"
     Options="
        badgeParentSelector: '.icon-banknote',
        checkCartInterval:5000"
/>
 Widget Source

The following is the source code for this widget.

Developer's Note:

To create a custom version of the widget, copy all of the code below into a file of the same name and place it into your Site's widgets folder (e.g., ../YourSiteFolder/Widgets). The CyberStore page engine will then override the default source with your customized version.

<style>
.miniShoppingCart{font-family:inherit;font-size:12px;display:none}.messageRow .alert{background:#f5e8cd}.alert span{font-weight:bold}.cartContent{padding:15px;background:#ecebeb;max-width:315px}.cartRow{padding:15px 0}.cartRow .image{padding:0}.cartItem .name{font-weight:bold;white-space:normal}.price-container{padding:0 5px 0 0}.col-sm-9.unitpriceRow{padding-right:5px}.QTY{padding:5px 0}.QTY input{width:30px;text-align:center;margin:0 5px}.unitprice{padding:7px 0}.itemtotal{font-weight:bold;font-size:1.1em;text-align:right}.deleteItem{font-size:10px;text-align:right;width:20px;float:right}span.remove-circle{background:#b60c0c;padding:3px 6px;color:#fff;border-radius:64%}.miniShoppingCart .divider{float:none;margin:auto;border-bottom:1px gray solid}.cartTotals.row{text-align:right;margin:15px -15px;padding:0 5px 0 0}.subtotalPrice{font-size:1.3em;font-weight:bold}.subtotalLabel{font-size:14px;padding:0 15px}button.btn.btn-primary{font-size:1.0;min-width:115px}.btnCheckout{text-align:right}@media screen and (max-width:767px){.itemtotal{font-weight:bold;font-size:1.1em;text-align:left;padding:15px}}
</style>

<script type="text/javascript">
    var cartData = { Data: { ItemCount: -1, Detail:[{}]  }};
    var lastCartData = cartData;

    $(function () {
        if ($(widgetOptions.badgeParentSelector).length || $(widgetOptions.badgeParentSelector)[0]) {
            if ($('#spnCartBadge').length <= 0) {
                $(widgetOptions.badgeParentSelector)
                    .append($('<span />')
                        .attr('id', 'spnCartBadge')
                        .attr('class', 'badge cart'));
            }
        }

        MakeAJAXCall("Cart.GetCartItemCount", {}, UpdateCart);

        
    });

    function UpdateCart(DATA) {
        if (DATA !== 'undefined' && DATA != null) {
            lastCartData = cartData;
            cartData = JSON.parse(DATA);

            if (cartData != lastCartData) {
                if (cartData.Data != null && cartData.Data.ItemCount != null && !isNaN(cartData.Data.ItemCount)) {
                    if ($('#spnCartBadge').length) {
                        if (cartData.Data.ItemCount == 0) {
                            $('#spnCartBadge').text('');
                        }
                        else {
                            if (lastCartData.Data.ItemCount != cartData.Data.ItemCount) {
                                if (widgetOptions.enableMiniCart) {
                                    MakeAJAXCall("Cart.GetCart", {}, LoadCart);
                                }
                                $('#spnCartBadge').text(cartData.Data.ItemCount);
                                if (lastCartData.Data.ItemCount > -1) {
                                    $('#spnCartBadge').addClass('notice');
                                    setTimeout(function () { $('#spnCartBadge').removeClass('notice'); }, 5000);
                                }
                            }
                        }
                    }
                }
            }
        }

        if (widgetOptions.enableLiveCartStatus) {
            setTimeout(function () {
                MakeAJAXCall("Cart.GetCartItemCount", {}, UpdateCart);
            }, widgetOptions.checkCartInterval || 5000);
        }
    }

    function LoadCart(DATA) {
        var newCart = JSON.parse(DATA);
        if (newCart.hasOwnProperty('Data')) {
            if (newCart.Data.hasOwnProperty('Detail')) {
                $("#listWidget").dxList({
                    height: 500,
                    width: 290,
                    dataSource: newCart.Data.Detail,
                    itemTemplate: $("#item-template"),
                }).dxList("instance");
                $('#spnSubTotal').text(newCart.Data.SubTotal);
                $('.miniShoppingCart').css('display', 'block');
            }
        }
    }
</script>

<div class="miniShoppingCart">
    <div class="cartContent">
        <div class="messageRow row">
            <div class="alert"><span>Alert:</span> 1 item(s) in your cart is back ordered.</div>
        </div>
        <div id="listWidget"></div>
        <div class="cartTotals row">

            <div class="subtotalPrice"><span class="subtotalLabel"> Subtotal </span><span id="spnSubTotal"></span></div>
        </div>
        <div class="checkout row">
            <div class="col-xs-6 btnEdit"> <button class="btn btn-primary DT-Button">EDIT</button> </div>
            <div class="col-xs-6 btnCheckout"><button class="btn btn-primary DT-Button">CHECK OUT</button></div>
        </div>
    </div>
</div>

<script type="text/html" id="item-template">
    <div class="cartRow row">
        <div class="col-xs-6 col-sm-3 image">
            <img src="<%= Photo %>" alt="" class="img-responsive" >
        </div>
        <div class="col-xs-6 cartItem">
            <div class="name"><%= Description %></div>
            <div class="stockcode"><%= StockCode %></div>

        </div>
        <div class="col-xs-6 col-sm-3 price-container">
            <div class="itemtotal"><%= TotalPrice %></div>

        </div>
        <div class="col-xs-12 col-sm-9 pull-right unitpriceRow">
            <div class="col-xs-5 QTY">QTY:<input type="text" placeholder="<%= Quantity %>"></div>
            <div class="col-xs-7 unitprice"><%= WebPrice %> <%= UOM %> <div class="deleteItem"><span class="remove-circle" aria-hidden="true">X</span></div></div>
        </div>
    </div>
</script>
<script type="text/html" id="empty-template">
    <div></div>
</script>