Crafter.CppDOM/examples/SPAExample
2025-11-14 18:40:13 +01:00
..
main.cpp lifecycle update 2025-11-14 18:40:13 +01:00
project.json SPA 2025-11-12 20:45:35 +01:00
README.md SPA readme 2025-11-12 20:46:38 +01:00
run.sh SPA 2025-11-12 20:45:35 +01:00

SPAExample

This example demonstrates how to create a Single Page Application (SPA) using Crafter.CppDOM with dynamic content updating and browser history management.

Features

  • Shows how to implement SPA navigation without page reloads
  • Demonstrates usage of PushState and PopState events
  • Illustrates dynamic content updating based on navigation
  • Shows how to handle browser back/forward buttons
  • Uses modern web techniques for seamless navigation

Usage

import Crafter.CppDOM;
import std;
using namespace Crafter;
using namespace Crafter::CppDOMBindings;

HtmlElementView* body = new HtmlElementView("body", R"(
<nav>
    <h2 style="margin-bottom: 20px; padding: 10px; background-color: #f0f0f0;">SPA Navigation Demo</h2>
    <a id="home" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">Home</a>
    <a id="about" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">About</a>
    <a id="contact" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">Contact</a>
</nav>
<div id="content" style="min-height: 200px; padding: 15px; border: 1px solid #ccc;"></div>
)");
HtmlElementView* home = new HtmlElementView("home");
HtmlElementView* about = new HtmlElementView("about");
HtmlElementView* contact = new HtmlElementView("contact");
HtmlElementView* content = new HtmlElementView("content");

void UpdateContent(const std::string_view page) {
    if (page == "home") {
        content->SetInnerHTML("<h3>Home Page</h3><p>Welcome to the Home page of our Single Page Application!</p><p>This demo shows how to use the new history.pushState and popstate event handling features.</p>");
    } else if (page == "about") {
        content->SetInnerHTML("<h3>About Page</h3><p>This is the About page.</p><p>Notice how the URL changes without reloading the page.</p>");
    } else if (page == "contact") {
        content->SetInnerHTML("<h3>Contact Page</h3><p>This is the Contact page.</p><p>You can navigate back and forth using the browser's back/forward buttons.</p>");
    }
}

int main() {
    body->SetStyle("font-family: Arial, sans-serif; margin: 0; padding: 20px;");
    
    // Add click handlers for navigation
    home->AddClickListener([](Crafter::MouseEvent e) {
        PushState("{\"page\": \"home\"}", "Home", "/");
        UpdateContent("home");
    });
    
    about->AddClickListener([](Crafter::MouseEvent e) {
        PushState("{\"page\": \"about\"}", "About", "/about");
        UpdateContent("about");
    });
    
    contact->AddClickListener([](Crafter::MouseEvent e) {
        PushState("{\"page\": \"contact\"}", "Contact", "/contact");
        UpdateContent("contact");
    });
    
    // Add popstate listener to handle browser back/forward buttons
    auto popStateId = AddPopStateListener([]() {
        std::string path = GetPathNameString();
        if (path == "/") {
            UpdateContent("home");
        } else if (path == "/about") {
            UpdateContent("about");
        } else if (path == "/contact") {
            UpdateContent("contact");
        } else {
            UpdateContent("home");
        }
    });
    
    // Initialize with home page
    UpdateContent("home");
    
    return 0;
}

Building and Running

crafter-build build executable
run.sh

Then navigate to http://localhost:8080/ in your browser.

If caddy is not installed, you can use your favorite static file server instead.