Autosaving fields

Every single field that is added as a Loki Component to the checkout automatically saves its value, once changed, towards the Magento application. On this page, it is described how this process works.

Fields as Loki Components

Every field in the Loki Checkout is defined through a single block instance (defined via the XML layout <block> statement). Often, the PHTML template is a generic form/field.phtml template. For instance, the following XML layout is used by the Yireo_LokiCheckoutAccountType module.

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <body>
        <referenceBlock name="loki-checkout.shipping.address.form">
            <block name="loki-checkout.shipping.address.account_type"
                   template="Yireo_LokiFieldComponents::form/field.phtml" before="-">
                ...
            </block>
        </referenceBlock>
    </body>
</page>

Additionally, the field is defined as a Loki Component (via an entry in the etc/loki_components.xml file). This transforms the HTML root element of this block, adding an Alpine attribute x-data to refer to a specific Alpine data. In the browser, this Alpine data becomes an Alpine component.

<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
    <component name="loki-checkout.shipping.address.account_type"...>...
</component>
        </components>

Every Magento block always has a unique name. This block name is identical to the component name. It is also used to uniquely identify the Alpine component (where the name is converted from kebab-case or snake-case into camel-case): LokiCheckoutShippingAddressAccountType.

Two way binding via Alpine.js

Within the same HTML, each HTML field (<input>, <textarea>, <select>) is accompanied with various Alpine bindings: Frequently, the value of that input is connected to an internal Alpine component property value. If this Alpine property changes from within the JavaScript space, the value of the field changes. And vice versa, when the value of the field is changed by the user, the Alpine property changes as well.

<input x-model="value"/>

Additionally, whenever this value changes, a common method post() is executed, which posts the value via AJAX back to the server. Often, another method submit() is used instead, which is actually a wrapper for post() plus validation and filtering.

<input x-model="value" @change="submit()"/>

The post() method is defined in the LokiComponentType object, while the submit() method is defined in the LokiFieldComponentType object. Not every LokiComponent includes validation and filtering.

Once the value passes validation, the post() method makes an AJAX call back to the server via a generic LokiComponents controller.

Storing values on the server

Once the AJAX POST request is received, the component name is derived from the payload. Based on this, a component repository class is instantiated. For instance, for the component loki-checkout.shipping.address.account_type, the etc/loki_components.xml defines a repository class:

<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
    <component
            name="loki-checkout.shipping.address.account_type"
            repository="Yireo\LokiCheckoutAccountType\Component\Checkout\Address\AccountType\AccountTypeRepository">
    </component>
</components>

Next, the repository object its saveValue() method is called to save the posted value. This is where the component repository is able to store the value in the quote, the session or elsewhere.

Updating client side HTML

In the same AJAX request, after the repository saves the value, a listing of blocks is rendered. Each block is derived from a target list. These targets can originate from the etc/loki_components.xml definition, they could be defined through the XML layout or they could originate from elsewhere.

Once the HTML output of these targets is rendered, the AJAX call is completed and an HTML response is sent back to the client. The browser then updates all of the HTML elements on the page accordingly.

sequenceDiagram
Browser->>Magento: POST request with component value
Magento-->>Browser: POST response with HTML output
Last modified: April 30, 2025