Magento 2 Onepage Checkout – How to Add Checkbox

checkoutmagento-2.1magento2onepage-checkout

I am trying to add an instore shipping checkbox above the Shipping Address information in checkout. I am not the most adept Magento2 developer, that's for sure. I have been stuck on this for over a week.

I have followed the instructions here: http://devdocs.magento.com/guides/v2.0/howdoi/checkout/checkout_form.html to no avail.

I have a script that rebuilds the entire site from scratch every time so I know caching is not the problem. I have created a very basic module and have verified it is loaded and active as well. Included are the files I have added to attempt to add a checkbox, maybe it will be a clue as to where I've gone wrong. The checkbox simply doesn't show up. Is it possible this is because I'm using Onepage checkout? Is there another way of doing this? Any hints on debugging this?

app/code/Premiergroup/InStoreShipping/view/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceBlock name="checkout.root">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="checkout" xsi:type="array">
                        <item name="children" xsi:type="array">
                            <item name="steps" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="shipping-step" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <item name="shippingAddress" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="before-form" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <!-- Start container -->
                                                            <item name="instore-shipping-form-container" xsi:type="array">
                                                                <item name="component" xsi:type="string">/Premiergroup/InStoreShipping/js/view/custom-checkout-form</item>
                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                <item name="config" xsi:type="array">
                                                                    <item name="template" xsi:type="string">Premiergroup/InStoreShipping/custom-checkout-form</item>
                                                                </item>
                                                                <item name="children" xsi:type="array">
                                                                    <item name="custom-checkout-form-fieldset" xsi:type="array">
                                                                        <!-- uiComponent is used as a wrapper for form fields (its template will render all children as a list) -->
                                                                        <item name="component" xsi:type="string">uiComponent</item>
                                                                        <!-- the following display area is used in template (see below) -->
                                                                        <item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
                                                                        <item name="children" xsi:type="array">
                                                                            <item name="checkbox_field" xsi:type="array">
                                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
                                                                                <item name="config" xsi:type="array">
                                                                                    <!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
                                                                                    <item name="customScope" xsi:type="string">customCheckoutForm</item>
                                                                                    <item name="template" xsi:type="string">ui/form/field</item>
                                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
                                                                                </item>
                                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                                <item name="dataScope" xsi:type="string">customCheckoutForm.checkbox_field</item>
                                                                                <item name="label" xsi:type="string">I want in-store shipping and pickup</item>
                                                                                <item name="sortOrder" xsi:type="string">1</item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                                <!-- End container -->
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</body>
</page>

app/code/Premiergroup/InStoreShipping/view/frontend/web/js/view/

/*global define*/
define([
'Magento_Ui/js/form/form'
], function(Component) {
'use strict';
return Component.extend({
    initialize: function () {
        this._super();
        // component initialization logic
        return this;
    },

    /**
     * Form submit handler
     *
     * This method can have any name.
     */
    onSubmit: function() {
        // trigger form validation
        this.source.set('params.invalid', false);
        this.source.trigger('instoreForm.data.validate');

        // verify that form data is valid
        if (!this.source.get('params.invalid')) {
            // data is retrieved from data provider by value of the customScope property
            var formData = this.source.get('instoreForm');
            // do something with form data
            console.dir(formData);
        }
    }
});
});

app/code/Premiergroup/InStoreShipping/view/frontend/templates/instore.phtml

<div>
<form id="instore-shipping-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
    <fieldset class="fieldset">
        <legend data-bind="i18n: 'Instore Shipping'"></legend>
        <!-- ko foreach: getRegion('instore-shipping-form-fields') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </fieldset>
</form>
</div>

Best Answer

The reason it's not showing up is that you have some errors in your path declarations and also because UI components use knockout html templates, not the .phtml kind which are used for blocks.

corrected component path in layout:

<item name="component" xsi:type="string">Premiergroup_InStoreShipping/js/view/custom-checkout-form</item>

Note underscore between vendor and module name.

Your template should be this: {module_dir}/view/frontend/web/template/custom-checkout-form.html

You declare it in the layout like:

<item name="template" xsi:type="string">Premiergroup_InStoreShipping/custom-checkout-form</item>