CyberStore Documentation
DocumentViewer_Popup Widget

A common document viewer widget. Introduced in v2.21.

 Remarks

The DocumentViewer_Popup widget is used in conjunction with the various account history widgets and is designed to display an individual document (i.e. sales order) in a pop up which can be easily read and printed by the logged in shopper.

The following types of documents can be displayd by the widget:

When a document is being viewed, clicking the Print button will open a new tab and bring up the browser's print dialog preview where the shopper can elect a printer or PDF output option.

Customizing Document Formatting and Content

Each document type displayed by the DocumentViewer_Popup will utilize a generic styling and automatically include the uploaded company logo in the header. Documents can be formatted to meet specific requirements by creating custom versions of the source XSLT style sheet files for your site.

The default XSLT files can be found in your installation's /Ecommerce/xslt folder. Specific files include:

 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.

 

 Widget Conventions
 Example

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

<Control src="LoadWidgetControl.ascx" 
    FileLocation="DocumentViewer_Popup.html" 
    RequireLogin="true" 
/>
 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.

<div id="popupContainerView"></div>

<style>
    .logoWrapper {
        border-bottom: 1px solid #888;
        margin-bottom: 20px;
    }

    .Invoice-box,
    .Return-box,
    .Order-box,
    .Dispatch-box {
        max-width: 80;
        margin: auto;
        padding: 30px;
        border: 1px solid #eee;
        box-shadow: 0 0 10px rgba(0, 0, 0, .15);
        font-size: 16px;
        line-height: 24px;
        font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
        color: #555;
    }

    /*    .Dispatch-box td.orderdisplayField:empty,
        td.orderdisplayField:empty {
        display: none;
    }*/
    td.orderdisplayTitle.dispatchNotePopupLink,
    .orderdisplayTitle {
        font-weight: 700;
        padding: 5px 0 30px;
        width;
    }

    .orderDisplayTable,
    .orderdisplayTable {
        margin: 0 auto;
        width: 100;
    }

    .orderdisplaydetailLabel {
        background: #ddd;
        padding: 5px;
    }

    td.orderdisplaydetailField {
        padding: 5px 10px;
        text-align: left;
    }

    .orderDisplayLabel,
    .orderdisplayLabel {
        width !important;
        font-weight: 700;
        text-align: right;
        padding: 5px;
    }

    .orderDisplaySubTable .evenRow td {
        background: #f7f7f6;
    }

    td.orderDisplayField,
    td.orderdisplayField {
        /*    width: 25 !important;*/
        padding: 5px;
    }

    .orderDisplaySubTable {
        margin-top: 25px;
        width;
    }

    table.DispatchNotesTable {
        margin: 20px auto;
        width: 99;
    }

    .DispatchNotesTable tbody tr th,
    .orderDisplaySubTable td.orderDisplayDetailLabel {
        background: #ddd;
        padding: 5px;
    }

    .DispatchNotesTable tbody tr td {
        padding: 5px;
    }

    td.orderDisplayDetailField {
        padding: 5px;
    }

    /*  FROM BILLING WIDGET  */


    .divTable {
        display: table;
        width;
    }

    .divTableRow.headerRow,
    .divTableRow.itemDetails {
        display: flex;
        /*table-row*/
        justify-content: space-between;
    }

    .divTableRow.headerRow,
    .divTableRow.headerRow {
        background-color: #ddd !important;
        color: #000;
    }

    .divTableHeading {
        background-color: #EEE;
        display: table-header-group;
    }

    .divTableCell.logo {
        background-image: url(/ecommerce/site/themes/images/logo.png);
        background-repeat: no-repeat;
        width: 250px;
        height: 100px;
        background-size: 100;
        margin: 0 0px;
        min-height: 10px;
        max-height: 180px;
    }

    .divTableRow.invoiceDetails {
        width;
        float: left;
    }

    .divTableRow.customerDetails {
        width: 35;
        float: right;
    }

    .divTableRow.invoiceTotals {
        width;
    }

    .divTableRow.itemDetails {
        margin-bottom: 10px;
    }

    .divTableCell {
        display: table-cell;
        padding: 5px 10px;
    }

    .divTableHead {
        display: table-cell;
        font-weight: bold;
        font-weight: bold;
    }

    .divTableRight {
        text-align: right;
    }

    .divTableBody {
        display: table-row-group;
    }

    .pseudocell {
        display: inline-block;
        width: 100px;
        text-align: left;
    }

    .divTableCell.StockCode,
    .divTableCell.divTableHead.divTableItem {
        min-width: 15;
    }

    .divTableCell.StockDes,
    .divTableCell.divTableHead.divTableDesc {
        min-width;
    }

    .divTableCell.Qty,
    .divTableCell.divTableHead.divTableQTY {
        min-width: 10;
        text-align: center;
    }

    .divTableCell.Price,
    .divTableCell.divTableHead.divTableEA {
        min-width;
        text-align: right;
    }

    .divTableCell.Gross,
    .divTableCell.divTableHead.divTablePrice {
        min-width: 20;
        text-align: right;
    }

    .divTableCell.orderTotal {
        font-weight: 700;
        margin: 10px 0 -5px;
        width;
    }

    .orderdisplayTable table {
        border: 0px solid #999;
    }
