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.
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
.
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()"/>
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.
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.
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