CyberStore Ecommerce 2023 Documentation
Cart_QuickOrder Widget

A quick order entry widget. Introduced in 2023.1.

 Remarks

The Cart_QuickOrder widget presents the shopper with an easy way to quickly add one or more lines to a shopping cart by entering just an item's stock code and a quanitty.

The widget provides much of the same functionality as the ShoppingCartQuickEntryControl while providing a more streamline user experience.  The widget displays the current cart. Allows items to be added or removed from the cart while also allowing the quantities of items in the cart to be updated.  Any fees that are added to the items are displayed. 

When entering a stock code, the widget utilizes an autocomplete function to aid the shopper in finding the correct item. As the shopper enters text into the input box, suggestions are automatically listed.

 

The shopper may elect to remove lines, or adjust quantites and as they do so, updates are made to the cart automatically. Further functionality allows for users to see stock levels and select a ship from warehouse (when enabled for the shopper's Customer Class).

Warehouse Display and Selection

The shopper can see current inventory levels by clicking the check Stock button.

If the user selects the 'Change' link next to the warehouse information displayed under the item, they will be able to select the warehouse from which the item will ship.

After selecting a warehouse, the new warehouse will be displayed along with any added fees associated with the warehouse change.

 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.

       

Search Options

If the EnableFilterModeSelection option is set to true and the AutoCompleteSearchMode property is set to a value that enables search functionality for the stock code input the autocomplete dropdown will be enabled (default, true)

The AutoCompleteSearchMode option controls the functionality of the Stock Code input field. Three values can be set for this property, 'Contains', 'StartsWith', and 'Exact'

Property Value Behavior

StockCodeFilterMinimumLength If the autocompleted search for stock code is enabled, this value establishes the number of characters that a user must type in the stock code box before any search results appear. (default, 2)

StockCodeFilterDelay - allows the user to set a time delay on the AutoComplete search feature in milliseconds. (default, 10).

StockCodeFilterDropDownLength - This property sets the number of items that will be displayed in the autocomplete drop-down. (default, 8)

Display Options

ShowColumnHeader - if set to true the header with column names will be displayed when there are items in the cart. (default, true)

DisplayCartHeaderCustomerPrice - If set to true the Customer price column will be displayed. (default, true)

StockCodeColumnHeaderText - Sets the text displayed for the column header if enabled. (default, 'Stock Code')

DescriptionColumnHeaderText - Sets the text displayed for the column header if enabled. (default, 'Description')

QuantityColumnHeaderText - Sets the text displayed for the column header if enabled. (default, 'Qty')

ExtPriceColumnHeaderText - Sets the text displayed for the total price column header if enabled. (default, 'Total')

OnHandQuantityColumnHeaderText - Sets the text displayed for the column header if enabled. (default, 'Stock')

Navigation Options

DefaultFocusedElementID Use the field ID to set the focus on page load. (['skuNumber' or 'skuQty'] default, 'skuNumber')

AfterQuantityFocusedElementID - Use the field ID to set the element that will get focus after the Quantity field loses focus. ( ['addToCartBtn','skuNumber', 'skuQty'] default, 'addToCartBtn')

QuantityInputEnterBehavior - Determines what happens when the enter button is clicked while the Quantity field has focus. (['tab','addToCart'] default,'addToCart')

EnableOnHandQuantityDisplay - If set to true the user will have the ability to click a button and see the on-hand inventory data for the item.

 Widget Conventions
 Example

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

<Control src="LoadWidgetControl.ascx" FileLocation="Cart_QuickOrder.html" RequireLogin="true" 
    Options=" 
        ShowColumnHeader: true,
        DisplayCartHeaderCustomerPrice: true,
        AutoCompleteSearchMode: 'StartsWith',
        StockCodeFilterMinimumLength: 2,
        EnableFilterModeSelection: true,
        StockCodeFilterDelay: 10,
        EnableOnHandQuantityDisplay: true,
        StockCodeFilterDropDownLength: 8,
        StockCodeColumnHeaderText: 'Stock Code',
        DescriptionColumnHeaderText: 'Description',
        QuantityColumnHeaderText: 'Qty',
        ExtPriceColumnHeaderText: 'Total',
        OnHandQuantityColumnHeaderText: 'Stock',
        DefaultFocusedElementID: 'skuNumber',  
        AfterQuantityFocusedElementID: 'addToCartBtn',
        QuantityInputEnterBehavior: 'addToCart'"
/>
 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 type="text/css">
    row-label Price .container {
        width: 85 !important;
    }

    .addStockCodeInput {
        margin: 20px 0;
    }

    .rowClass1 {
        padding: 0 5px;
        display: inline-block;
    }

    .field-label {
        display: inline-block;
    }

    .field-value {
        display: inline-block;
        padding: 10px;
        font-weight: bold;
    }
    tr.dx-row.dx-header-row {
        font-weight: 700;
        color: #000;
        font-size:14px;
    }
    .listHeader {
        padding: 5px;
        display: inline-block;
        font-weight: 700;
        font-size: 14px;
    }

        .listHeader.Price {
            justify-self: end;
            text-align: right;
        }

        /*REVIEW  */
        .listHeader.show-stock {
            justify-self: center;
            text-align: right;
        }

    .row.qoeRows {
        margin-bottom: 0;
    }

    .listData {
        padding: 5px;
        display: inline-block;
        white-space: normal;
    }

    .cartListHeader {
        /*REVIEW visibility: hidden */
        visibility: hidden;
        background-color: rgb(187, 208, 236);
        display: grid;
        grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
        grid-gap: 10px;
        align-items: end;
    }

    .details {
        display: grid;
        grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
        grid-gap: 10px;
        align-items: center;
    }

    #cartList .dx-list-item-content {
        padding: 10px 10px 0;
    }

    .dx-item.dx-list-item {
        border: 1px solid #e1e1e1;
        margin-bottom: 9px;
    }

        .dx-item.dx-list-item:nth-child(even) {
            background: #f6f6f6;
        }

    .btnClass {
        width: 320px;
    }

    .dx-button-has-text .dx-button-content,
    .dx-button.dx-button-default {
        padding: 5px;
        top: -2px;
        position: relative;
    }

    .listData.btnWrapper.dx-button {
        margin: 0 5px;
        max-height: 40px;
        height;
    }

    .listData.OHQ {
        display: none;
    }

    .dx-list-item-after-bag.dx-list-static-delete-button-container {
        /*  position: fixed;*/
    }

    .dx-list-static-delete-button,
    .dx-list-switchable-delete-button {
        position: relative;
        top: 15px;
        right: 25px;
    }

    .dx-numberbox.dx-texteditor.dx-numberbox-spin,
    .dx-texteditor-input {
        /*width: auto !important;*/
        max-width: 90px;
        padding: 0 3px 0;
        height: 40px;
    }

    .dx-autocomplete .dx-texteditor-input {
        max-width: 200px;
    }

    div#goToCartBtn {
        width:fit-content
        min-width: 90px;
        margin: 25px 0;
    }
    div#goToCartBtn .dx-button-content {
        padding: 5px 10px;
    }
    .qtyWrapper {
        display: grid;
        grid-template-columns: 2fr 1fr;
        min-width: 120px;
        align-items: center;
    }

    .warehouseDetail {
        justify-content: flex-start;
        padding: 0 15px;
    }

    .warehouse-text {
        /* font-weight: bold; */
        color: crimson;
    }

    /* Image */
    .listData.image {
        padding: 0;
        text-align: center;
    }

    .image img {
        max-height: 70px;
        width: auto;
    }

    .listData.deleteBtn {
        background-color: transparent !important;
        /*background-image: url(/Ecommerce/Images/close.png);*/
        background-size: 40px;
    }

        .listData.deleteBtn:hover {
            background-color: transparent !important;
            /*background-image: url(/Ecommerce/Images/close-over.png);*/
            background-size: 40px;
        }

    /* Pricing */
    .listHeader.totalPrice,
    .listData.totalPrice,
    .listData.itemDescription {
        font-weight: 700;
    }

    /* Fee ROWS  */
    .FeeRowWrapper {
        min-height: 30px;
        background: #d9d9d9;
    }

    .FeeRow {
        display: grid;
        grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
        background: #d9d9d9;
        grid-gap: 10px;
        align-items: baseline;
    }

    .warehouseFeeRow {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 220px));
        background: #d9d9d9;
    }

    /*REVIEW Original css  */
    /* .row-warehouse-SelectLink {
        grid-column: span 2;
        justify-self: end;
    } */
    .row-warehouse-SelectLink {
        grid-column: span 1;
        justify-self: start;
        padding-left: 10px;
    }

    /* REVIEW needed padding */
    .warehouse-link {
        padding: 5px;
        display: inline-block;
        white-space: normal;
    }

    .FeeRow > div,
    .warehouseFeeRow > div {
        /* padding: 5px 0; */
        align-items: baseline;
    }

    .fee-row-img {
        justify-self: center;
    }

        .fee-row-img img {
            max-width: 20px !important;
        }

    .fee-row-TotalPrice2 {
        justify-self: end;
        font-weight: 700;
        align-items: baseline;
    }

    .listData.btnWrapper.showStockBtn.dx-button.dx-button-default.dx-button-mode-contained.dx-widget.dx-button-has-text.dx-state-focused,
    /* #clearFormBtn.dx-state-focused, */
    #addToCartBtn.dx-state-focused,
    .listData.btnWrapper.deleteBtn.dx-button.dx-button-default.dx-button-mode-contained.dx-widget.dx-state-focused {
        border-color: #337ab7;
    }

    @media (min-width: 328px) {
        .cartListHeader {
            display: none;
        }

        .details {
            display: grid;
            grid-template-columns: 2fr 2fr 4fr 2fr;
            grid-gap: 10px;
            padding: 5px;
        }

        .fee-row-img {
            justify-self: start;
        }

        .listData.showStockBtn {
            grid-column: auto / span 3;
        }

        .listData.OHQ {
            grid-column: auto / span 3;
        }

        .listData.deleteBtn {
            grid-column: auto / span 1;
            justify-self: end;
        }

        .listData.defaultPrice:before {
            display: none;
            content: 'Default Price:  ';
            font-weight: 700;
        }

        .listData.customerPrice:before {
            /* display: none; */
            content: 'Customer Price:  ';
            font-weight: 700;
        }

        .listData.discountPrice:before {
            display: none;
            content: 'Discount Price:  ';
            font-weight: 700;
        }

        .listData.webPrice:before {
            /* display: none; */
            content: 'Web Price:  ';
            font-weight: 700;
        }

        .listData.totalPrice:before {
            /* display: none; */
            content: 'Total Price:  ';
            font-weight: 700;
        }

        .listData.btnWrapper.deleteBtn.dx-button {
            margin-bottom: 15px;
        }

        .FeeRow {
            grid-template-columns: repeat(2, 1fr) 2fr repeat(4, 1fr) 1fr 1fr;
        }

            .FeeRow .row-label {
                grid-column: span 7;
                white-space: normal;
            }

        /* REVIEW noved spacer two to the end of fee row??*/
        .spacerTwo {
            display: none;
            /* background-color: red; */
        }

        /*REVIEW Original css  */
        /* .row-warehouse-SelectLink {
            grid-column: span 6;
            justify-self: end;
        } */

        .row-warehouse-SelectLink {
            grid-column: span 1;
            justify-self: start;
        }

        /* REVIEW needed padding */
        .warehouse-link {
            padding: 5px;
            display: inline-block;
            white-space: normal;
        }
    }

    @media (min-width: 1020px) {
        .cartListHeader {
            display: grid;
        }

        .details {
            display: grid;
            grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
            grid-gap: 10px;
            padding: 0px 10px;
        }

        .fee-row-img {
            justify-self: center;
        }

        .listData.defaultPrice {
            grid-column: auto;
            justify-self: end;
        }

        .listData.customerPrice {
            grid-column: auto;
            justify-self: end;
        }

        .listData.discountPrice {
            grid-column: auto;
            justify-self: end;
        }

        .listData.webPrice {
            grid-column: auto;
            justify-self: end;
        }

        .listData.totalPrice {
            grid-column: auto;
            justify-self: end;
        }

        .listData.showStockBtn {
            grid-column: auto;
            justify-self: center;
        }

        .listData.OHQ {
            grid-column: auto;
        }

        .listData.deleteBtn {
            grid-column: auto;
            justify-self: end;
        }

        .listData.defaultPrice:before {
            display: none;
        }

        .listData.customerPrice:before {
            display: none;
        }

        .listData.discountPrice:before {
            display: none;
        }

        .listData.webPrice:before {
            display: none;
        }

        .listData.totalPrice:before {
            display: none;
        }

        .listData.btnWrapper.deleteBtn.dx-button {
            margin-bottom: 0px;
        }

        .FeeRow {
            grid-template-columns: repeat(2, 1fr) 3fr repeat(4, 1fr) 3fr 1fr;
        }

            /*REVIEW Original code
        .FeeRow .row-label {
            grid-column: span 2;
        } */

            .FeeRow .row-label {
                grid-column: span 1;
            }

        /*REVIEW Original code
        .row-warehouse-SelectLink {
            grid-column: span2;
        }*/

        .row-warehouse-SelectLink {
            grid-column: span 1;
        }

        /* REVIEW needed padding */
        .warehouse-link {
            padding: 5px;
            display: inline-block;
            white-space: normal;
        }
    }

    /* START styles inported from WarehouseShipFrom_Display */
    .outer > * {
    }

    .data {
        font-weight: bold;
        padding-right: 5px;
        padding-left: 5px;
    }

    .listLine {
        padding: 5px 0px;
    }

    .dx-popup-wrapper > .dx-overlay-content {
        padding: 15px;
    }

    .dx-popup-content .outer {
        margin-bottom: 20px;
        display: grid;
        grid-template-columns: 1fr 1fr;
    }

    .popUpTitle {
        font-weight: bold;
        padding-right: 10px;
        padding-left: 10px;
        font-size: 1.3em;
    }

    div#simpleList {
        font-size: 1.2em;
    }

    #simpleList .dx-list-item-selected {
        font-weight: 700;
    }

    .warehouseList {
        display: grid;
        /* justify-content: start; */
        grid-template-columns: 1fr 3fr 1fr 1fr;
        justify-items: start;
    }

    .warehouseBox {
        margin-top: 15px;
        display: inline-block;
    }

        .warehouseBox .data-row.outer {
            margin-right: -15px;
        }

    .row-warehouse-SeviceFee.data {
        margin-left: auto;
    }

    .warehouseCode.listLine {
    }

    .warehouseDesc.listLine {
    }

    .warehouseRank.listLine {
    }

    .warehouseFee.listLine {
        margin-left: auto;
        text-align: right;
        padding: 5px 0px
    }

    div#whLink:before {
    }

    /* REVIEW Original css  */
    /* div#whLink {
        display: block;
        font-weight: 700;
    } */
    /* span#whLink {
        display: inline-flex;
        justify-self: end;
        font-weight: 700;
    } */

    .btnholder {
        float: right;
        justify-self: end;
    }

        .btnholder button {
            background-color: #657680;
            color: #fff;
            padding: 8px 20px;
            border-radius: 7px;
            border-width: 0;
        }

            .btnholder button:hover {
                background-color: #000;
            }

    .warehouseBox .dx-popup-content {
        min-height: 200px;
    }


    /* END styles inported from WarehouseShipFrom_Display */
    /* QSTARINT CSS moved from bottom */
    .addStockCodeInput {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
        gap: 15px;
    }

    #skuNumber {
        order: 1;
        grid-column: auto / span 3;
    }

    /* #clearFormBtn {
        order: 2;
    } */

    /* #clearFormBtn, */
    .showStockBtn.dx-button-mode-contained.dx-button-default {
        color: #000000;
        font: 12px Tahoma, Geneva, sans-serif;
        border: 1px solid #7F7F7F;
        background: #E0DFDF url(/ECommerce/DXR.axd?r=1_77-Me8wi) repeat-x top;
        padding: 1px;
    }

        /*
        #clearFormBtn:hover, */
        .showStockBtn.dx-button-mode-contained.dx-button-default:hover {
            color: #000000;
            background: #F2F2F2 url('/ECommerce/DXR.axd?r=1_78-Me8wi') repeat-x top;
            border: 1px solid #606060;
        }

    #skuQty {
        order: 3;
    }

    #addToCartBtn {
        order: 4;
    }

    .dx-button-mode-contained.dx-button-default {
        background-color: #657680;
        border-color: transparent;
        color: #fff;
    }

        .dx-button-mode-contained.dx-button-default.dx-state-hover {
            background-color: #000;
        }

        .dx-button-mode-contained.dx-button-default.dx-state-focused {
            background-color: #657680;
            border-color: #337ab7;
            color: #fff
        }

    .cartListHeader {
        background-color: #d9d9d9;
        /* display: none; */
    }

    /* REVIEW original css */
    /* div#whLink {
        display: grid;
        font-weight: 700;
        margin-right: 20px;
    } */
    /* span#whLink {
        display: inline-flex;
        justify-self: end;
        padding-left: 10%;
        /* display: grid;
        font-weight: 700;
        margin-right: 20px;
        font-weight: 700;
    } */

    .dx-radiobutton-icon-checked .dx-radiobutton-icon-dot {
        background: #013CA6;
    }

    .One,
    .Three,
    .spacerTwo,
    .spacerThree {
        display: none;
    }
