return function () {
    $self = url('/@object/@action/' . urlencode('htmx/inline_edit'));
    $key = 'docs_demo_htmx_rows';
    // The rows live in the visitor's session (five sample products), never in a table
    if ( ! isset($_SESSION[$key]) || ! is_array($_SESSION[$key]) || (isset($_POST['reset']) && _class('csrf_guard')->check())) {
        $_SESSION[$key] = [];
        foreach (array_slice(_class('sample_products', YF_PATH . '.dev/samples/classes/')->load(), 0, 5, true) as $id => $row) {
            $_SESSION[$key][(int) $id] = ['name' => $row['name'], 'price' => $row['price']];
        }
    }
    $rows = &$_SESSION[$key];
    $id = (int) ($_GET['row'] ?? 0);
    $error = '';

    $show_row = function ($id, $row) use ($self) {
        return '<tr id="row-' . $id . '"><td>' . $id . '</td><td>' . _prepare_html($row['name'], 0) . '</td><td>' . _prepare_html($row['price'], 0) . '</td>'
            . '<td><button type="button" class="btn btn-default btn-outline-secondary btn-sm" hx-get="' . $self . '?row=' . $id . '&edit=1">Edit</button></td></tr>';
    };
    $edit_row = function ($id, $row, $error = '') use ($self) {
        return '<tr id="row-' . $id . '" class="docs-demo-editing"><td>' . $id . '</td>'
            . '<td><input name="name" class="form-control input-sm form-control-sm" maxlength="60" value="' . _prepare_html($row['name'], 0) . '">'
            . ($error !== '' ? '<div class="text-danger small">' . _prepare_html($error, 0) . '</div>' : '') . '</td>'
            . '<td><input name="price" class="form-control input-sm form-control-sm" inputmode="decimal" value="' . _prepare_html($row['price'], 0) . '"></td>'
            . '<td class="text-nowrap"><button type="button" class="btn btn-primary btn-sm" hx-post="' . $self . '?row=' . $id . '" hx-include="closest tr">Save</button> '
            . '<button type="button" class="btn btn-default btn-outline-secondary btn-sm" hx-get="' . $self . '?row=' . $id . '">Cancel</button></td></tr>';
    };

    $htmx = _class('htmx');
    // One URL, two answers (fragment or page): keep caches from mixing them up
    header('Vary: HX-Request, HX-History-Restore-Request');
    if ($htmx->_wants_fragment() && isset($rows[$id])) {
        if (is_post()) {
            // the session token comes in the X-CSRF-Token header (hx-headers on the table)
            if ( ! _class('csrf_guard')->check()) {
                $error = 'The CSRF token is missing or wrong: reload the page.';
            } else {
                $name = trim(preg_replace('~\s+~u', ' ', (is_string($_POST['name'] ?? null) ? $_POST['name'] : '')));
                $price = str_replace(',', '.', trim((is_string($_POST['price'] ?? null) ? $_POST['price'] : '')));
                if ($name === '' || mb_strlen($name) > 60) {
                    $error = 'Name: 1 to 60 characters.';
                } elseif ( ! preg_match('~^\d{1,4}(\.\d{1,2})?$~', $price)) {
                    $error = 'Price: a number from 0 to 9999.99.';
                } else {
                    $rows[$id] = ['name' => $name, 'price' => number_format((float) $price, 2, '.', '')];
                    return $htmx->_result($show_row($id, $rows[$id]));
                }
            }
            $posted = ['name' => (is_string($_POST['name'] ?? null) ? $_POST['name'] : ''), 'price' => (is_string($_POST['price'] ?? null) ? $_POST['price'] : '')];
            return $htmx->_result($edit_row($id, $posted, $error));
        }
        return $htmx->_result(isset($_GET['edit']) ? $edit_row($id, $rows[$id]) : $show_row($id, $rows[$id]));
    }

    asset('htmx');
    $intro = '<p class="docs-demo-intro">Inline editing with htmx: <b>Edit</b> swaps the row for a form row (<code>hx-get</code>),
        <b>Save</b> posts it (<code>hx-post</code> with <code>hx-include="closest tr"</code>) and gets the updated row back, or the form row
        with an error. The values are validated on the server and kept in your session only. The POST carries the session CSRF token in
        the <code>X-CSRF-Token</code> header (<code>hx-headers</code>), checked with <code>_class(\'csrf_guard\')->check()</code>.
        Classes: <code>yf_htmx</code>, <code>yf_csrf_guard</code>.</p>';
    $body = '';
    foreach ($rows as $row_id => $row) {
        $body .= $show_row($row_id, $row);
    }
    $headers = htmlspecialchars(json_encode(['X-CSRF-Token' => _class('csrf_guard')->session_token()]), ENT_QUOTES);
    return $intro
        . '<table class="table table-bordered table-condensed table-sm docs-demo-inline" hx-target="closest tr" hx-swap="outerHTML" hx-headers="' . $headers . '">'
        . '<thead><tr><th>Id</th><th>Name</th><th>Price</th><th></th></tr></thead><tbody>' . $body . '</tbody></table>'
        . '<form method="post" action="' . $self . '"><input type="hidden" name="reset" value="1">'
        . '<input type="hidden" name="_token" value="' . _class('csrf_guard')->session_token() . '">'
        . '<button type="submit" class="btn btn-default btn-outline-secondary btn-sm">Reset the rows</button></form>';
};

Inline editing with htmx: Edit swaps the row for a form row (hx-get), Save posts it (hx-post with hx-include="closest tr") and gets the updated row back, or the form row with an error. The values are validated on the server and kept in your session only. The POST carries the session CSRF token in the X-CSRF-Token header (hx-headers), checked with _class('csrf_guard')->check(). Classes: yf_htmx, yf_csrf_guard.

IdNamePrice
10051Archives T-shirt, black37.00
10052Archives T-shirt, navy37.00
10053Archives T-shirt, purple37.00
10056Attacker T-shirt, white37.00
10058Blamo T-shirt, black37.00