# 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 `LokiCheckout_AccountType` module.

```xml
<?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="Loki_FieldComponents::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
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components: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.

```html
<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.

```html
<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
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
    <component
            name="loki-checkout.shipping.address.account_type"
            repository="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.

<pre class="mermaid">
sequenceDiagram
Browser->>Magento: POST request with component value
Magento-->>Browser: POST response with HTML output
</pre>