</style>

<div class="quickOrderWrapper">
    <!--Headder-->
    <div id="Main_Title">
        <h3>
            Quick Order Entry
        </h3>
        <div class="infoStatement">
            Quickly add items directly to your cart by entering stock codes below.
        </div>
    </div>
    <!--Subtotal-->
    <div class="subTotalDisplay">
        <div class="field-label">
            Subtotal:
        </div>
        <div class="field-value" id="subTotal">
        </div>
    </div>
    <!--Add stockCode to Cart-->
    <div class="addStockCodeInput">
        <div class="rowClass1" id="skuQty">
        </div>
        <div class="rowClass1" id="skuNumber">
        </div>
        <div class="rowClass1" id="addToCartBtn">
        </div>
    </div>
</div>
<!-- Header for DX list control -->
<div class="cartListHeader">
    <div class="listHeader">
    </div>
    <div id="stockCodeColumnHeader" class="listHeader"></div>
    <div id="DescriptionColumnHeader" class="listHeader"></div>
    <div class="qtyWrapper">
        <div id="QuantityColumnHeader" class="listHeader"></div>
        <!-- spacer for UOM -->
        <div class="listHeader"></div>
    </div>
    <!-- REVIEW -->
    <div class="listHeader Price One defaultPrice">
        Default Price
    </div>
    <div class="listHeader Price Two customerPrice">
        Customer Price
    </div>
    <div class="listHeader Price Three discountPrice">
        Discount Price
    </div>
    <div class="listHeader Price Four WebPrice">
        Web Price
    </div>
    <div id="ExtPriceColumnHeader" class="listHeader Price totalPrice"></div>
    <div id="OnHandQuantityColumnHeader" class="listHeader show-stock"></div>
