CyberStore Documentation
Items_TileListing Widget

A tile listing widget for Items. Introduced in v2.18. 

 Remarks
The Items_TileListing widget is designed as a display alternative to the CatalogItemTileListingControl to provide similar presentation while maximizing use of AJAX from the client side for optimal performance. The widget is built to be used within a Category or search results page to display Items within the scope of the page.
 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.

While the scope of Items to display is initially determined by the Category for the page the widget is loaded into, or the search terms used by a Shopper, there are widget options available to further extend or limit that scope. Setting the includeItemsFromAllChildCategories option to true extends the Items shown to include all items in sub categories of the current Category, while a value of false contains them to the current Category. Items selected for inclusion can also be refined using the includeModels (default true), includeStockCodes (default true) and includeSKUs (defautl false) options.

The scope can be further altered by limiting it to a specific Category or categories, to do so set the overrideCategoryList option to a single Category_ID or a comma-separated list of IDs in a string format - for example '41,43,45,57'. A Category's ID can be obtained by opening the Edit Category popup for the desired categroy in the Console's Items > Items and Category Mainteannce screen.

Tile Layout Options

Options available for handling certain traits of the individual tiles displayed include the following.

The main wrapper that contains all the tiles displayed can have an overall specified size, the height option by default has a value of 'auto' but can be set to any valid CSS value for a typical height style. Should the size not be tall enought to show all tiles, then the tile overflow will occur within the main wrapping container and a scroll bar will be available based on the value of the showScrollBar option. Valid values are true (default), or false.

The tileHeight option sets the height of each Item tile in pixels. The default is 415. The width of the tiles is then set using the tileWidth option, which has a default value of 240. The pixel padding space around tiles is set to a default numeric value of 12 can be overrideen using the tileMargin option.

The order in which Item tiles are displayed is determined by the search configurations for the site (see Site Manager), but the direction in which they are presented can be controlled by the tileFlowDirection option. The default direction is 'vertical' (top to bottom), but can also be set to 'horizontal' (left to right).

Each tile displayed is bound with a border. The showTileBorder option has a default value of true, but the border can be hidden by setting the values to false.

Though disabled by default, it is possible to highlight each tile whenever the Shopper clicks on one. To turn this feature on, set the enableHighlightOnTileClick option to true

Pager Options

The widget's display includes the use of a pager for navigating through larger numbers of Items by spreading them across one or more pages of results. The default number of tiles per page in the results can be set directly using the option pageSize by setting it to any number desired keeping in mind that if the total number of records is less than or equal to the value set, a single page will display. The default value of -1 indicates that the "Item Listing Page Size" value will used. The setting is located in the Catalog Configuration tab of the Site Manager.

The pager presents a series of clickable buttons to navigate forward or backward and links for each page in the total results. The default text for the navigation buttons are 'Prev' and 'Next' but these can be customized using the previousPageButtonText and nextPageButtonText options, respectively.  

Behaviors controlling the presention of the Previous and Next buttons under certain conditions can be determined with pager show options. The pagerShowPrevAtEdge option can be used to disable displaying a previous button in the pager when on the first page, set the value to false, default is true. In a similar manner, the pagerShowNextAtEdge opiton disables displaying a next button when on the last page if the value is false, default is true. Finally, if there is only a single page then the pagerShowJustOne option will turn off any pager from showing at all when there is only a single page,  default is true which will show the pager in this case.

When there are a large number of pages, a long sequence will be dispalayed as a series of buttons in the beginning, another at the end, and an ellipsis, '...',  in the middle. The pagerButtonsDisplayedBeforeEllipsis determines the maximimun number of buttons for the beginning using a default value of 3. The number of buttons at the end are set using the pagerButtonsAtEdge option, the default being 2.

Should the number of pages exceed available space, the middle ellipsis button can be set to enable any page direct navigation when clicked. The default widget enables this, but it can be disabled by setting the enableGoToPageByEllipsis option to false.

The pager can be styled using one of three supllied themes. The pagerCSSClass option accepts values of 'light-theme' (default), 'dark-theme' or 'compact-theme'.

Add to Carrt Label Options

When an Item is able to be added to a Shopper's cart, the Add to Cart button can be customized using the addToCartButtonText option - the default being 'Add to Cart' and then upon successfully adding to the cart  the addedToCartButtonText option, which has a default of 'Added to Cart' can also be customized.   

The label used for the quantity input box be default is 'Qty:' but can be altered using the qtyLabelText option.

When an Item fails to add to the cart for some reason, the message displayed will be returned from the attempted addition of the item. However the message can be customized if so desired, using the addToCartErrorMessageText.

Additionally, the addedToCartMessageTimeout enables you to dictate the number of milliseconds before the Added to Cart message is displayed after clicking the Add to Cart button and the Item is successfully added. When this option is not set with a value it defaults to 1500, or 1.5 seconds.

Similarily, the addToCartErrorMessageTimeout enables you to dictate the number of milliseconds before an error message is displayed when after clicking the Add to Cart button and the Item is not successfully added. When this option is not set with a value it defaults to 3500, or 3.5 seconds.

The link to an Item's detail page reads 'Detail View' by default. The learnMoreLinkText option lets one set the label differently.

 Widget Conventions
 Example

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

<!-- Example: Options showing default values -->
<Control src="LoadWidgetControl.ascx"
    FileLocation="Items_TileListing.html" 
    Options="
        includeItemsFromAllChildCategories: false,
        enableHighlightOnTileClick: false,
        tileHeight: 415,
        tileWidth: 240,
        tileMargin: 12,
        showScroll: true,
        tileFlowDirection: 'vertical',
        height: 'auto',
        overrideCategoryList: PAGE_CATEGORY,
        includeModels: true,
        includeStockCodes: true,
        includeSKUs: false,
        pageSize: -1,
        showTileBorder: true,
        pagerCSSClass: 'light-theme',
        pagerButtonsDisplayedBeforeEllipsis: 3,
        previousPageButtonText: 'Prev',
        nextPageButtonText: 'Next',
        enableGoToPageByEllipsis: true,
        pagerButtonsAtEdge: 2,
        addToCartButtonText: 'Add to Cart',
        addedToCartButtonText: 'Added to Cart',
        addedToCartMessageTimeout: 1500,
        addToCartErrorMessageText: null,
        addToCartErrorMessageTimeout: 3500,
        addToCartError: null,
        learnMoreLinkText: 'Detail View',
        qtyLabelText: 'Qty:'"
/>
 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.

