CyberStore Ecommerce 2023 Documentation
Account_CreateCustomer Widget

A B2B account registration widget. Introduced in v2023.1. 

 Remarks

The Account_CreateCustomer widget can be used to capture a new front end visitor's information, create a login account and a new on-file Customer account that is then created in SYSPRO based on the default settings of a template customer.

When the visitor completes the form, a new Customer will be created in SYSPRO based on the defaults of the "Template Customer" as configured in the Website tab of the Site Configuration screen in Site Manager. When customer numbers are numeric in format, the next available number will be used. If Customer Numbers are setup as alphanumeric, then the phone number entered during registration will be used with masking applied based on the setup in the SYSPRO Configuration screen.

 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 options exist to allow for the configuration and setup of the reCAPTCHA check.

The reCaptchaSiteKey option is used to supply the public portion of the API integration for Google reCAPTCHA.

The theme for the non-human check can be set using reCaptchaTheme with values of either 'light' (default) or 'dark'.
       

Additionally a page can be set as the page to load after the completion of the registration. the option is redirectPage: with a default value of  'CustomerMyAccount.aspx'.  

 Example

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

<Control src="LoadWidgetControl.ascx" FileLocation="Account_CreateCustomer.html" RequireLogin="false" 
    Options="
        reCaptchaSiteKey: '6Lf4q0wUAAXXXXXXXXXXXnRFjs4wnQFRNwFu7',
        reCaptchaTheme: 'light'
        redirectPage: CustomerMyAccount.aspx" 
/>
 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.

<!-- <link href="/ECommerce/site/Widgets/login.css" rel="stylesheet"> -->
<style>
    h2.panel-title {
        font-size: 30px;
    }

    .regCheckbox label.dx-field-item-label.dx-field-item-label-location-left {
        width: 100;
        padding-top: 0;
    }

    .regCheckbox .dx-field-item-content.dx-field-item-content-location-right {
        width;
        float: left;
    }

    .dx-field-value.col-xs-12.login {
        width: 100 !important;
    }

    div#Registration {
        float: left;
    }

    .dx-popup-wrapper > .dx-overlay-content {
        width;
        min-width: 240px;
    }

    /* .dx-popup-title {
        background: #333;
        color: #fff;
    }

    .dx-dialog-message p {
        color: #ed1c24;
    } */

    .panel-default {
        display: none;
    }
</style>

<script type="text/javascript">
    var verifyCallback = function (response) {
        //alert(response);
        var response = grecaptcha.getResponse();
        if (response.length == 0) {
            //reCaptcha not verified
            return response.length;
        } else {
            //reCaptch verified
            return response;
        }
    };


    var widgetId1;
    var onloadCallback = function () {
        // Renders the HTML element with id 'reCaptcha' as a reCAPTCHA widget.
        // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
        widgetId1 = grecaptcha.render('reCaptcha', {
            // 'sitekey': widgetOptions.reCaptchaSiteKey || '',
            'sitekey': '6Lf4q0wUAAAAAKkBdm9dWHc1nRFjs4wnQFRNwFu7',
            'theme': widgetOptions.reCaptchaTheme || 'light'
        });
    };

</script>


<div>
    <section class="row login">
        <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
            <div class="panel panel-default">
                <div class="panel-heading" role="tab" id="headingOne">

                    <h2 class="panel-title">
                        Create an Account
                    </h2>
                    <p>If you do not have an existing login account, please register below.</p>
                </div>
                <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
                    <div class="panel-body">
                        <div class="col-xs-12">
                            <div class="inputRow col-xs-12">
                                <div id="RegistrationDetails"></div>
                                <div class="dx-field-value col-xs-12 login">
                                    <!-- reCaptcha form -->
                                    <form action="javascript:alert(grecaptcha.getResponse(widgetId1));">
                                        <div id="reCaptcha"></div>
                                    </form>
                                    <div class="loadPanel"></div>
                                    <div id="Registration" class="primary-btn-theme loginBtn"></div>
                                </div>
                                <div id="popup"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</div>


<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer>
</script>