</div>
<div id="cartList">
</div>
<div id="goToCartBtn">
</div>
<!-- For popup?? -->
<div class="warehouseBox">
</div>
<div id="popupContainerView">
</div>
</div>
<script>

    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Base Widget:  Cart_QuickOrder.html
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' (c) 2022 by Dovetail Internet Technologies, LLC
    // '              www.dovetailinternet.com
    // '              info@dovetailinternet.com
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' All rights reserved. Not to be used without permission.
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Development Date: Jan 2022
    // ' Release Version:  2.21.0
    // ' Revision: 1.0
    // ' Modified: 12/09/2022
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    // Global Variables
    var cartDataSource_widgetID = [];
    var CartList_widgetID;
    const AllAvalibleWarehouseNames = [];
    const Profile = { PreferredWarehouse: '', EnableWarehouseSelection: false };
    let NoPrefWarehouseInfo = { Warehouse: '', Description: `No Preference`, InventoryQty: 0, SurchargeFee: '', SurchargeFeeAmount: 0 };



    /**================================================================================================
     **                                      processCartData_widgetID
     *?  Takes the cart data combindes item detail lines and fee lines then uses data for dx.list dataSource?
     *@param cart cartData obj from different ajax call
     *@return cartDataSource_widgetID Array used as the data source for disply cart(list)
     *================================================================================================**/
    function processCartData_widgetID(cart) {
        cartDataSource_widgetID = [];
        let feeArray = [];
        let combinedCartRow = [];

        cart.Data.Detail.forEach((row, i) => {
            if (row.Parent_ID != -1) {
                feeArray.push(row);
            }
            if (row.Parent_ID == -1) {
                combinedCartRow.push(row);
            }
        });

        for (var i = 0; i < combinedCartRow.length; i++) {
            for (var j = 0; j < feeArray.length; j++) {
                if (feeArray[j].Parent_ID == combinedCartRow[i].ID) {
                    combinedCartRow[i].fee = feeArray[j];
                }
            }
            if (cart.Data.OriginalDetail) {
                if (cart.Data.OriginalDetail.Item_ID == combinedCartRow[i].Item_ID) {
                    combinedCartRow[i].OriginalDetail = cart.Data.OriginalDetail;
                }
            }
        }

        cartDataSource_widgetID = combinedCartRow;
        $('#subTotal').html(cart.Data.SubTotal);
        CartList_widgetID.option('dataSource', cartDataSource_widgetID);

        //NOTE if there are items in the cart and ShowColumnHeader === true
        if (!_.isEmpty(cartDataSource_widgetID) && widgetOptions.ShowColumnHeader) {
            $('.cartListHeader').show();
        }
        else {
            $('.cartListHeader').hide();
        }

        SetUpCartDisplay(!_.isEmpty(cartDataSource_widgetID));
        NotifyCart();
        clearForm();
        setFocus(widgetOptions.DefaultFocusedElementID);
        //REVIEW focus now set with widgetOption $('#skuNumber').dxAutocomplete('focus');
    }

    /**================================================================================================
     **                                      SetUpCartDisplay
     *? use widget options to determin what columns are displayed. ?
     *? This function is called if there are items in the cart. ?
     *@param hasItems bool
     *================================================================================================**/
    function SetUpCartDisplay(hasItems) {
        if (hasItems) {
            $('.cartListHeader').css("visibility", "visible");

            if (widgetOptions.DisplayCartHeaderCustomerPrice) {
                $('.listData.customerPrice').css("visibility", "visible");
                $('.listHeader.Price.Two.customerPrice').css("visibility", "visible");
            } else {
                $('.listData.customerPrice').css("visibility", "hidden");
                $('.listHeader.Price.Two.customerPrice').css("visibility", "hidden");
            }
            //NOTE col header
            $('#stockCodeColumnHeader').html(widgetOptions.StockCodeColumnHeaderText);
            $('#DescriptionColumnHeader').html(widgetOptions.DescriptionColumnHeaderText);
            $('#QuantityColumnHeader').html(widgetOptions.QuantityColumnHeaderText);
            $('#ExtPriceColumnHeader').html(widgetOptions.ExtPriceColumnHeaderText);
            $('#OnHandQuantityColumnHeader').html(widgetOptions.OnHandQuantityColumnHeaderText);
            //NOTE display DiscountPrice
            // if (widgetOptions.DisplayCartHeaderDiscountPrice) {
            //     $('.listData.discountPrice ').css("visibility", "visible");
            //     $('.listHeader.Price.Three.discountPrice').css("visibility", "visible");
            // } else {
            //     $('.listData.discountPrice ').css("visibility", "hidden");
            //     $('.listHeader.Price.Three.discountPrice').css("visibility", "hidden");
            // }
            //NOTE display DefaultPrice
            // if (widgetOptions.DisplayCartHeaderDefaultPrice) {
            //     $('.listData.defaultPrice').css("visibility", "visible");
            //     $('.listData.defaultPrice.One.defaultPrice').css("visibility", "visible");
            // } else {
            //     $('.listData.defaultPrice').css("visibility", "hidden");
            //     $('.listData.defaultPrice.One.defaultPrice').css("visibility", "hidden");
            // }
        }
    }

    /**================================================================================================
     **                                      setFocus
     *?  What does it do?
     *@param is string
     *================================================================================================**/
    function setFocus(id) {
        if (id === 'skuQty') {
            $('#skuQty').dxNumberBox('focus');
        }
        if (id === 'skuNumber') {
            $('#skuNumber').dxAutocomplete('focus');
        }
        if (id === 'addToCartBtn') {
            $('#addToCartBtn').dxButton('focus');
        }
        if (id === 'goToCartBtn') {
            $('#goToCartBtn').dxButton('focus');
        }
    }


    $(function () {
        //variables
        let skuNumberDataSource = {};
        let skuNumberDataSearchMode = '';
        /**================================================================================================
        *                                      widgetOptions
        *================================================================================================**/
        widgetOptions.ShowColumnHeader = widgetOptions.ShowColumnHeader ?? true;
        widgetOptions.DisplayCartHeaderCustomerPrice = widgetOptions.DisplayCartHeaderCustomerPrice ?? true;
        widgetOptions.AutoCompleteSearchMode = widgetOptions.AutoCompleteSearchMode ?? 'StartsWith'; // [Contains,StartsWith,Exact]
        widgetOptions.StockCodeFilterMinimumLength = widgetOptions.StockCodeFilterMinimumLength ?? 2;
        widgetOptions.EnableFilterModeSelection = widgetOptions.EnableFilterModeSelection ?? true;
        widgetOptions.StockCodeFilterDelay = widgetOptions.StockCodeFilterDelay ?? 0;
        widgetOptions.EnableOnHandQuantityDisplay = widgetOptions.EnableOnHandQuantityDisplay ?? true;
        widgetOptions.StockCodeFilterDropDownLength = widgetOptions.StockCodeFilterDropDownLength ?? 8;
        widgetOptions.StockCodeColumnHeaderText = widgetOptions.StockCodeColumnHeaderText ?? 'Stock Code';
        widgetOptions.DescriptionColumnHeaderText = widgetOptions.DescriptionColumnHeaderText ?? 'Description';
        widgetOptions.QuantityColumnHeaderText = widgetOptions.QuantityColumnHeaderText ?? 'Qty';
        widgetOptions.ExtPriceColumnHeaderText = widgetOptions.ExtPriceColumnHeaderText ?? 'Total';
        widgetOptions.OnHandQuantityColumnHeaderText = widgetOptions.OnHandQuantityColumnHeaderText ?? 'Stock';
        widgetOptions.DefaultFocusedElementID = widgetOptions.DefaultFocusedElementID ?? 'skuNumber';  //'[skuNumber, skuQty]'
        widgetOptions.AfterQuantityFocusedElementID = widgetOptions.AfterQuantityFocusedElementID ?? 'skuNumber'; //'[addToCartBtn,skuNumber, skuQty]'
        widgetOptions.QuantityInputEnterBehavior = widgetOptions.QuantityInputEnterBehavior ?? 'addToCart'; //[tab,addToCart]
        widgetOptions.AddToCartButtonCssClass = widgetOptions.AddToCartButtonCssClass ?? '';
        //REVIEW future add other pricing cols to cart grid
        // // widgetOptions.DisplayCartHeaderDefaultPrice = widgetOptions.DisplayCartHeaderDefaultPrice ?? true;
        // // widgetOptions.DisplayCartHeaderDiscountPrice = widgetOptions.DisplayCartHeaderDiscountPrice ?? true

        //NOTE Template get underscore
        _.templateSettings.variable = 'item';

        /*==================================  START OF FORM INPUTS SECTION ==========================================*/
        if (widgetOptions.EnableFilterModeSelection) {
            if (widgetOptions.AutoCompleteSearchMode !== 'Exact') {
                skuNumberDataSearchMode = widgetOptions.AutoCompleteSearchMode;
                skuNumberDataSource = new DevExpress.data.CustomStore(
                    {
                        loadMode: 'raw',
                        load: function () {
                            return $.getJSON('/ecommerce/exports/stockcodes.json');
                        }
                    }
                )
            }
        }

        $('#skuNumber').dxAutocomplete({
            dataSource: skuNumberDataSource,
            placeholder: 'Enter Stock Code...',
            width: '320px',
            valueExpr: 'stockcode',
            searchExpr: ['stockcode', 'name'],
            itemTemplate: function (data, index) {
                return data.stockcode + ' - ' + data.name;
            },
            showClearButton: true,
            onEnterKey: function (e) {
                e.component.blur();
                $('#skuQty').dxNumberBox('focus');
                //confirmItemToAdd();
            },
            onFocusOut: function () {
                /$('#skuQty').dxNumberBox('focus');
            },
            tabIndex: 1,
            searchMode: skuNumberDataSearchMode,
            minSearchLength: widgetOptions.StockCodeFilterMinimumLength,
            searchTimeout: widgetOptions.StockCodeFilterDelay,
            maxItemCount: widgetOptions.StockCodeFilterDropDownLength
        });

        $('#skuQty').dxNumberBox({
            value: 1,
            min: 1,
            mode: 'number',
            placeholder: 'Qty',
            showSpinButtons: true,
            width: '100px',
            onFocusIn: e => { e.element.find('.dx-texteditor-input').select() },
            onFocusOut: e => { setFocus(widgetOptions.AfterQuantityFocusedElementID) },
            valueChangeEvent: 'input enterKey',
            onValueChanged: function (e) {
                if (e.value == null || e.value == 0) {
                    e.component.option('value', 1);
                }
            },
            onEnterKey: function (e) {
                if (widgetOptions.QuantityInputEnterBehavior === 'addToCart') {
                    confirmItemToAdd();
                }
                if (widgetOptions.QuantityInputEnterBehavior === 'tab') {
                    setFocus(widgetOptions.AfterQuantityFocusedElementID);
                }
                //confirmItemToAdd();
                // $('#skuNumber').dxAutocomplete('focus');
            },
            tabIndex: 2,
        });

        $('#addToCartBtn').dxButton({
            stylingMode: 'contained',
            text: 'Add To Cart',
            elementAttr: {
                class: 'DT-Button'
            },
            type: 'default',
            width: 120,
            onClick: function () { confirmItemToAdd() },
            tabIndex: 3,
        });

        $('#goToCartBtn').dxButton({
            stylingMode: 'contained',
            text: 'Checkout',
            elementAttr: {
                class: 'DT-Button'
            },
            type: 'default',
            width: 90,
            onClick() {
                //REVIEW redirect to Cart while the checkout redirect requirments are pending
                //document.location = SITE_PATHS.application + '/Checkout.aspx';
                document.location = SITE_PATHS.application + '/ShoppingCart.aspx';
            },
        });
        /*==================================  END OF FORM INPUTS SECTION ==========================================*/

        setFocus(widgetOptions.DefaultFocusedElementID);

        //TODO
        $('#addToCartBtn').addClass(widgetOptions.AddToCartButtonCssClass);


        /**========================================================================
         **                           confirmItemToAdd
         *?  Confirms form input data and submits getWarehouseForNewItem(stockcode, qty) if data is valid?
         *@return getWarehouseForNewItem(stockcode, qty)
         *========================================================================**/
        function confirmItemToAdd() {
            //NOTE what if the autocomplete is not a stockcode
            let qty = $('#skuQty').dxNumberBox('option', 'value') ?? 1;
            let stockcode = $('#skuNumber').dxAutocomplete('option', 'value')?.toUpperCase() ?? ''
            if (stockcode === '') {
                ToastAlert('You must select a valid stock code.', false);
                $('#skuNumber').dxAutocomplete('focus');
                return;
            }
            getWarehouseForNewItem(stockcode, qty);
        }


        /**================================================================================================
         **                                      buildCartDisplay
         *?  Gets the cart data, sends the data to the processCartData_widgetID function for proccessing ?
         *?  then displays the dxList using the cartTemplate ?
         *@return data obj
         *================================================================================================**/
        function buildCartDisplay() {

            let noDataMsg = ``;
            CartList_widgetID = $('#cartList').dxList({
                height: 'auto',
                itemTemplate: $('#cartTemplate'),
                noDataText: noDataMsg,
                allowItemDeleting: false,
                focusStateEnabled: false,
                activeStateEnabled: false,
                onInitialized: function (e) {
                    try {
                        MakeAJAXCall('Cart.GetCart', {},
                            function (DATA) {
                                if (DATA != null) {
                                    var data = JSON.parse(DATA);
                                    if (data.Result.Success) {
                                        Profile.EnableWarehouseSelection = data.LookupData.Profile?.EnableWarehouseSelection ?? false;
                                        Profile.PreferredWarehouse = data.LookupData.Profile?.PreferredWarehouse ?? '';
                                        AllAvalibleWarehouseNames.push(data.LookupData.Warehouses);
                                        if (data.Data?.Detail.length > 0) {
                                            processCartData_widgetID(data);
                                        }
                                        //NOTE if the cart detail === 0 or if data.Data is null or undefined then display
                                        if (data.Data?.Detail.length <= 0) {
                                            noDataMsg = `There are no items in the cart.`;
                                            $('#cartList').dxList('option', 'noDataText', noDataMsg);
                                            $('.cartListHeader').hide();
                                        }
                                        //NOTE if data.Data === null or if Detail.length =< 0
                                        if (data.Data?.Detail?.length === undefined || data.Data?.Detail?.length <= 0) {
                                            noDataMsg = `There are no items in the cart.`;
                                            $('#cartList').dxList('option', 'noDataText', noDataMsg);
                                            $('.cartListHeader').hide();
                                        }
                                    }
                                    if (!data.Result.Success) {
                                        ToastAlert('Can not find the cart data ' + data.Message, false);
                                    }
                                }
                            });
                    } catch (error) {
                        console.log(error);
                    }
                },
                onItemDeleted: function (e) { }
            }).dxList('instance');
        }
        //NOTE lets get the cart data and load the page.
        buildCartDisplay();

    });//end of load ready


    /**================================================================================================
     **                                      addItemToCart
     *?  Adds a new Iten to the cart then it updates the datasource for the the dx.list where cart data is displayed?
     *@param stockcode str
     *@param qty int
     *@param warehouse string
     *@return Array
     *================================================================================================
    ///     * INFO
    ///     Type of the unit of measure valid options are as follows: Stocking : "stocking", "STK",
    ///     "S" or 1 Alternate : "alternate", "ALT", "A" or 2 Other : "other", "OTH", "O" or 3
    ///     Preferred : "preferred", "PREF", "P" or 0. Alternatively, the actual UOM label p the up[date if the slection has not changed
    ///     by an @ symbol (i.e. "@EA") which will then be translated to the appropriate UOM type.
     *================================================================================================**/
    function addItemToCart(stockcode, qty, warehouse) {
        try {
            MakeAJAXCall('Cart.AddItemToCartByStockCode', {
                StockCode: stockcode,
                Qty: qty,
                UOM: 0
                , Options: { Warehouse: warehouse }
            }, function (DATA) {
                if (DATA != null) {
                    var data = JSON.parse(DATA);
                    if (data.Result.Success) {
                        processCartData_widgetID(data);
                    }
                    if (!data.Result.Success) {
                        ToastAlert(`The item could not be added to the Order. ${data.Message}`, false);
                    }
                }
            })
        } catch (error) {
            console.log(error);
        }
    }


    ///-------------------------------------------------------------------------------------------------
    /// <summary>
    ///     Display the in Stock information for an Item
    /// </summary>
    ///
    /// <param name='item'>
    ///     Cart line item detail with fee data appended if the fee{} exists
    /// </param>
    ///-------------------------------------------------------------------------------------------------
    function showStockData(item) {
        try {
            MakeAJAXCall('Inventory.GetItemInventoryQuantities', {
                Item_ID: item.Item_ID
                , UOM: item.UnitType
            }, function (DATA) {
                if (DATA != null) {
                    var data = JSON.parse(DATA);
                    if (data.Result.Success) {
                        if (data.Data.Warehouses && data.Data.Warehouses.length > 0) {
                            $('#showStockBtn_' + item.ID).hide()
                            $('#showStockData_' + item.ID).show();
                            $warehousecontainer = $('#showStockData_' + item.ID);
                            $warehousecontainer.empty();
                            var uom = ((data.Data.UOM != '' && data.Data.UOM != null) ? data.Data.UOM : 'EA')
                            var warehouseRow = $('<div>').addClass('data-row outer');
                            $('<div>')
                                .addClass('data totalOHQ')
                                .text(data.Data.InventoryQty + ' ' + uom + ' Limited Available')
                                .appendTo(warehouseRow);
                            data.Data.Warehouses.forEach(function (val, i) {
                                $('<div>')
                                    .addClass('warehouseDetail')
                                    .html('<span class="warehouse">' + val.Warehouse + '</span>' + '  ' + '<span class="warehouseQTY">' + val.InventoryQty + '</span>')
                                    .appendTo(warehouseRow);
                            });
                            warehouseRow.appendTo($warehousecontainer);
                        }
                        if (!data.Data.Warehouses) {
                            ToastAlert('There is no warehouse data for ' + item.Item_ID, false);
                        }
                    }
                }
            }
            )
        } catch (error) {
            console.log(error);
        }
    }


    /**================================================================================================
     **                                      buildDisplayWidgetRow
     *?  Called from the template for each cart item line. Duilds the display and inputs for each item line?
     *@param item{}  Cart item line detail with appended fee if fee exists processCartData_widgetID(cart)
     *================================================================================================**/
    function buildDisplayWidgetRow(item) {
        $('#qty_' + item.ID).dxNumberBox({
            mode: 'number',
            min: 1,
            value: item.Quantity,
            width: '100px',
            showSpinButtons: true,
            onEnterKey: function (e) {
                e.component.blur();
            },
            onValueChanged: function (e) {
                if (e.value == null || e.value == 0) {
                    e.value = e.previousValue;
                }
            },
            onFocusOut: function (e) {
                var newQty = e.component._$submitElement[0].value;
                if (newQty != item.Quantity && newQty != null) {
                    updateCartLineWarehouse(item.ID, item.StockCode, newQty, item.UnitType, item.Warehouse);
                }
            }
        });
        //NOTE if widgetOptions.EnableOnHandQuantityDisplay then create button else create empty div
        if (widgetOptions.EnableOnHandQuantityDisplay) {
            $('#showStockBtn_' + item.ID).dxButton({
                stylingMode: 'contained',
                text: 'Check Stock',
                elementAttr: {
                    class: 'DT-Button'
                },
                type: 'default',
                width: 110,
                onClick() {
                    showStockData(item);
                }
            });
        }
        if (!widgetOptions.EnableOnHandQuantityDisplay) {
            $('#showStockBtn_' + item.ID).html('<div class=""></div>')

        }


        $('#deleteItem_' + item.ID).dxButton({
            stylingMode: 'contained',
            text: '',
            icon: 'trash',
            type: 'default',
            width: 40,
            elementAttr: {
                class: 'deleteButton DT-Button',
            },
            onClick() {
                try {
                    MakeAJAXCall('Cart.DeleteCartLine', {
                        'ID': item.ID
                    }, function (DATA) {
                        if (DATA != null) {
                            var data = JSON.parse(DATA);
                            if (data.Result.Success) {
                                processCartData_widgetID(data);
                            }
                            if (!data.Result.Success) {
                                ToastAlert('The item ' + item.StockCode + ' has not been deleted from your cart.' + data.Result.Message, false);
                            }
                        }
                    }
                    )
                } catch (error) {
                    console.log(error)
                }
            },
        });
    }


    /**================================================================================================
     **                                      getWarehouseDescription
     *?  returns Warehouse Description by lookup ?
     *@param warehouse str
     *@return Warhouse.Description string
     *================================================================================================**/
    function getWarehouseDescription(warehouseName) {
        const { Warehouse, Description } = NoPrefWarehouseInfo;
        if (warehouseName == Warehouse) {
            return Description;
        }
        let x = AllAvalibleWarehouseNames[0].find(e => e.Warehouse == warehouseName);
        return x.Description
    }


    /**================================================================================================
     **                                      getWarehouseDescription
     *?  returns Warehouse Description by lookup ?
     *@param warehouse str
     *@return Warhouse.Description string
     *================================================================================================**/
    function getWarehouseDescription(warehouseName) {
        const { Warehouse, Description } = NoPrefWarehouseInfo;
        if (warehouseName == Warehouse) {
            return Description;
        }
        let x = AllAvalibleWarehouseNames[0].find(e => e.Warehouse == warehouseName);
        return x.Description
    }


    /**================================================================================================
     **                                      buildServiceFeeRow
     *?  Builds the service fee line. Function called from the template as the display list is rendered.?
     *@param item{}  Cart item line detail with appended fee if fee exists processCartData_widgetID(cart)
     *================================================================================================**/
    function buildServiceFeeRow(item) {
        let cartItemFeeLine = { ItemDetail: {} };
        cartItemFeeLine.ItemDetail = Object.assign({}, item)

        let wareHouseName = getWarehouseDescription(item.Warehouse);
        let TotalPrice = '';
        let Description = '';

        let warehouseNameText = `Will Ship from warehouse: ${wareHouseName} ${item.Warehouse}`;
        if (!_.isUndefined(cartItemFeeLine.ItemDetail.fee) && !_.isEmpty(cartItemFeeLine.ItemDetail.fee)) {
            TotalPrice = cartItemFeeLine.ItemDetail.fee.TotalPrice ?? '';
            Description = cartItemFeeLine.ItemDetail.fee.Description ?? '';
        }

        if (Profile.EnableWarehouseSelection) {
            $('<div>')
                .addClass('fee-row-spacer spacerOne')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-img')
                .prepend('<img id="theImg" src="/ecommerce/images/arrow-right-angle.png" />')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .attr('id', 'wareHouseName_' + item.ID)
                .addClass('row-label')
                .text(warehouseNameText)
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<span>')
                .addClass('row-warehouse-SelectLink')
                .attr('id', 'whLink' + item.ID)
                .html('<a class="warehouse-link">Change</a>')
                .on('click', function () {
                    getInventoryWarehouseData(cartItemFeeLine);
                })
                .appendTo('#wareHouseName_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer spacerThree')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer spacerFour')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-TotalPrice2')
                .html(Description)
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-TotalPrice2')
                .html(TotalPrice)
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer spacerTwo')
                .appendTo('#serviceFeeRow_' + item.ID);
        }


        //Build display row without Warehouse data
        if (Profile.EnableWarehouseSelection == false && item.fee) {
            $('<div>')
                .addClass('fee-row-spacer')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-img')
                .prepend('<img id="theImg" src="/ecommerce/images/arrow-right-angle.png" />')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('row-label')
                .text('')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer')
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-TotalPrice2')
                .html(Description)
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-TotalPrice2')
                .html(TotalPrice)
                .appendTo('#serviceFeeRow_' + item.ID);
            $('<div>')
                .addClass('fee-row-spacer')
                .text('')
                .appendTo('#serviceFeeRow_' + item.ID);
        }
    }

    /**================================================================================================
     **                                      getInventoryWarehouseData
     *? get the inventory warehouse data for the popup then display the popup?
     *@param cartLineData obj
     *@return type
     *================================================================================================**/
    function getInventoryWarehouseData(cartLineData) {
        //build an obj with the data we need
        let warehousePopupData = Object.assign({}, cartLineData);
        try {
            MakeAJAXCall(
                'Inventory.GetItemInventoryQuantities',
                {
                    Item_ID: cartLineData.ItemDetail.Item_ID,
                    UOM: cartLineData.ItemDetail.UnitType,
                }, function (DATA) {
                    if (DATA != null) {
                        var data = JSON.parse(DATA);
                        if (data.Result.Success) {
                            if (data?.Data?.Warehouses === undefined) {
                                ToastAlert(`Warehouse selection is not avalible for this item. Please contact customer service.`, false);
                                return;
                            }
                            //NOTE the item wh is the wh we want. need the arr of wh for the popup.  add no pref to arr
                            if (data?.Data?.Warehouses !== undefined) {
                                const ItemWarehouseArray = [...data?.Data?.Warehouses];
                                if (ItemWarehouseArray.length === data.Data.Warehouses.length) {
                                    ItemWarehouseArray.unshift(NoPrefWarehouseInfo);
                                }
                                warehousePopupData.ItemTnventory = Object.assign({}, data.Data);
                                warehousePopupData.ItemWarehouseArray = [...ItemWarehouseArray];
                                buildWarehousePopup(warehousePopupData);
                            }
                            if (!data.Result.Success) {
                                throw error = Result.Message
                            }
                        }
                    }
                })
        } catch (error) {
            console.log(error)
        }
    }


    /**========================================================================
     **                           getWarehouseForNewItem
     *?  Find the correct Warehouse for when the item is first added to the cart?
     *@param stockcode str
     *@param qty int
     *@return theWarehouse string
     *========================================================================**/
    function getWarehouseForNewItem(stockcode, qty) {
        let warehouse = '';
        try {
            MakeAJAXCall('Inventory.GetItemInventoryQuantitiesByStockCode', {
                StockCode: stockcode,
                UOM: 0
            }, function (DATA) {
                if (DATA != null) {
                    var data = JSON.parse(DATA);
                    if (data.Result.Success) {
                        //NOTE 1.preferredWarehouse
                        if (data.Data.PreferredWarehouse != '') {
                            warehouse = data.Data.PreferredWarehouse;
                        }//NOTE 2.DefaultWarehouse
                        else if (data.Data.PreferredWarehouse == '' && data.Data.DefaultWarehouse != '') {
                            warehouse = data.Data.DefaultWarehouse;
                        }
                        addItemToCart(stockcode, qty, warehouse)
                    }
                }
            })
        } catch (error) {
            console.log(error);
        }
    }


    /**================================================================================================
     **                                      buildWarehousePopup
     *?  Build the warehouse selector popup.?
     *@param warehousePopupData JSON
     * {ItemDetail:{},ItemTnventory:{},ItemWarehouseArray:{}}
     *================================================================================================**/
    function buildWarehousePopup(warehousePopupData) {
        const OriginalItemWarehouse = [];
        const SelectedItemWarehouse = [];

        var dataArr = warehousePopupData.ItemWarehouseArray

        var listWidget = $('<div id="simpleList">').dxList({
            height: 'auto',
            dataSource: dataArr,
            editEnabled: true,
            allowItemDeleting: false,
            hoverStateEnabled: true,
            showSelectionControls: true,
            selectionMode: 'single',
            onSelectionChanged: function (e) {
                if (_.isEmpty(e.removedItems)) {
                    OriginalItemWarehouse.WareHouseBeforPopup = Object.assign([], e.addedItems)
                    SelectedItemWarehouse.SelectedWarehouse = Object.assign([], e.addedItems);
                }
                if (!_.isEmpty(e.removedItems)) {
                    SelectedItemWarehouse.SelectedWarehouse = Object.assign([], e.addedItems);
                }

            },
            itemTemplate: function (dataArr, index) {
                var result = $('<div>').addClass('warehouseList');
                $('<div>')
                    .addClass('warehouseCode listLine')
                    .text(dataArr.Warehouse)
                    .appendTo(result);
                $('<div>')
                    .addClass('warehouseDesc listLine')
                    .text(dataArr.Description)
                    .appendTo(result);
                $('<div>')
                    .addClass('warehouseRank listLine')
                    .text(dataArr.Status)
                    .appendTo(result);
                $('<div>')
                    .addClass('warehouseFee listLine')
                    .html(dataArr.SurchargeFee)
                    .appendTo(result);
                return result;
            },
        });

        $('#popupContainerView').dxPopup({
            showTitle: false,
            height: 'auto',
            width: '600px',
            closeOnOutsideClick: false,
            onHiding: function () { },
            contentTemplate: function (contentElement) {
                var popUpHead = $('<div>').addClass('outer');
                $('<div>')
                    .addClass('popUpTitle')
                    .text('Select a warehouse')
                    .appendTo(popUpHead);
                $('<div>')
                    .addClass('btnholder DT-Button')
                    .attr('id', 'closeBtn')
                    .html('<button>X</button>')
                    .on('click', function (e) {
                        if (SelectedItemWarehouse.SelectedWarehouse[0].Warehouse === OriginalItemWarehouse.WareHouseBeforPopup[0].Warehouse) {
                            $('#popupContainerView').dxPopup('instance').hide();
                            return;
                        }
                        if (SelectedItemWarehouse.SelectedWarehouse[0].Warehouse !== OriginalItemWarehouse.WareHouseBeforPopup[0].Warehouse) {
                            let id = warehousePopupData.ItemDetail.ID;
                            let stockCode = warehousePopupData.ItemDetail.StockCode;
                            let qty = warehousePopupData.ItemDetail.Quantity;
                            let uom = warehousePopupData.ItemDetail.UnitType;
                            let warehouse = SelectedItemWarehouse.SelectedWarehouse[0].Warehouse;
                            updateCartLineWarehouse(id, stockCode, qty, uom, warehouse);
                        }
                        $('#popupContainerView').dxPopup('instance').hide();
                    })
                    .appendTo(popUpHead);
                contentElement.append(popUpHead);
                contentElement.append(listWidget);
            },
        });
        $('#popupContainerView').dxPopup('instance').show();

        //NOTE when the popup loads the current item warehouse for that line item should be selected.
        let itemWarehousePopupDefaultIndex = warehousePopupData.ItemWarehouseArray.findIndex(x => x.Warehouse == warehousePopupData.ItemDetail.Warehouse);
        updatePopupSelectedWarehouse(warehousePopupData.ItemWarehouseArray[itemWarehousePopupDefaultIndex]);
    }


    /**================================================================================================
     **                                      updatePopupSelectedWarehouse
     *?  Updates the selected warehouse when the popup loads ?
     *@param arr array item with a warehouse
     *@return array selectedKeys
     *================================================================================================**/
    function updatePopupSelectedWarehouse(arr) {
        let selectedKeys = []
        selectedKeys.push(arr);
        const list = $('#simpleList').dxList('instance');
        list.option('selectedItemKeys', selectedKeys);
    }


    /**================================================================================================
     **                                      updateCartLineWarehouse
     *?  Updates the cart line Item Warehouse with the user selected warehouse. ?
     *?  Reloads the dataSourse for the cart dx.list  ?
     *@param Item_Detail_Inventory combined warehouse & cart data.
     *@return updated Cart data
     *================================================================================================**/
    function updateCartLineWarehouse(id, stockCode, qty, uom, warehouse) {
        //NOTE confirmed the warehouse has changed before update
        try {
            MakeAJAXCall('Cart.UpdateCartLine', {
                ID: id,
                StockCode: stockCode,
                Qty: qty,
                UOM: uom,
                Options: {
                    Warehouse: warehouse
                }
            }, function (DATA) {
                if (DATA != null) {
                    var data = JSON.parse(DATA);
                    if (data.Result.Success) {
                        processCartData_widgetID(data);
                        //ToastAlert('The Quanty of ' + item.StockCode + ' has changed from ' + item.Quantity + ' to ' + newQty);
                    }
                    if (!data.Result.Success) {
                        ToastAlert(`The Warehouse could not be updated. ${data.Result.Message}`, false);
                        console.log(data.Result.Message);
                    }
                }
            })
        } catch (error) {
            console.log
        }
    }


    /**================================================================================================
     **                                      clearForm
     *?  clears form ?
     *================================================================================================**/
    function clearForm() {
        $('#skuQty').dxNumberBox('option', 'value', 0);
        $('#skuNumber').dxAutocomplete('option', 'value', '');
    }

