Magento – Create dynamic form in checkout step magento2

checkoutformsmagento-2.1magento2

Hi i have crated a custom checkout step in magento 2 , now I need to create dynamic from which will analyse cart items and output some form elements to my form. How can I implement that ?

view/fronted/layout/checkout_index_index.xml

<item name="steps" xsi:type="array">
    <item name="children" xsi:type="array">
        <item name="my-new-step" xsi:type="array">
            <item name="component" xsi:type="string">Amsi_UserManagement/js/view/select-student</item>
            <item name="sortOrder" xsi:type="string">2</item>
            <item name="children" xsi:type="array">
            </item>
        </item>
    </item>
</item>

view/frontend/web/js/view/select-student.js

define(
    [
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Checkout/js/model/quote',
        'jquery'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator,
        quote,
        $
    ) {
        'use strict';

        function checkVisible() {
            if(quote.isVirtual() && !stepNavigator.stepCodes.length)
                return ko.observable(true);
            else
                return ko.observable(false);
        }

        return Component.extend({
            defaults: {
                template: 'Amsi_UserManagement/checkout/select-student'
            },

            isVisible: checkVisible(),

            initialize: function () {
                this._super();
                stepNavigator.registerStep(
                    'select_student',
                    'select_student',
                    'Select Student',
                    this.isVisible,

                    _.bind(this.navigate, this),
                    15
                );

                return this;
            },

            navigate: function () {
            },
            navigateToNextStep: function (form) {
                stepNavigator.next();
            }
        });
    }
);

My current template is static I need to make it dynamic and also need to validate the fields by clicking the next button in my template

view/frontend/web/template/checkout/select-student.html

<li id="select_student" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: 'Select Student'" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">

            <div class="fieldset"
                 data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
                 <div class="field field-email required">
                    <label class="label" for="save-email"><span data-bind="i18n: 'Email Address'"></span></label>
                    <div class="control">
                        <input type="email"
                               class="input-text"
                               id="save-email"
                               name="email"
                               data-validate="{required:true}" />
                    </div>
                </div>

            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

I have researched about it and I got an idea to use layout processor, how can i implement that, any idea ?

Best Answer

If any one looking for the answer, this is how I implemented it.

Changed view/fronted/layout/checkout_index_index.xml to

<item name="select-student" xsi:type="array">
    <item name="component" xsi:type="string">Amsi_UserManagement/js/view/select-student</item>
    <item name="provider" xsi:type="string">checkoutProvider</item>
    <item name="config" xsi:type="array">
        <item name="template" xsi:type="string">Amsi_UserManagement/checkout/select-student</item>
    </item>
    <item name="children" xsi:type="array">
        <item name="select-student-form-fieldset" xsi:type="array">
            <item name="component" xsi:type="string">uiComponent</item>
            <item name="displayArea" xsi:type="string">select-student-form-fields</item>
            <item name="children" xsi:type="array">
            </item>
        </item>
    </item>
</item>

view/frontend/web/template/checkout/select-student.html

<li id="select_student" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: 'Select Student'" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
        <form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
            <fieldset class="fieldset">
                <legend data-bind="i18n: 'Custom Checkout Form'"></legend>
                <!-- ko foreach: getRegion('select-student-form-fields') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!--/ko-->
            </fieldset>
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" data-bind="click: onSubmit" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

Created new newPlugin/Model/Checkout/LayoutProcessor.php

<?php
namespace Amsi\UserManagement\Plugin\Model\Checkout;

class LayoutProcessor
{  

    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array  $jsLayout
    ) {

        $jsLayout['components']['checkout']['children']['steps']['children']['select-student']['children'] ['select-student-form-fieldset']
        ['children']['text-field'] = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'selectStudentCheckoutForm',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
            ],
            'provider' => 'checkoutProvider',
            'dataScope' => 'selectStudentCheckoutForm.text_field',
            'label' => 'Text Field',
            'sortOrder' => 1,
            'validation' => [
                'required-entry' => true,
            ],
        ];

        return $jsLayout;
    }
}

Crated new etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="pl_student_layout_pl" type="Amsi\UserManagement\Plugin\Model\Checkout\LayoutProcessor" sortOrder="100"/>
    </type>
</config>