Storefront
Live-Demo öffnen unter /documentation/examples/run/store.
Einleitung
Ein Shop ist der kürzeste Weg zu zeigen, dass DotApp ein Full Stack ist. PHP besitzt Katalog und Warenkorb. CSS legt das Raster. dotapp.js sucht, fügt Zeilen hinzu und sendet die Kasse ohne Reload. Produkt-IDs sind verschlüsselt. Sitzungszustand lebt in DSM::use('Examples'), niemals in $_SESSION.
- Eigene JS-Bibliothek — Toasts beim Hinzufügen
- Sichere Formulare — das Kassen-
fo-rm - AJAX-Listen — dasselbe Overlay +
parseReply - NOVA-Shop — Pro-Beispiel: vollständiger E-Shop, Katalog-Cache, Checkout, Bestell-Desk
Markup und CSS
Die Seite ist ein vollständiges HTML-Dokument in store.view.php. Raster und Warenkorb sind eigene Views, damit AJAX sie ersetzen kann. Gemeinsames Aussehen: /assets/modules/Examples/css/examples.css (.ex-products, .ex-product, .ex-cart-panel, .ex-toast-stack).
<div id="storeWrap" class="ex-store"
data-catalog="{{ var: $catalogUrl }}"
data-add="{{ var: $addUrl }}"
data-remove="{{ var: $removeUrl }}">
<div id="gridInner">{{ var: $gridHtml }}</div>
<aside id="cartPanel">
<div id="cartInner">{{ var: $cartHtml }}</div>
<fo-rm method="POST" id="checkoutForm" action="{{ var: $checkoutAction }}">
{{ formName(checkout) }}
<button type="submit" id="checkoutBtn" class="ex-btn">Place demo order</button>
</fo-rm>
</aside>
</div>
Katalog, Warenkorb, DSM
Verschlüsselte SKU auf jeder Karte und Warenkorbzeile:
$enc = Crypto::encrypt($item['sku'], 'Examples.product.id');
$sku = Crypto::decrypt((string) ($data['id'] ?? ''), 'Examples.product.id');
if ($sku === false) {
return DotApp::DotApp()->ajaxReply(['status' => 0, 'message' => 'Invalid product.'], 200);
}
Warenkorb in DSM:
$cart = DSM::use('Examples')->get('cart');
if (!is_array($cart)) {
$cart = [];
}
DSM::use('Examples')->set('cart', $cart);
Die Suche läuft über einen kleinen In-Memory-Katalog (sechs Artikel). Trotzdem gilt die Listenregel: Entprellen, ab drei Zeichen, Overlay, Patch von #gridInner. Die Kasse ist ein echtes fo-rm auf derselben URL wie die Seite.
Suche, Hinzufügen, Kasse
$dotapp().live("click", ".js-store-add", function (btn) {
var id = btn.getAttribute("data-item");
$dotapp().load(addUrl, "POST", { id: id }, function (raw) {
var reply = $dotapp().parseReply(raw);
if (reply && reply.html) $dotapp("#cartInner").html(reply.html);
if (reply && reply.message) $dotapp().exNotify({ title: "Cart", text: reply.message });
});
});
$dotapp().live() ruft den Handler als (element, event) auf. Das erste Argument ist der treffende Knoten, nicht das Browser-Event — lesen Sie data-item von diesem Button. Entfernen bestätigt ein Modal. Die Kasse nutzt $dotapp().form("#checkoutForm") mit Block-Guard und Loadern. Nach Erfolg wird das Warenkorb-HTML ersetzt und die Felder geleert — kein location.reload().
Seitenskript: /app/modules/Examples/assets/js/store.js. Widgets: ex-ui.js.
Live-Demo
/documentation/examples/run/store — suchen Sie „mug“, legen Sie Artikel in den Warenkorb, schließen Sie ab. Der Warenkorb überlebt einen Reload, weil er in DSM liegt.