<script src='/Ecommerce/Widgets/image_zoom.min.js'></script>
<script src='/Ecommerce/js/simplePagination/jquery.simplePagination.min.js?2.21.2'></script>
<link href='/Ecommerce/Widgets/image_zoom.min.css' rel='stylesheet'>
<style>
    ul.simple-pagination {
        list-style: none
    }

    .simple-pagination {
        display: block;
        overflow: hidden;
        padding: 0 5px 5px 0;
        margin: 0
    }

        .simple-pagination ul {
            list-style: none;
            padding: 0;
            margin: 0
        }

        .simple-pagination li {
            list-style: none;
            padding: 0;
            margin: 0;
            float: left
        }

    span.ellipse.clickable {
        cursor: pointer
    }

    .ellipse input {
        width: 3em
    }

    .compact-theme span {
        cursor: pointer
    }

    .compact-theme a, .compact-theme span {
        float: left;
        color: #333;
        font-size: 14px;
        line-height: 24px;
        font-weight: 400;
        text-align: center;
        border: 1px solid #aaa;
        border-left: none;
        min-width: 14px;
        padding: 0 7px;
        box-shadow: 2px 2px 2px rgba(0,0,0,.2);
        background: #efefef;
        background: -moz-linear-gradient(top,#fff 0,#efefef 100);
        background,#efefef));
        background: -webkit-linear-gradient(top,#fff 0,#efefef 100);
        background);
        background: -ms-linear-gradient(top,#fff 0,#efefef 100);
        background)
    }

        .compact-theme a:hover, .compact-theme li:not(.disabled):not(.active) span:hover {
            text-decoration: none;
            background: #efefef;
            background: -moz-linear-gradient(top,#efefef 0,#bbb 100);
            background,#bbb));
            background: -webkit-linear-gradient(top,#efefef 0,#bbb 100);
            background);
            background: -ms-linear-gradient(top,#efefef 0,#bbb 100);
            background)
        }

    .compact-theme li:first-child a, .compact-theme li:first-child span {
        border-left: 1px solid #aaa;
        border-radius: 3px 0 0 3px
    }

    .compact-theme li:last-child a, .compact-theme li:last-child span {
        border-radius: 0 3px 3px 0
    }

    .compact-theme .current {
        background: #bbb;
        background: -moz-linear-gradient(top,#bbb 0,#efefef 100);
        background,#efefef));
        background: -webkit-linear-gradient(top,#bbb 0,#efefef 100);
        background);
        background: -ms-linear-gradient(top,#bbb 0,#efefef 100);
        background);
        cursor: default
    }

    .compact-theme .ellipse {
        background: #eaeaea;
        padding: 0 10px;
        cursor: default
    }

    .light-theme span {
        cursor: pointer
    }

    .light-theme a, .light-theme span {
        float: left;
        color: #666;
        font-size: 14px;
        line-height: 24px;
        font-weight: 400;
        text-align: center;
        border: 1px solid #bbb;
        min-width: 14px;
        padding: 0 7px;
        margin: 0 5px 0 0;
        border-radius: 3px;
        box-shadow: 0 1px 2px rgba(0,0,0,.2);
        background: #efefef;
        background: -moz-linear-gradient(top,#fff 0,#efefef 100);
        background,#efefef));
        background: -webkit-linear-gradient(top,#fff 0,#efefef 100);
        background);
        background: -ms-linear-gradient(top,#fff 0,#efefef 100);
        background)
    }

        .light-theme a:hover, .light-theme li:not(.disabled):not(.active) span:hover {
            text-decoration: none;
            background: #fcfcfc
        }

    .light-theme .current {
        background: #666;
        color: #fff;
        border-color: #444;
        box-shadow: 0 1px 0 rgba(255,255,255,1),0 0 2px rgba(0,0,0,.3) inset;
        cursor: default
    }

    .light-theme .ellipse {
        background: 0;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        font-weight: 700;
        cursor: default
    }

    .dark-theme span {
        cursor: pointer
    }

    .dark-theme a, .dark-theme span {
        float: left;
        color: #ccc;
        font-size: 14px;
        line-height: 24px;
        font-weight: 400;
        text-align: center;
        border: 1px solid #222;
        min-width: 14px;
        padding: 0 7px;
        margin: 0 5px 0 0;
        border-radius: 3px;
        box-shadow: 0 1px 2px rgba(0,0,0,.2);
        background: #555;
        background: -moz-linear-gradient(top,#555 0,#333 100);
        background,#333));
        background: -webkit-linear-gradient(top,#555 0,#333 100);
        background);
        background: -ms-linear-gradient(top,#555 0,#333 100);
        background)
    }

        .dark-theme a:hover, .dark-theme li:not(.disabled):not(.active) span:hover {
            text-decoration: none;
            background: #444
        }

    .dark-theme .current {
        background: #222;
        color: #fff;
        border-color: #000;
        box-shadow: 0 1px 0 rgba(255,255,255,.2),0 0 1px 1px rgba(0,0,0,.1) inset;
        cursor: default
    }

    .dark-theme .ellipse {
        background: 0;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        font-weight: 700;
        cursor: default
    }

    .circle-theme span {
        cursor: pointer
    }

    .circle-theme a, .circle-theme span {
        float: left;
        color: #666;
        font-size: 12px;
        line-height: 24px;
        font-weight: 400;
        text-align: center;
        min-width: 14px;
        padding: 0 7px;
        margin: 0 5px 0 0
    }

        .circle-theme a:hover, .circle-theme li:not(.disabled):not(.active) span:hover {
            text-decoration: none;
            color: #464646;
            font-weight: 600
        }

    .circle-theme .current {
        background: #828282;
        color: #fff;
        border: 1px solid #979797;
        width: 25px;
        height: 25px;
        cursor: default;
        border-radius: 50%
    }

        .circle-theme .current.next, .circle-theme .current.prev, .circle-theme li a.page-link.next, .circle-theme li a.page-link.prev {
            background: 0;
            color: #444;
            width: fit-content;
            height: 25px;
            cursor: default;
            border-width: 0;
            box-shadow: none;
            margin: 1px 25px;
            font-size: 16px;
            font-weight: 300
        }

    .circle-theme .ellipse {
        background: 0;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        font-weight: 700;
        cursor: default
    }
</style>
<script>
    var imgNotFound = '/Ecommerce/images/photo-not-found.png';
    var currentTileViewDs;
    var browserBufferForScroll;
    var nextPageLoading = false;
    var lightBox;
    var itemsInCategory;
    var totalItemsInCategory;
    var totalPagesInCategory;
    var tilesToShow;
    var sortCriteria = '';
    var itemsToView = [];
    var resultsPerPageFromQuery;
    var pagingNavigation;
    const FIRST_PAGE = 1;
    var nextPage = FIRST_PAGE;
    var popup = null;
    var itemData;
    var skusForGrid = [];
    var imageOnlyTiles = [{ "text": '' }, { "text": '' }, { "text": '' }, { "text": '' }, { "text": '' }, { "text": '' }, { "text": '' }];

    (function () {

        // loads blank tiles to be replaced
        document.addEventListener('DOMContentLoaded', function () {
            if (widgetOptions.includeItemsFromAllChildCategories === false && PAGE_CAT_ITEMS.directItems === false) { return; };
            generateTiles(imageOnlyTiles, $("#empty-template"));
        });

        // // loads the filled tiles
        window.onload = function () {
            getPage(FIRST_PAGE);
        }


        $('body').scroll(function (e) { processScrollEvent(); }); // hanldle when zoomed
        $(window).scroll(function (e) { processScrollEvent(); }); // handle when 100%

        function processScrollEvent() {
            if (widgetOptions.pagingMode === 'paged' || widgetOptions.pagingMode === undefined) return;

            var tileViewInstance = $('.tile').dxTileView('instance');
            var nextPageOfItems;
            var totalHeight;
            var visibleHeight;
            var currentScroll;
            currentTileViewDs = tileViewInstance.getDataSource();

            (document.documentElement.scrollTop) ?
                currentScroll = document.documentElement.scrollTop : currentScroll = document.body.scrollTop

            totalHeight = document.body.offsetHeight;
            visibleHeight = document.documentElement.clientHeight;

            checkScrollability(currentScroll, visibleHeight, totalHeight, currentTileViewDs, tileViewInstance);
            if (ASPxClientUtils.androidPlatform) { $('#loadingMessage').show(); }
        }

        function checkScrollability(currentScroll, visibleHeight, totalHeight, currentTileViewDs, tileViewInstance) {
            if (totalItemsInCategory === undefined || totalItemsInCategory === '' || nextPageLoading) return;
            totalPagesInCategory = totalItemsInCategory.Paging.TotalPages || 0;

            var tileBottom = document.getElementById('divWrapper_ItemsTileListing').getBoundingClientRect().bottom;

            (ASPxClientUtils.iOSPlatform || ASPxClientUtils.androidPlatform) ? browserBufferForScroll = 210 : browserBufferForScroll = totalHeight - tileBottom;

            if (totalHeight <= (currentScroll + visibleHeight + browserBufferForScroll) && isNextPageInRange(nextPage, totalPagesInCategory)) {
                getNextPagePageForScroll(currentTileViewDs, tileViewInstance);
            }
        };


        function getNextPagePageForScroll(currentTileViewDs, tileViewInstance) {
            nextPageLoading = true;

            nextPage++;
            $('#loadingMessage').show();
            var gsp = GetSearchParameters(nextPage);
            MakeAJAXCall(gsp.SearchOperation, gsp, loadNextPageforScroll, { ds: currentTileViewDs, tile: tileViewInstance });
        };

        function loadNextPageforScroll(pagedData, dataObj) {
            nextPageOfItems = JSON.parse(pagedData).Data;
            nextPageOfItems.map(function (nextItem) {
                dataObj.ds.items().push(nextItem);
            });

            $('.tile').dxTileView('option', 'dataSource', dataObj.ds);

            setupLinks();

            nextPageLoading = false;
            if (ASPxClientUtils.androidPlatform) {
                return;
            }
            $('#loadingMessage').hide();


            if (widgetOptions.debugMode) {
                var paging = JSON.parse(pagedData).Paging;
                console.log(paging);
                console.table(nextPageOfItems, ['RowNumber', 'StockCode', 'Name']);
            };
            var newArr = _.difference(dataObj.ds.items(), nextPageOfItems);
            var new2 = dataObj.ds.items().filter(function (item) { return nextPageOfItems.indexOf(item) >= 0 })
        };

        function getPage(pageNumber) {
            var params = GetSearchParameters(pageNumber);
            MakeAJAXCall(params.SearchOperation, params, SetupItemsToDisplay);
        };

    })();

    // end module here, everything else to global
    function showImage(imgData, item) {
        (imgData === null || imgData === '') ?
            item.ImgSRC = imgNotFound : item.ImgSRC = imgData;
        displayTileImage(item.ImgSRC, item.Item_ID);
    };

    function GetSearchParameters(pageNumber, tilesToDisplay) {
        var hasSCID = (QueryString['SCID'] != null && QueryString['SCID'] !== undefined && !isNaN(QueryString['SCID']));
        var PARAMS = {
            SearchString: (QueryString['SearchStr'] != null) ? QueryString['SearchStr'] : '',
            SearchCategoryID: widgetOptions.overrideCategoryList || ((hasSCID)
                ? parseInt(QueryString['SCID'])
                : PAGE_CATEGORY),
            IncludeModels: (widgetOptions.includeModels != null) ?
                widgetOptions.includeModels :
                true,
            IncludeStockCodes: (widgetOptions.includeStockCodes != null) ?
                widgetOptions.includeStockCodes :
                true,
            IncludeSKUs: (widgetOptions.includeSKUs != null) ?
                widgetOptions.includeSKUs :
                false,
            IncludeItemsFromAllChildCategories: (widgetOptions.includeItemsFromAllChildCategories != null) ?
                widgetOptions.includeItemsFromAllChildCategories :
                false,
            RowsPerPage: (tilesToDisplay != null) ? tilesToDisplay : widgetOptions.pageSize || -1,
            PageNumber: pageNumber,
            Filters: '[]',
            CharacteristicPaths: '',
            SearchOperation: (widgetOptions.getPricingInResults != null) ?
                (widgetOptions.getPricingInResults) ?
                    'Inventory.GetSearchResultsFilteredWithPricingPaged' :
                    'Inventory.GetSearchResultsWithCharacteristicsFilteredPaged' :
                'Inventory.GetSearchResultsFilteredWithPricingPaged'
        };
        var filterObj = {};
        filterObj.SortBy = sortCriteria;
        filterObj.FilterBy = [];
        if (typeof (GetActiveFilters) !== 'undefined') {
            filterObj.FilterBy = GetActiveFilters();
        };
        PARAMS.Filters = JSON.stringify(filterObj);
        return PARAMS;
    };

    function SetupItemsToDisplay(itemData) {
        var url = window.location.href.slice(window.location.href.lastIndexOf('CatalogSearch.aspx'), window.location.href.lastIndexOf('?'));

        if (itemData === '') {
            itemData = '{ "Data": [],"Paging": {"CurrentPage": 1,"TotalPages": 1,"TotalResults": 0,"ResultsPerPage":' + widgetOptions.pageSize + ' }}'
        }
        var dataCheck = JSON.parse(itemData);

        if (dataCheck.Data.length === 0 && url === 'CatalogSearch.aspx') {
            setNoProductsFoundMessage();
            return;
        } else if (dataCheck.Data.length === 0) {
            setNoProductsFoundMessage();
            return;
        } else {
            totalItemsInCategory = JSON.parse(itemData);
            itemsInCategory = totalItemsInCategory.Data;
        };
        resultsPerPageFromQuery = totalItemsInCategory.Paging.ResultsPerPage;
        if (widgetOptions.showTileBorder == null) { widgetOptions.showTileBorder = true; };

        (widgetOptions.showTileBorder == null) ? widgetOptions.showTileBorder = true : null;
        (widgetOptions.showTileBorder) ? $('.dx-item.dx-tile').css('border', '1px solid #a8a8a8') : $('.dx-item.dx-tile').css('border', 'none');
        (widgetOptions.pagingMode === 'paged' || widgetOptions.pagingMode === undefined) ? setupPaging(totalItemsInCategory) : setupScrolling(itemsInCategory);

        if (widgetOptions.debugMode) {
            var paging = JSON.parse(itemData).Paging;
            var items = JSON.parse(itemData).Data;
            console.log(paging);
            console.table(items, ['RowNumber', 'StockCode', 'Name']);
        };

        if (document.querySelector('#divWrapper_ItemCharacteristicFilter') != null) {
            if (document.querySelector('#divWrapper_ItemCharacteristicFilter').offsetHeight < document.body.offsetHeight) {
                //NOTE comment code so the page and paginate on Antroid devices
                //if (ASPxClientUtils.androidPlatform) { return; };
                $('#loadingMessage').hide();
            }
        };
        setupTilesToViewDropdown(resultsPerPageFromQuery);
    };

    function setNoProductsFoundMessage() {
        var noproductsMsg = (widgetOptions.noProductsFoundText != undefined) ? widgetOptions.noProductsFoundText : 'No Products found.'
        $('#divWrapper_ItemsTileListing').css('visibility', 'hidden');
        $('#divActiveFilters_ItemCharacteristicFilter').append('<span class="not-found-message">' + noproductsMsg + '</span>');
    }

    // Tile specific functions
    function generateTiles(dataSource, itemTemplate) {
        _.templateSettings.variable = 'item';

        var tile = $(".tile").dxTileView({
            activeStateEnabled: (widgetOptions.enableHighlightOnTileClick != null) ?
                widgetOptions.enableHighlightOnTileClick :
                false,
            dataSource: dataSource,
            baseItemHeight: widgetOptions.tileHeight || 415,
            baseItemWidth: widgetOptions.tileWidth || 240,
            itemMargin: widgetOptions.tileMargin || 12,
            showScrollbar: (widgetOptions.showScroll != null) ?
                widgetOptions.showScroll :
                true,
            itemTemplate: itemTemplate,
            direction: widgetOptions.tileFlowDirection || 'vertical',
            height: widgetOptions.height || 'auto',

        }).dxTileView("instance");
        $('#divWrapper_ItemsTileListing').css('visibility', 'visible');
        return tile;
    };

    function displayTileImage(photoData, id) {
        var tileImageID = 'imgItemPhoto_ItemsTileListing_' + id;
        $('#' + tileImageID).show();
        if (photoData != '' && document.getElementById(tileImageID) !== null) {
            document.getElementById(tileImageID).setAttribute('src', photoData);
            document.getElementById(tileImageID).setAttribute('data-imgSrc', photoData);
        };
    };

    // Paging specific functions
    function displayPagedItems(itemsInCategory) {
        var tileTemplate = widgetOptions.tileTemplate || 'tile-template';
        generateTiles(itemsInCategory, $('#' + tileTemplate));

        setupLinks();
        var autoScrollToTop = (widgetOptions.autoScrollTopOnTileLoad != null) ?
            widgetOptions.autoScrollTopOnTileLoad : true;
        if (autoScrollToTop) {
            ScrollTop();
        }
    };

    function setupPaging(totalItemsInCategory) {

        pagingNavigation = $('#divPaging_ItemsTileListing').pagination({
            pages: totalItemsInCategory.Paging.TotalPages,
            cssStyle: widgetOptions.pagerCSSClass || 'light-theme',
            displayedPages: widgetOptions.pagerButtonsDisplayedBeforeEllipsis || 3,
            hrefTextPrefix: '#p-',
            prevText: widgetOptions.previousPageButtonText || 'Prev',
            nextText: widgetOptions.nextPageButtonText || 'Next',
            ellipsePageSet: (widgetOptions.enableGoToPageByEllipsis != null) ?
                widgetOptions.enableGoToPageByEllipsis : true,
            edges: widgetOptions.pagerButtonsAtEdge || 2,
            showPrevAtEdge: (widgetOptions.pagerShowPrevAtEdge != null) ?
                widgetOptions.pagerShowPrevAtEdge : true,
            showNextAtEdge: (widgetOptions.pagerShowNextAtEdge != null) ?
                widgetOptions.pagerShowNextAtEdge : true,
            showJustOne: (widgetOptions.pagerShowJustOne != null) ?
                widgetOptions.pagerShowJustOne : true,
            onPageClick: function (pageNumber) {
                var pageSizeValue = parseInt(document.querySelector("#pageSize_Wrapper > div > input[type=hidden]").value);
                var params = GetSearchParameters(pageNumber, pageSizeValue);
                MakeAJAXCall(params.SearchOperation, params, pagingclicked);
            }
        });
        displayPagedItems(itemsInCategory);
        itemsToView = [];
        return pagingNavigation;
    };

    function pagingclicked(pagedData) {
        itemsInCategory = JSON.parse(pagedData).Data;
        displayPagedItems(itemsInCategory);
    };

    function setupTilesToViewDropdown(resultPerPage) {
        var dropDownElements = 3;
        for (var i = 1; i <= dropDownElements; i++) {
            itemsToView.push(resultPerPage * i)
        };
        itemsToView.push('All');

        if (widgetOptions.showPagesizeDropdown || widgetOptions.showPagesizeDropdown === undefined) {
            if (widgetOptions.pagingMode === 'endless') { return; }
            $('#pageSizeLabel')[0].innerText = (widgetOptions.pageSizeLabel || 'Page Size');

            $("#pageSize_Wrapper").dxDropDownBox({
                value: itemsToView[0],
                dataSource: itemsToView,
                contentTemplate: function (e) {
                    var $list = $("<div>").dxList({
                        dataSource: e.component.option("dataSource"),
                        selectionMode: "single",
                        onSelectionChanged: function (arg) {
                            var searchParameters = GetSearchParameters(1, arg.addedItems[0]);
                            if (arg.addedItems[0] > totalItemsInCategory.Paging.TotalResults) {
                                $('#divPaging_ItemsTileListing').hide();
                            };

                            if (arg.addedItems[0] != 'All' && arg.addedItems[0] < totalItemsInCategory.Paging.TotalResults) {
                                widgetOptions.pagingMode = 'paged';
                                $('#divPaging_ItemsTileListing').show();
                            };

                            if (widgetOptions.pagingMode === 'endless') { return; };

                            if (searchParameters.RowsPerPage === 'All') {
                                widgetOptions.pagingMode = 'endless';
                                searchParameters = GetSearchParameters(1);
                                MakeAJAXCall(searchParameters.SearchOperation, searchParameters, displayTiles);
                                e.component.option("value", arg.addedItems[0]);
                                e.component.close();
                                $('#divPaging_ItemsTileListing').hide();
                            } else {
                                MakeAJAXCall(searchParameters.SearchOperation, searchParameters, displayTiles);
                                e.component.option("value", arg.addedItems[0]);
                                e.component.close();
                                totalItemsInCategory.Paging.ResultsPerPage = arg.addedItems[0];
                            }
                        }
                    });
                    return $list;
                }
            });
        } else {
            $('#pageSizeLabel')[0].hide();
        };
    };

    function displayTiles(viewData) {
        tilesToShow = JSON.parse(viewData).Data;
        totalItemsInCategory.Data = tilesToShow;
        totalItemsInCategory.Paging.TotalPages = Math.ceil(totalItemsInCategory.Paging.TotalResults / totalItemsInCategory.Paging.ResultsPerPage);
        setupPaging(totalItemsInCategory);
        displayPagedItems(tilesToShow);
    };

    function setupScrolling(itemsInCategory) {
        displayPagedItems(itemsInCategory);
    };

    function isNextPageInRange(currentPage, totalPagesInCategory) {
        return currentPage < totalPagesInCategory;
    };

    // + specific functions
    function popupContent_StockCode(contentElement, itemData) {
        var itemDetailLinkHTML = $('<a />').attr('class', 'ItemDetailLink').attr('href', itemData.URL).text(widgetOptions.popup_detailLinkText || 'View Item Details'); //B#14875 change path to be itemData.URL
        contentElement.append(
            $('<div />').attr('id', 'popupLightboxImage_' + itemData.Item_ID),
            $('<div />').attr('class', 'QVImage col-xs-6')
                .append(
                    $('<a />').attr('id', 'popupLightBoxLink_' + itemData.Item_ID)
                        .attr('onClick', 'generateLightBox(itemData)')
                        .append(
                            $('<img />')
                                .attr('id', 'imgItemPhoto_ItemsTileListingPopup_' + itemData.Item_ID)
                                .attr('class', 'CatalogProductQuickViewPicture img-responsive')
                        ),
                    $('<div />').attr('class', 'zoomIcon')
                        .append($('<img />').attr('class', 'dxWeb_izHint'))
                        .append('<span>Zoom</span>')
                ),
            $('<div />').attr('id', 'zoomArea_' + itemData.Item_ID),

            // meta-data
            $('<div />')
                .attr('class', 'quickviewContent col-xs-12 col-sm-6')
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewStockCode')
                        .append((widgetOptions.popup_showStockCode === true || widgetOptions.popup_showStockCode === undefined) ? itemData.StockCode : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewName')
                        .append((widgetOptions.popup_showName === true || widgetOptions.popup_showName === undefined) ? itemData.Name : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewHeadline')
                        .append((widgetOptions.popup_showHeadline === true || widgetOptions.popup_showHeadline === undefined) ? itemData.Headline : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewSubHeadline')
                        .append((widgetOptions.popup_showSubHeadline === true || widgetOptions.popup_showSubHeadline === undefined) ? itemData.SubHeadline : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewShortDescription')
                        .append((widgetOptions.popup_showShortDescription === true || widgetOptions.popup_showShortDescription === undefined) ? itemData.ShortDescription : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewLongDescription2')
                        .append((widgetOptions.popup_showLongDescription2 === true) ? itemData.LongDescription2 : '')
                )
                .append(
                    $('<div />').attr('class', 'itemDetailLinkDiv')
                        .append((widgetOptions.popup_showItemDetailLink === true || widgetOptions.popup_showItemDetailLink === undefined) &&
                            (widgetOptions.popup_detailLinkText || widgetOptions.popup_detailLinkText === undefined) ?
                            itemDetailLinkHTML :
                            '')
                ),
        )
        // pricing and add to cart
        if (itemData.CanAddToCart) {
            var priceText = (widgetOptions.popup_priceText != undefined) ? widgetOptions.popup_priceText : 'Price';
            var addToCartButtonTextVal = (widgetOptions.popup_AddToCartBtnText != undefined) ? widgetOptions.popup_AddToCartBtnText : 'Add to Cart';
            contentElement.append(
                $('<div />')
                    .attr('id', 'divWrapper_pricing_' + itemData.Item_ID)
                    .attr('class', 'quickviewContent divWrapper col-xs-12 col-sm-6')
                    .append($('<div>' + priceText + '</div>').attr('class', 'PriceRow'))
                    .append($('<div />')
                        .attr('id', 'displayPrice_' + itemData.Item_ID)
                        .attr('class', 'itemPrice')
                    )
                    .append($('<input />')
                        .attr('type', 'text')
                        .attr('id', 'stockCodeAddToCartQty_' + itemData.Item_ID)
                        .attr('class', 'QVQty')
                    )
                    .append($('<a>' + addToCartButtonTextVal + '</a>')
                        .attr('id', 'popupAddToCartButton_' + itemData.Item_ID)
                        .attr('class', 'addToCartBtn dxbButton btnCart')
                    )
            )
        }
        return contentElement;
    };

    function popupContent_Model(contentElement, itemData) {
        var itemDetailLinkHTML = $('<a />').attr('class', 'ItemDetailLink').attr('href', itemData.URL).text(widgetOptions.popup_detailLinkText || 'View Item Details');

        return contentElement.append(
            $('<div />').attr('id', 'popupLightboxImage_' + itemData.Item_ID),
            $('<div />')
                .attr('class', 'QVImage col-xs-6')
                .append(
                    $('<a />').attr('id', 'popupLightBoxLink_' + itemData.Item_ID)
                        .attr('onClick', 'generateLightBox(itemData)')
                        .append(
                            $('<img />')
                                .attr('id', 'imgItemPhoto_ItemsTileListingPopup_' + itemData.Item_ID)
                                .attr('class', 'CatalogProductQuickViewPicture img-responsive')
                        ),
                    $('<div />').attr('class', 'zoomIcon')
                        .append($('<img />').attr('class', 'dxWeb_izHint'))
                        .append('<span>Zoom</span>')
                ),

            $('<div />').attr('id', 'zoomArea_' + itemData.Item_ID),
            // meta-data
            $('<div />')
                .attr('class', 'quickviewContent col-xs-12 col-sm-6')
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewStockCode')
                        .append((widgetOptions.popup_showStockCode) ? itemData.StockCode : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewName')
                        .append((widgetOptions.popup_showName) ? itemData.Name : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewHeadline')
                        .append((widgetOptions.popup_showHeadline) ? itemData.Headline : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewSubHeadline')
                        .append((widgetOptions.popup_showSubHeadline) ? itemData.SubHeadline : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewShortDescription')
                        .append((widgetOptions.popup_showShortDescription) ? itemData.ShortDescription : '')
                )
                .append(
                    $('<div />').attr('class', 'CatalogQuickViewLongDescription2')
                        .append((widgetOptions.popup_showLongDescription2) ? itemData.LongDescription2 : '')
                )
                .append(
                    $('<a />').attr('class', 'ItemDetailLink')
                        .attr('href', itemData.URL)
                        .text(widgetOptions.popup_detailLinkText || 'View Item Details')

                ),
            $('<div />').attr('class', 'QVcheckoutLink')
                .append('<a href="/ecommerce/shoppingcart.aspx" class="checkoutLink btnCart">Check Out</a>')
                .append(
                    $('<div />').attr('class', 'itemDetailLinkDiv')
                        .append((widgetOptions.popup_showItemDetailLink === true || widgetOptions.popup_showItemDetailLink === undefined) &&
                            (widgetOptions.popup_detailLinkText || widgetOptions.popup_detailLinkText === undefined) ?
                            itemDetailLinkHTML :
                            '')
                ),

            $('<div />').attr('id', 'loadingPanelDiv')
                .append(
                    $('<div />').attr('id', 'messagePlaceHolder')
                        .append('<img src="/ecommerce/Widgets/leaf.svg" alt="loading" style="width:30px;"> Retrieving pricing...')
                ),

            $('<div />').attr('id', 'popupPricingGrid')
                .attr('style', 'height: 100;width;')
        )
    };

    function lightboxContent(contentElement, itemData) {
        return contentElement.append(
            $('<div />').attr('class', 'lightboxImage')
                .append(
                    $('<a />').attr('class', 'lightbox-close')
                        .attr('onClick', 'closeLightbox()')
                        .append('X'),
                    $('<img />').attr('id', 'lightboxImage_' + itemData.Item_ID)
                )
        )
    };

    function closeLightbox() {
        lightBox.hide();
    };

    function generateLightBox(itemData) {
        MakeAJAXCall('Inventory.GetItemPhoto', { StockCode: itemData.StockCode }, getLightboxImage, itemData);
    };

    function getLightboxImage(photoData, itemData) {
        var imgHeight;
        var lightboxImg = new Image();
        var windowWidth = $(window).width();
        var windowHeight = $(window).height();

        lightboxImg.src = photoData;

        lightBox = $('#popupLightboxImage_' + itemData.Item_ID).dxPopup({
            shading: true,
            shadingColor: 'rgba(128, 128, 128, 0.8)',
            closeOnOutsideClick: true,
            showTitle: false,
            width: 'auto',
            height: function (e) {
                if (lightboxImg.height > windowHeight) {
                    return windowHeight;
                }
                return lightboxImg.height;
            },
            maxWidth: function (e) {
                return windowWidth;
            },
            maxHeight: function (e) {
                return windowHeight;
            },
            onShowing: function (e) {
                var left = (lightboxImg.width > windowWidth) ?
                    ((lightboxImg.width - windowWidth) / 4) + 'px' :
                    ((windowWidth - lightboxImg.width) / 4) + 'px';
                $('#lightboxImage_' + itemData.Item_ID).attr('src', photoData);

                $('#lightboxImage_' + itemData.Item_ID).css({
                    'max-height': this._options.maxHeight(),
                    'height': this._options.height(),
                    'max-width': this._options.maxWidth(),
                    'width': 'auto',
                    'margin-right': 'auto',
                    'margin-left': 'auto',
                    'display': 'block'
                });

            },
            contentTemplate: function (contentElement) {
                lightboxContent(contentElement, itemData);
            }
        }).dxPopup('instance');

        lightBox.show();



    };

    function setupLinks(itemData) {
        var QVLinks = Array.prototype.slice.call(document.querySelectorAll('.QVLink'));
        var detailLinks = Array.prototype.slice.call(document.querySelectorAll('.detailLink'));
        QVLinks.map(function (qvLink) {
            qvLink.addEventListener('click', function () {
                clickHandler(event);
            });
        });
        detailLinks.map(function (detailLink) {
            detailLink.addEventListener('click', function () {
                clickHandler(event);
            });
        });
    };

    function createPopup(data) {
        itemData = JSON.parse(data);
        var isModel = false;
        if (popup) {
            $('.popup').remove();
        }
        popup = $('#divWrapper_ItemListingPopup').dxPopup({
            contentTemplate: function (contentElement) {
                if (itemData.Model_ID === -1) {
                    popupContent_Model(contentElement, itemData);
                    isModel = true;
                } else {
                    popupContent_StockCode(contentElement, itemData)
                }
            },
            showTitle: (widgetOptions.popupShowTitle != null) ?
                widgetOptions.popupShowTitle :
                true,
            showCloseButton: (widgetOptions.popupShowCloseButton != null) ?
                widgetOptions.popupShowCloseButton :
                true,
            closeOnOutsideClick: (widgetOptions.popupCloseOnOutsideClick != null) ?
                widgetOptions.popupCloseOnOutsideClick :
                true,
            width: widgetOptions.popupWidth || 700,
            height: widgetOptions.popupHeight || 500,
            minWidth: widgetOptions.popupMinWidth || null,
            minHeight: widgetOptions.popupMinHeight || null,
            maxWidth: widgetOptions.popupMaxWidth || null,
            maxHeight: widgetOptions.popupMaxHeight || null,
            dragEnabled: (widgetOptions.popupEnableDrag != null) ?
                widgetOptions.popupEnableDrag :
                true,
            resizeEnabled: (widgetOptions.popupEnableResize != null) ?
                widgetOptions.popupEnableResize :
                false,
            shading: (widgetOptions.popupModal != null) ?
                widgetOptions.popupModal :
                false,
            shadingColor: 'rgba(128, 128, 128, 0.8)',
            onShowing: function (e) {
                if (isModel) {
                    var contentToChangeStyle = e.component.content().parent();
                    var img = $('#imgItemPhoto_ItemsTileListingPopup_' + itemData.Item_ID);
                    var PARAMS = {
                        ItemID: itemData.Item_ID,
                        CharacteristicPaths: ''
                    };

                    MakeAJAXCall("Inventory.GetSKUsByItemIDWithCharacteristicsAndPricing", PARAMS, getSKUsForGrid);
                    MakeAJAXCall('Inventory.GetItemPhoto', { StockCode: itemData.StockCode }, getImgSrc, img);
                } else {

                    var img = $('#imgItemPhoto_ItemsTileListingPopup_' + itemData.Item_ID);
                    var qtyBox = $('#stockCodeAddToCartQty_' + itemData.Item_ID);
                    var PARAMS = {
                        StockCode: itemData.StockCode,
                        Quantity: 1,
                        UOM: 0
                    };
                    if (itemData.CanAddToCart) {
                        var addToCartBtn_StockCodePopup = document.getElementById('popupAddToCartButton_' + itemData.Item_ID);
                        addToCartBtn_StockCodePopup.addEventListener('click', function (e) {
                            popUpAddToCart(e, itemData, qtyBox, addToCartBtn_StockCodePopup);
                        });
                        MakeAJAXCall('Price.GetDisplayPriceByStockCode', PARAMS, showStockCodePrice, itemData);
                    };
                    MakeAJAXCall('Inventory.GetItemPhoto', { StockCode: itemData.StockCode }, getImgSrc, img);
                }
            },
            onShown: function (e, f) {
                setupImageZoom(e, itemData);
            },
            onContentReady: function (e) {
                $('#imgItemPhoto_ItemsTileListingPopup_' + itemData.Item_ID).attr('error', function () {
                    if ($(this)[0].naturalHeight === 0) { }
                });
            },
            onHiding: function (e) {
                $('body').removeClass('touchAction');
            },
            title: widgetOptions.popUpTitle || 'Quick View'
        }).dxPopup('instance');

        popup.show(itemData);
    };

    // popup internal functions
    function getImgSrc(imgData, img) {
        if (imgData === '') {
            img.attr('src', imgNotFound);
            return;
        }
        img.attr('src', imgData);
        return imgData;
    };

    function showStockCodePrice(data, itemData) {
        var priceData = JSON.parse(data);
        document.querySelector('#displayPrice_' + itemData.Item_ID).textContent = priceData.WebPrice;
    };

    function setupImageZoom(e, itemData) {
        var image = $('.QVImage > a > img');

        MakeAJAXCall('Inventory.GetItemPhoto', { StockCode: itemData.StockCode }, getZoomImage, { image, itemData })
    };

    function getZoomImage(imgData, dataObj) {
        var imgURL;
        (imgData === '' || imgData === undefined) ?
            imgURL = imgNotFound : imgURL = imgData;

        new ImageZoom(dataObj.image, {
            maxZoom: 8,
            target: $('#zoomArea_' + dataObj.itemData.Item_ID),
            imageUrl: imgURL,
            deadarea: 0.25
        });
    };

    function createPricingGrid(skusForGrid, loadPanel) {
        var pricingGrid = $('<div />').dxDataGrid({
            dataSource: skusForGrid,
            showBorders: true,
            columnAutoWidth: true,
            focusStateEnabled: false,
            hoverStateEnabled: false,
            scrolling: function (e) {
                if (ASPxClientUtils.safari) {
                    return {
                        showScrollbar: 'always'
                    }
                };

                return {
                    mode: 'standard',
                    useNative: false,
                    showScrollbar: 'always'
                };
            },
            height: function (e) {
                if (ASPxClientUtils.safari) return 'auto';
            },
            onShowing: function (e) {
                contentElement.on("dxmousewheel", onDxMouseWheel);
            },

            onContentReady: function (e) {
                $('#loadingPanelDiv').hide();
                $('body').addClass('touchAction');
            },
            columns: [{
                caption: widgetOptions.pricingGridColumn_SKUtext || 'SKU',
                cellTemplate: function (el, rowData) {
                    el.html(rowData.key.Name);
                }
            }, {
                caption: widgetOptions.pricingGridColumn_Pricetext || "Price",
                cellTemplate: function (el, rowData) {
                    el.html(rowData.data.Pricing.WebPrice)
                }
            }, {
                caption: widgetOptions.pricingGridColumn_CheckStockText || "Stock",
                cellTemplate: function (el, rowData) {
                    var itemId = rowData.data.Item_ID;
                    var checkStockLink = document.createElement('a');
                    checkStockLink.id = 'checkStockGrid_' + itemId;
                    var linkText = document.createTextNode(widgetOptions.pricingGrid_CheckStockLinkText || 'Check Stock');
                    checkStockLink.appendChild(linkText);
                    checkStockLink.addEventListener('click', function (e) {
                        GetOnHandQuantityDisplayString(itemId, checkStockLink)
                    });
                    el.append(checkStockLink);
                }
            }, {
                caption: widgetOptions.pricingGridColumn_QTYtext || 'QTY',
                cellTemplate: function (el, rowData) {
                    var itemID = rowData.data.Item_ID;
                    var textBoxDiv = document.createElement('div');
                    el.attr('id', 'gridAddToCartQty_' + itemID);
                    el.append(textBoxDiv).dxTextBox({
                        elementAttr: { id: 'gridAddToCartQty_Textinput_' + itemID }
                    })
                }
            }, {
                caption: widgetOptions.pricingGridColumn_AddToCarttext || '',
                cellTemplate: function (el, rowData) {
                    var hasPricing = Object.keys(rowData.data.Pricing).length === 0 ? false : true;

                    if (rowData.data.CanAddToCart && hasPricing) {
                        var itemID = rowData.data.Item_ID;
                        var qtyInput = $('#gridAddToCartQty_Textinput_' + itemID);

                        var divWrapper = document.createElement('div');
                        divWrapper.classList.add('divWrapper_gridAddToCartButton');

                        var addToCartLink = document.createElement('a');
                        addToCartLink.id = 'gridAddToCartButton_' + itemID;
                        addToCartLink.classList.add('gridAddToCartButton');
                        addToCartLink.text = widgetOptions.pricingGrid_addToCartBtnText || 'Add';
                        addToCartLink.addEventListener('click', function (e) {
                            var validateAddToCartOptions = {
                                options: {
                                    addToCartButtonText: addToCartLink.text,
                                    addedToCartButtonText: (widgetOptions.pricingGrid_addedToCartText) ? widgetOptions.pricingGrid_addedToCartText : 'Added'
                                },
                                button: addToCartLink.id,
                                textbox: qtyInput[0].id
                            };
                            MakeAJAXCall('Cart.AddItemToCart', {
                                Item_ID: itemID,
                                Qty: GetQty(qtyInput[0].id),
                                UOM: 'P'
                            }, ValidateAddToCart, validateAddToCartOptions)
                        });

                        divWrapper.appendChild(addToCartLink);
                        el.append(divWrapper);
                    } else {
                        return;
                    };
                }
            }],
        }).appendTo($('#popupPricingGrid'));
    };

    function getSKUsForGrid(data) {
        if (data === '') {
            $('#loadingPanelDiv').hide();
            $('.checkoutLink').hide();
            return;
        };
        skusForGrid = JSON.parse(data);
        createPricingGrid(skusForGrid);
    };

    function GetOnHandQuantityDisplayString(Item_ID, checkStockLink) {
        if (Item_ID == 0 || Item_ID == '' || Item_ID == null) { return; } // TODO go back to text box

        var Params = {
            'Item_ID': Item_ID,
            'EnableOnHandQuantityDisplay': true,
            'EnableLeadTimeMessage': false,
            'LimitedAvailableMessage': '[qty]',
            'LimitedUnavailableMessage': 'Out of Stock',
            'UnlimitedAvailableMessage': '[qty]',
            'UnlimitedUnavailableMessage': 'Out of Stock',
            'LeadTimeMessage': ''
        }

        MakeAJAXCall('GetOnHandQuantityDisplayString', Params, ShowOHQ, checkStockLink);
    };

    function ShowOHQ(Data, checkStockLink) {
        checkStockLink.innerHTML = Data;
    };

    function popUpAddToCart(e, itemData, qtyBox, addToCartBtn) {
        e.preventDefault();
        MakeAJAXCall('Cart.AddItemToCart', {
            Item_ID: itemData.Item_ID,
            Qty: GetQty(qtyBox[0].id),
            UOM: 'P'
        }, ValidateAddToCart, {
            options: {
                addToCartButtonText: (widgetOptions.popup_AddToCartBtnText) ? widgetOptions.popup_AddToCartBtnText : 'Add to Cart',
                addedToCartButtonText: (widgetOptions.popup_AddedToCartBtnText) ? widgetOptions.popup_AddedToCartBtnText : 'Added to Cart'
            },
            button: addToCartBtn.id,
            textbox: qtyBox[0].id
        })
    };

    function getPopupData(e) {
        var itemId = parseInt(e.target.dataset.itemid);
        var PARAMS = {
            ItemID: itemId
        }
        MakeAJAXCall("Inventory.GetItemByItemID", PARAMS, createPopup);
    };

    function clickHandler(e) {
        if (widgetOptions.enableItemQuickView) {
            if (e.target.classList.contains('QVLink') || e.target.classList.contains('detailLink')) {
                getPopupData(e);
            } else {
                return;
            }
        } else {
            window.location = SITE_PATHS.application + '/product/' + e.target.dataset.stockcode;
        }
    };

    function GetQty(id) {
        if (id.includes('ItemsTileListing') || id.includes('stockCodeAddToCartQty')) {
            var elem = document.getElementById(id);
        } else {
            var elem = document.querySelector('#' + id + '> div > div.dx-texteditor-input-container > input');
        }

        var qtyVal = (elem) ? elem.value : 1;
        if (isNaN(qtyVal) || qtyVal < 1) {
            qtyVal = 1;
        }
        elem.value = qtyVal;
        return qtyVal;
    };
</script>
<style>
    .itemDetailLinkDiv {
        margin: 15px 0
    }

    a.QVLink {
        display: block
    }

    img.CatalogProductTileListPicture {
        width: 100;
        height: auto
    }

    .QVLink.CatalogProductTileListPicture {
        width: auto;
        background-color: transparent;
        border-width: 0;
        max-width;
        max-height: 185px
    }

    div#pageSizeLabel {
        float: left;
        font-weight: 500;
        font-size: 18px;
        margin-bottom: 0;
        font-family: Khand,sans-serif !important;
        height: 35px;
        padding: 6px 6px 6px 0
    }

    #pageSize_Wrapper {
        height: 30px;
        float: left;
        position: relative;
        z-index: 7
    }

        #pageSize_Wrapper input.dx-texteditor-input {
            width: 40px;
            padding: 0 5px 0 5px;
            min-height: 28px
        }

    ul.thumbnails:empty {
        padding-left: 0;
        height: 0
    }

    .dx-dropdowneditor-icon:before {
        margin-left: -18px
    }

    .dx-list .dx-empty-message, .dx-list-item {
        padding: 0 8px;
        font-size: 1em
    }

    .dx-list-item {
        padding: 0 4px
    }

    .dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-focused {
        background-color: #000;
        color: #fff
    }

        .dx-list:not(.dx-list-select-decorator-enabled) .dx-list-item.dx-state-focused.dx-list-item-selected {
            background-color: #000;
            color: #fff
        }

    .dx-popup-content {
        padding: 4px;
        font-size: initial
    }

    .dx-item-content.dx-list-item-content:hover {
        font-weight: 400
    }
</style>
<script type='text/html' id='tile-template'>
    <% var path = item.URL %>
    <% var learnMoreText = widgetOptions.learnMoreLinkText || 'Detail View' %>
    <% var addToCartText = widgetOptions.addToCartButtonText || 'Add to Cart' %>
    < var qtyText = widgetOptions.qtyLabelText || 'Qty>
    <% var stockCodeLabel = widgetOptions.stockCodeLabel || 'Model Number' %>
    <div class="item-name CatalogTileListItemName">
        <%= item.Name %>
    </div>
    <div class="item-headline CatalogTileListItemHeadline">
        <%= item.Headline %>
    </div>
    <div class="item-stockcode itemTileStock">
        <%= stockCodeLabel %> :
        <%= item.StockCode %>
    </div>
    <% if (widgetOptions.enableItemQuickView) { %>
    <div class="item-image viewPopup" id="itemImage_div_<%= item.Item_ID %>">
        <input type=image onClick="event.preventDefault();"
               class="QVLink CatalogProductTileListPicture "
               data-itemData="itemData<%= item.Item_ID %>"
               data-itemID="<%= item.Item_ID %>"
               data-StockCode="<%= item.StockCode %>"
               id="imgItemPhoto_ItemsTileListing_<%= item.Item_ID %>"
               src="<%= item.Photo1 %>" />
    </div>

    <div class="viewPopup" id="detailLink_ItemsTileListing_<%= item.Item_ID %>">
        <a href="javascript:void(0)"
           class="detailLink"
           data-itemData="itemData<%= item.Item_ID %>"
           data-itemID="<%= item.Item_ID %>"
           data-StockCode="<%= item.StockCode %>">
            <%= learnMoreText %>
        </a>
    </div>
    <% } else {%>
    <div class="item-image" id="itemImage_div_<%= item.Item_ID %>">
        <a href="<%= path %>">
            <img id="imgItemPhoto_ItemsTileListing_<%= item.Item_ID %>"
                 width=" 60"
                 height="60"
                 src="<%= item.Photo1 %>"
                 class="CatalogProductTileListPicture ">
        </a>
    </div>

    <div id="detailLink_ItemsTileListing_<%= item.Item_ID %>" class="detailLink">
        <a href="<%= path %>">
            <%= learnMoreText %>
        </a>
    </div>
    <% } %>
    <div id="pricingDiv_ItemsTileListing_<%= item.Item_ID %>" class="dxtilePricing">
        <div class="PriceRow" id="defaultPriceDiv_ItemsTileListing_<%= item.Item_ID %>">
            <label><= (item.Pricing && item.Pricing.ShowDefaultPrice) ? item.Pricing.DefaultPriceLabelText ></label>
            <div class="DefaultPrice itemPrice">
                <= (item.Pricing && item.Pricing.ShowDefaultPrice) ? item.Pricing.DefaultPrice >
            </div>
        </div>
        <div class="PriceRow" id="customerPriceDiv_ItemsTileListing_<%= item.Item_ID %>">
            <label><= (item.Pricing && item.Pricing.ShowCustomerPrice) ? item.Pricing.CustomerPriceLabelText ></label>
            <div class="CustomerPrice itemPrice">
                <= (item.Pricing && item.Pricing.ShowCustomerPrice) ? item.Pricing.CustomerPrice >
            </div>
        </div>
        <div class="PriceRow" id="discountPriceDiv_ItemsTileListing_<%= item.Item_ID %>">
            <label><= (item.Pricing && item.Pricing.ShowDiscountPrice) ? item.Pricing.DiscountPriceLabelText ></label>
            <div class="DiscountPrice itemPrice">
                <= (item.Pricing && item.Pricing.ShowDiscountPrice) ? item.Pricing.DiscountPrice >
            </div>
        </div>
        <div class="PriceRow" id="webPriceDiv_ItemsTileListing_<%= item.Item_ID %>">
            <label><= (item.Pricing && item.Pricing.ShowWebPrice) ? item.Pricing.WebPriceLabelText ></label>
            <div class="WebPrice itemPrice">
                <= (item.Pricing && item.Pricing.ShowWebPrice) ? item.Pricing.WebPrice >
            </div>
        </div>
        <div id="addToCartDiv_ItemsTileListing_<%=item.Item_ID %>" class="addToCartRow">
            <div class="addToCartQtyDiv">
                <label for="addToCartQtyinput_ItemsTileListing_<%= item.Item_ID %>"><%= qtyText %></label>
                <input type="text" id="addToCartQtyinput_ItemsTileListing_<%= item.Item_ID %>">
            </div>
            <div class="addToCartDiv">
                <button class="addToCartBtn dxbButton btnCart" id="addToCartBtn_ItemsTileListing_<%= item.Item_ID%>"><%= addToCartText %></button>
            </div>
        </div>
    </div>
    < $(function(){(item.CanAddToCart == false)? document.getElementById('addToCartDiv_ItemsTileListing_' + item.Item_ID).innerHTML = '' >
    < $(function () {
    $('#addToCartBtn_ItemsTileListing_' + item.Item_ID).click(function (e) {
    e.preventDefault();
    MakeAJAXCall('Cart.AddItemToCart', {
    Item_ID: item.Item_ID,
    Qty: GetQty('addToCartQtyinput_ItemsTileListing_' + item.Item_ID),
    UOM: 'P'
    }, ValidateAddToCart, {options: widgetOptions, button:'addToCartBtn_ItemsTileListing_' + item.Item_ID, textbox>
</script>
<script type='text/html' id='empty-template'>
    <div class="item-image">
        <img style="margin: 0px auto;height: 200px;max-width:90% !important; opacity: 0.7;" src="/Ecommerce/images/pre-load-tile.gif" class="CatalogProductTileListPicture pre-load">
    </div>
</script>
<div id='divActiveFilters_ItemCharacteristicFilter'></div>
<div id='divWrapper_ItemsTileListing' class='col-xs-12'>
    <div class='sizeselector'>
        <div id='pageSizeLabel'></div>
        <div id='pageSize_Wrapper'></div>
    </div>
    <div class='pagingDiv' id='divPaging_ItemsTileListing'></div>
    <div class='tile'></div>
    <div id='loadingMessage' style='display:none'>
        <img src='/ecommerce/Widgets/leaf.svg' alt='loading' style='width:30px'> Loading more items...
    </div>
    <div id='loadingPanel'></div>
    <div id='divWrapper_ItemListingPopup'></div>
</div>
<style>
    .simple-pagination {
        margin: 0 auto;
        text-align: center;
        position: relative;
        display: inline-flex;
        width: 70
    }

        .simple-pagination ul {
            list-style: none;
            padding: 0;
            margin: 0 auto;
            position: relative
        }

    img.CatalogProductTileListPicture.pre-load {
        margin: 0 auto;
        height: auto;
        max-width: none !important;
        opacity: .7;
        max-height: none;
        top: -15px
    }

    div#divWrapper_ItemsTileListing {
        top: -10px;
        padding-right: 0
    }

    div#pageSizeLabel:empty, div#pageSize_Wrapper:empty {
        height: 0;
        padding: 0
    }

    div#divActiveFilters_ItemCharacteristicFilter {
        height: 45px
    }

        div#divActiveFilters_ItemCharacteristicFilter:empty {
            height: 0
        }

    .dx-scrollview-content.dx-tileview-wrapper {
        min-height: 600px;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: flex-start;
        align-content: flex-start;
        align-items: stretch;
        height: auto !important
    }

    .dx-item-content .item-image {
        width: auto;
        height: 200px
    }

    .dx-tile-content {
        padding: 10px 20px 20px
    }

    .dx-item.dx-tile {
        text-align: center;
        /*        height: auto;
        display: inline-block;*/
        vertical-align: top;
        box-shadow: 0 2px 6px rgba(69,73,91,.078);
        -webkit-box-shadow: 0 2px 6px rgba(69,73,91,.078);
        -moz-box-shadow: 0 2px 6px rgba(69,73,91,.078);
        display: flex;
        position: relative;
        flex-direction: column;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-content: center;
        align-items: flex-start;
        margin;
        left: auto !important;
        top: auto !important;
        height: auto !important;
    }

    .dxtilePricing {
        text-align: left;
        width: 100
    }

        .dxtilePricing .CustomerPrice label, .dxtilePricing .DefaultPrice label, .dxtilePricing .DiscountPrice label, .dxtilePricing .WebDiscountedPrice label, .dxtilePricing .WebPrice label {
            width: 130px
        }

    .itemPrice {
        float: right;
        font-weight: 600
    }

    .PriceRow .itemPrice:empty, .PriceRow label:empty {
        display: none
    }

    .dxtilePricing .addToCartQtyDiv input {
        width: 40px !important
    }

    .addToCartQtyDiv {
        width;
        float: left;
        margin-top: 10px
    }

    .addToCartDiv {
        float: right
    }

    /*   .dx-item.dx-tile {
        width: 95 !important
    }

    @media only screen and (min-width:576px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:768px) {
        .dx-item.dx-tile {
            width: 95 !important
        }
    }

    @media only screen and (min-width:898px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:992px) {
        .dx-item.dx-tile {
            width: 48 !important
        }
    }

    @media only screen and (min-width:1100px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:1200px) {
        .dx-item.dx-tile {
            width: 31 !important
        }
    }

    @media only screen and (min-width:1300px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:1400px) {
        .dx-item.dx-tile {
            width: 23 !important
        }
    }

    @media only screen and (min-width:1500px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:1600px) {
        .dx-item.dx-tile {
            width: 23 !important
        }
    }

    @media only screen and (min-width:1700px) {
        .dx-item.dx-tile {
            width !important
        }
    }

    @media only screen and (min-width:1800px) {
        .dx-item.dx-tile {
            width: 23 !important
        }
    }*/

    @media (min-width:368px) {
        .simple-pagination {
            width;
            margin: 10px 0;
            text-align: center;
            position: relative;
            display: block;
            top: 10px
        }
    }

    @media(min-width:768px) {
        .simple-pagination {
            margin: 0 auto;
            text-align: center;
            position: relative;
            display: inline-flex;
            top: 5px
        }
    }
}
</style>
<link href='/Ecommerce/Widgets/listingWidget.css' rel='stylesheet'>
<link href='/Ecommerce/site/Widgets/listingWidget.css' rel='stylesheet'>
See Also

Items

Management Console

Reference