</script>

<!--* INFO --->
<script id="cartTemplate" type="text/html">
    <div class='row qoeRows'>
        <div class='dataRows'>
            <div class='dataRowOne'>
                <div class='details'>
                    <div class=' listData image'>
                        <img src='<%= item.Photo %>' />
                    </div>
                    <div class='listData stockCode'><%= item.StockCode %></div>
                    <div class='listData itemDescription'><a href= <%= item.URL %>><%= item.Description %></a></div>
                    <div class='qtyWrapper'>
                        <div class='listData selectWrapper' id='qty_<%= item.ID %>'></div>
                        <div class='listData'><%= item.UOM %></div>
                    </div>
                    <div class='listData defaultPrice One'><%= item.DefaultPrice %></div>
                    <div class='listData customerPrice Two'><%= item.CustomerPrice %></div>
                    <div class='listData discountPrice Three'><%= item.DiscountPrice %></div>
                    <div class='listData webPrice Four'><%= item.WebPrice %></div>
                    <div class='listData totalPrice'><%= item.TotalPrice %></div>
                    <div class='listData btnWrapper showStockBtn' id='showStockBtn_<%= item.ID %>'></div>
                    <div class='listData OHQ' id='showStockData_<%= item.ID %>'></div>
                    <div class='listData btnWrapper deleteBtn' id='deleteItem_<%= item.ID %>'></div>
                </div>
                <div class='FeeRowWrapper'>
                    <div class='FeeRow' id='serviceFeeRow_<%= item.ID %>'></div>
                </div>
            </div>
        </div>
    </div>
    <% $(function () { buildDisplayWidgetRow(item); }); %>
    <% $(function () { buildServiceFeeRow(item); }); %>
</script>
<style> 
.dx-button-has-text .dx-button-content {
    overflow: visible;
}
</style>