<script type="text/javascript">

    states = [
        'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL',
        'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME',
        'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH',
        'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI',
        'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY'
    ];

    function setWidgetOptionDefaults(widgetOptions = {}) {
        widgetOptions.redirectPage = widgetOptions.redirectPage ?? 'CustomerMyAccount.aspx';
        widgetOptions.reCaptchaTheme = widgetOptions.reCaptchaTheme ?? 'dark'

    }

    // Registration DETAIL SCRIPTS
    $(function () {
        setWidgetOptionDefaults(widgetOptions);

        MakeAJAXCall("Visitor.GetAccountProfile", {},
            function (DATA) {
                if (ValidAJAXResponse(DATA)) {
                    accountInfo = JSON.parse(DATA);
                    if (accountInfo.Data.OnFile == false && jQuery.isEmptyObject(accountInfo.Data
                        .BillingAddress) && jQuery.isEmptyObject(accountInfo.Data.ShippingAddress)) {
                        $(".panel-default").show();
                    }
                }
            });



        var RegistrationForm = $("#RegistrationDetails").dxForm({
            validationGroup: "newAccountData",
            items: [{
                itemType: "group",
                cssClass: "inputRow",
                colCount: 2,
                colCountByScreen: {
                    md: 2,
                    sm: 1
                },
                screenByWidth: function (width) {
                    return width < 720 ? "sm" : "md";
                },
                items: [{
                    dataField: "firstName",
                    editorType: "dxTextBox",
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "First name is required"
                    }],
                },
                {
                    dataField: "lastName",
                    editorType: "dxTextBox",
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Last name field is required"
                    }],
                },
                {
                    dataField: "password",
                    editorType: "dxTextBox",
                    label: {
                        location: "top"
                    },
                    editorOptions: {
                        mode: "password"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Password is required"
                    }, {
                        type: "stringLength",
                        min: 6,
                        message: "Field must be 6 and 20 characters long."
                    }],
                },
                {
                    dataField: "confirmPassword",
                    editorType: "dxTextBox",
                    editorOptions: {
                        mode: "password"
                    },
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Please confirm your password."
                    }, {
                        type: "compare",
                        message: "'Password' and 'Confirm Password' do not match",
                        comparisonTarget: function () {
                            return RegistrationForm.option("formData")
                                .password
                        }
                    }
                        , {
                        type: "stringLength",
                        min: 6,
                        message: "Field must be 6 and 20 characters long."
                    }
                    ],
                },
                {
                    dataField: "companyName",
                    editorType: "dxTextBox",
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Company name is required"
                    }],
                },
                {
                    dataField: "billingAddress1",
                    editorType: "dxTextBox",
                    editorOptions: {
                        //inputAttr:{ 'style':  'text-transform: uppercase'},
                    },
                    label: {
                        location: "top",
                        text: 'Billing Address'
                    },
                    validationRules: [{
                        type: "required",
                        message: "Street address is is required"
                    }],
                }, {
                    dataField: "billingAddress2",
                    editorOptions: {
                    },
                    editorType: "dxTextBox",
                    label: {
                        location: "top",
                        text: 'Billing Address 2'
                    }
                },
                {
                    dataField: "billingCity",
                    editorType: "dxTextBox",
                    editorOptions: {
                    },
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "City field is required"
                    }],
                },
                {
                    dataField: "billingState",
                    editorType: "dxSelectBox",
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "State field is required"
                    }],
                    editorOptions: {
                        placeholder: "State",
                        items: states,
                    },
                },
                {
                    dataField: "billingZipCode",
                    editorType: "dxTextBox",
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Zip code field is required"
                    }, {
                        type: "numeric",
                        message: "This field accepts numbers only"
                    }],
                },
                {
                    dataField: "telephone",
                    editorType: "dxTextBox",
                    editorOptions: {
                        mask: "(###) ###-####",
                        maskRules: {
                            "#": /[01-9]/
                        },
                        maskInvalidMessage: "The phone field must have 10 digits.",
                        useMaskedValue: true
                    },

                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Telephone number is required"
                    },
                    {
                        type: "stringLength",
                        min: 10,
                        message: "Field must be 10 digits"
                    }
                    ],
                },
                {
                    dataField: "email",
                    editorType: "dxTextBox",
                    editorOptions: {
                        onEnterKey: function (e) {
                            // blur the password box so the value is captured
                            e.component.blur();
                            // click the Registration button automatically when ENTER is pressed in the field
                            $('#Registration').trigger('click');
                        }
                    },
                    label: {
                        location: "top"
                    },
                    validationRules: [{
                        type: "required",
                        message: "Email address is required"
                    },
                    {
                        type: "email",
                        message: "Email is invalid"
                    }
                    ],
                },
                ]
            },]
        }).dxForm("instance");


        //Create account
        var ValidationMsg;
        var registrationBtn = $("#Registration").dxButton({
            text: "Continue",
            elementAttr: {
                class: 'DT-Button'
            },
            validationGroup: "newAccountData",
            onClick: function (e) {
                var alertResult;
                ValidationMsg = '';
                var result = e.validationGroup.validate();
                if (result) {
                    if (result.isValid) {
                        // validate the re-capthca
                        MakeAJAXCall("Utility.ValidateRecaptcha", { ValidationResponse: verifyCallback() }, function (DATA) {
                            if (ValidAJAXResponse(DATA))
                                var d = JSON.parse(DATA);
                            if (d.Result.Success) {
                                if (d.Data.ValidationPassed) {
                                    // if recaptcha good
                                    AccountLoadPanel.show();
                                    MakeAJAXCall("Visitor.CreateOnFileAccount", {
                                        Email: RegistrationForm.getEditor("email").option("value"),
                                        Password: RegistrationForm.getEditor("confirmPassword").option("value"),
                                        FirstName: RegistrationForm.getEditor("firstName").option("value").toUpperCase(),
                                        LastName: fixQuote(RegistrationForm.getEditor("lastName").option("value")).toUpperCase(),
                                        CompanyName: fixQuote(RegistrationForm.getEditor("companyName").option("value")).toUpperCase(),
                                        Telephone: RegistrationForm.getEditor("telephone").option("value"),
                                        TelephoneExtension: "",
                                        AlternateTelephone: "",
                                        AlternateTelephoneExtension: "",
                                        Fax: "",
                                        BillingAddress1: fixQuote(RegistrationForm.getEditor("billingAddress1").option("value")).toUpperCase(),
                                        BillingAddress2: fixQuote(RegistrationForm.getEditor("billingAddress2").option("value")).toUpperCase(),
                                        BillingAddress3: "",
                                        BillingCity: RegistrationForm.getEditor("billingCity").option("value").toUpperCase(),
                                        BillingState: RegistrationForm.getEditor("billingState").option("value"),
                                        BillingZipCode: RegistrationForm.getEditor("billingZipCode").option("value"),
                                        BillingCountry: "US",
                                        ShippingAddress1: fixQuote(RegistrationForm.getEditor("billingAddress1").option("value")).toUpperCase(),
                                        ShippingAddress2: fixQuote(RegistrationForm.getEditor("billingAddress2").option("value")).toUpperCase(),
                                        ShippingAddress3: "",
                                        ShippingCity: RegistrationForm.getEditor("billingCity").option("value").toUpperCase(),
                                        ShippingState: RegistrationForm.getEditor("billingState").option("value"),
                                        ShippingZipCode: RegistrationForm.getEditor("billingZipCode").option("value"),
                                        ShippingCountry: "US"
                                    }, confirmNewAccount)
                                }
                                else {
                                    alertResult = DevExpress.ui.dialog.alert('You must complete the reCAPTCHA validation before completing registration.',
                                        'Missing Information');
                                }
                            }
                        })
                    } else { // form input is not valid
                        $.each(result.brokenRules, function () {
                            ValidationMsg += '<p>' + this.message + '</p>';
                        });
                        alertResult = DevExpress.ui.dialog.alert(ValidationMsg,
                            'Missing Information');
                    }
                }
            }
        }).dxButton("instance");


        function fixQuote(str) {
            if (str.length > 0) {
                return str.replace("'", "\\\'");
            } else {
                return "";
            }
        }

        function confirmNewAccount(DATA) {
            AccountLoadPanel.hide();
            var msg = '';
            if (ValidAJAXResponse(DATA)) {
                var data = JSON.parse(DATA);
                if (data.Result.Success) {
                    document.location = SITE_PATHS.application + '/' + widgetOptions.redirectPage;
                } else if (!data.Result.Success) {
                    msg = data.Result.Message;
                    var alertResult = DevExpress.ui.dialog.alert(data.Result.Message, 'Important Information');
                }
            }
        }

        var AccountLoadPanel = $(".loadPanel").dxLoadPanel({
            shadingColor: "rgba(237, 28, 36, 0.70)",
            position: {
                of: "#Registration"
            },
            visible: false,
            message: "Processing ...",
            showIndicator: true,
            showPane: true,
            shading: true,
            closeOnOutsideClick: false,
        }).dxLoadPanel("instance");

    });
</script>