</style>


<script type="text/javascript">
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Base Widget:  DocumentViewer_Popup.html
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Custom Widget Filename:
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' (c) 2021 by Dovetail Internet Technologies, LLC
    // '              www.dovetailinternet.com
    // '              info@dovetailinternet.com
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' All rights reserved. Not to be used without permission.
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Development Date: Sept 2021
    // ' Revision: 1.0
    // ' Modified: 10/06/2021
    // ' Revision: 2.0
    // ' Modified: 04/14/2022 - PR Document links added
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    // ' Purpose: Display Orders, Invoices and Returns in a popup window
    // ' that provides print functionality.
    // ' Built to display and print any document type added to the
    // ' documentDisplayList object.
    // '
    // '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    function showDocumentViewerPopUp(docType, docInfoReference) {

        var documentDisplayList =
            [{ DocumentType: 'Order', ServiceCall: 'Order.GetOrderDetailView', ParamName: 'OrderNumber', ServiceParam: {} },
            { DocumentType: 'Invoice', ServiceCall: 'Billing.GetInvoiceDetailView', ParamName: 'InvoiceNumber', ServiceParam: {} },
            { DocumentType: 'Return', ServiceCall: 'Return.GetReturnDetailView', ParamName: 'RMANumber', ServiceParam: {} },
            { DocumentType: 'Dispatch', ServiceCall: 'Fulfillment.GetDispatchNoteDetailView', ParamName: 'DispatchNoteNumber', ServiceParam: {} }
            ];

        // get the ServiceCall
        documentDisplayList.forEach(function (item, index) {
            if (documentDisplayList[index].DocumentType == docType) {
                documentDisplayList[index].ServiceParam[documentDisplayList[index].ParamName] = docInfoReference;
                MakeAJAXCall(documentDisplayList[index].ServiceCall, documentDisplayList[index].ServiceParam,
                    function (DATA) {
                        if (DATA != null) {
                            var data = JSON.parse(DATA);
                            if (data.Result.Success) {
                                buildPopup(data.Html, docType, docInfoReference);
                            }
                        }
                    }
                );
            }
        })
    }

    /**=======+++++++++++++++++++++++++++++++++++++++++++++++++++=======================================
     **              removeSpecialCharsForPopupId()
     *?  Returns the docInfoReference that has had the special chars replaced with '_'. Needed for use as div id?
     *@param docRef string
     *@return string
     *=====================================++++++++++++++++++++++++++++++++++++++++++++++++++++========**/
    function removeSpecialCharsForPopupId(docRef) {
        return docRef.replace(/[^a-zA-Z0-9_-]/g, '_');
    }

    function buildPopup(returnedHtml, docType, docInfoReference) {

        var docId = docType + removeSpecialCharsForPopupId(docInfoReference);
        var docClass = docType + '-box';
        // need to set the destination for each popup
        var dynamicPopupContainer = $('#popupContainerView')
            .append($('<div />').attr('id', docId));
        var dynmicPopup = $('#' + docId).dxPopup({
            visible: true,
            showTitle: true,
            showCloseButton: true,
            closeOnOutsideClick: true,
            elementAttr: {
                class: "order"
            },
            resizeEnabled: true,
            contentTemplate: function (contentElement) {
                contentElement.append(
                    $('<div />').attr('id', 'scrollbarContainer')
                        .append($('<div />').attr('id', docId + '_scroll').attr('class', docClass)
                            .append(returnedHtml)
                        ).dxScrollView({
                            direction: 'both',
                            scrollByThumb: true,
                            scrollByContent: true,
                            showScrollbar: 'always',
                            useNative: true
                        })
                )
            },
            onShowing: function () {
                PretifyNumbers();
                buildDrillDownPopUplinks();
            },
            toolbarItems: [{
                location: "before"
            }, {
                widget: "dxButton",
                location: "after",
                options: {
                    text: "Print",
                    onClick: function () {
                        var divToPrint = document.getElementById(docId + '_scroll');
                        var newWin = null;
                        newWin = window.open('', '_blank');
                        if (newWin == null) {
                            var alertResult = DevExpress.ui.dialog.alert('You must enable popup in this browser to use the print function', 'Message');
                            alertResult.done(function () {
                                // nothing to do here
                            });
                        }
                        if (newWin != null) {
                            setTimeout(function () {
                                newWin.document.open();
                                setTimeout(function () {
                                    newWin.document.write('<html><head><link href="/Ecommerce/site/themes/css/printInvoice.css" rel="stylesheet" /></head><body onload="window.print()">' + divToPrint.innerHTML + '</body></html>');
                                    setTimeout(function () {
                                        newWin.document.close();
                                        setTimeout(function () {
                                            newWin.close();
                                        }, 200);
                                    }, 200);
                                }, 200);
                            }, 200);
                        }
                    }
                }
            }]
        }).dxPopup('instance');

        var popInst = $('#' + docId).dxPopup("instance");
        popInst.option('title', docType + ' ' + docInfoReference);
        if (docType == 'Dispatch') {
            popInst.option('title', `${docType} Note ${docInfoReference}`);
        }
    }

    function buildDrillDownPopUplinks() {
        //NOTE handle the  different types of docs that can be passed --> add function by class added in Customer_XX_Display.xslt files.
        // MakeAJAXCall("Billing.GetCustomerInvoices", {}, console.log) --> .invoicePopupLink
        //Return.GetReturnDetailView --> .rmaPopupLink
        //Order.GetOrderDetailView --> .orderPopupLink
        //Fulfilment.GetDispatchNoteDetailView --> .DispatchNotePopupLink

        $('.invoicePopupLink').each(function () {
            var iRefNumber = $(this).text();
            var iLookUpType = "Invoice";
            $(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + iLookUpType + '\',\'' + iRefNumber + '\')">' + iRefNumber + '</a>');
        })

        $('.rmaPopupLink').each(function () {
            var rRefNumber = $(this).text();
            var rLookUpType = "Return";
            $(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + rLookUpType + '\',\'' + rRefNumber + '\')">' + rRefNumber + '</a>');
        })

        $('.orderPopupLink').each(function () {
            var oRefNumber = $(this).text();
            var oLookUpType = "Order";
            $(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + oLookUpType + '\',\'' + oRefNumber + '\')">' + oRefNumber + '</a>');
        })

        $('.dispatchPopupLink').each(function () {
            var dRefNumber = $(this).text();
            var dRookUpType = "Dispatch";
            $(this).html('<a href="#" onclick="showDocumentViewerPopUp(\'' + dRookUpType + '\',\'' + dRefNumber + '\')">' + dRefNumber + '</a>');
        })
    }


</script>