Prejsť na obsah

Príklad formulárov

Otvoriť živú ukážku na adrese /documentation/examples/run/forms.

Tento príklad ukazuje pomenované formuláre vykresľované na serveri vo DotApp PHP Framework. Živá stránka je čisté HTML, odosiela dáta na tú istú URL a nenačítava dotapp.js.

Úvod

Tri formuláre môžu zdieľať jeden POST endpoint, ak každý obsahuje token {{ formName(Name) }}. Kontrolér volá $request->form(['POST'], 'Name', $ok, $err) pre každý očakávaný názov formulára a vráti vykreslenú stránku pre formulár, ktorý sa zhoduje.

Ak ste v DotApp noví, najprv si preštudujte základy modulov a routovania:

Vytvorenie modulu Examples

Modul Examples vytvorte pomocou DotApper CLI:

php dotapper.php --create-module=Examples

Živý modul sa aktivuje iba pre URL spúšťača príkladov. V súbore /app/modules/Examples/module.init.php ponechajte rozsah trás explicitný:

public function initializeRoutes()
{
    return ['/documentation/examples/run', '/documentation/examples/run/*'];
}

Vytvorenie kontroléra Forms

Pre modul Examples vytvorte kontrolér s názvom Forms:

php dotapper.php --module=Examples --create-controller=Forms

Kontroléry v DotApp 2.0 vystavujú verejné statické akčné metódy a odkazujú sa reťazcami modulového kontroléra, napríklad 'Examples:Forms@index!'.

Konfigurácia trás

Definujte pár trás pre URL s lomkou aj bez lomky. Živý modul používa malého pomocníka, aby GET a POST ostali konzistentné:

public function initialize($dotApp)
{
    Config::module('Examples', 'prefix') ?? Config::module('Examples', 'prefix', '/documentation/examples/run');
    $p = rtrim((string) Config::module('Examples', 'prefix'), '/');

    $pair = function (string $path): array {
        $path = rtrim($path, '/');
        return [$path, $path . '/'];
    };

    Router::get($pair($p . '/forms'), 'Examples:Forms@index!', Router::STATIC_ROUTE);
    Router::post($pair($p . '/forms'), 'Examples:Forms@submit!', Router::STATIC_ROUTE);
}

Akcia GET vykreslí stránku formulára. Akcia POST overí názov odoslaného formulára a vráti novú HTML odpoveď.

Vytvorenie view

Živá ukážka používa samostatný view v /app/modules/Examples/views/forms.view.php. Súbor je kompletný HTML dokument.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>{{ var: $title }} - DotApp PHP Framework 2.0</title>
  <link rel="stylesheet" href="/assets/modules/Examples/css/examples.css" />
</head>
<body class="ex-body">
  <main class="ex-main">
    <h1>Named forms</h1>
    <p>Three forms post to the same URL. This demo does not use dotapp.js.</p>

    {{ if $formNumber }}
      <div class="ex-status">Using form {{ var: $formNumber }}, you submitted the text: {{ var: $formText }}</div>
    {{ /if }}

    <form method="POST">
      <input type="text" name="textfrom1" placeholder="Enter text to display" />
      {{ formName(Form1) }}
      <button type="submit">{{ var: $btnName }}</button>
    </form>

    <form method="POST">
      <input type="text" name="textfromanother" placeholder="Enter text to display" />
      {{ formName(Form2) }}
      <button type="submit">{{ var: $btnName }}</button>
    </form>

    <form method="POST">
      <input type="text" name="textfromanother" placeholder="Enter text to display" />
      {{ formName(Form3) }}
      <button type="submit">{{ var: $btnName }}</button>
    </form>
  </main>
</body>
</html>

Značky {{ formName(Form1) }}, {{ formName(Form2) }} a {{ formName(Form3) }} musia byť vo vnútri príslušných značiek <form>.

Spracovanie formulárov

Živý kontrolér vracia HTML reťazec. Každé volanie $request->form() obsahuje callback úspechu aj callback chyby, aby kontroly nezhodujúcich sa formulárov mohli bezpečne pokračovať.

use Dotsystems\App\Parts\Logger;
use Dotsystems\App\Parts\Renderer;
use Dotsystems\App\Parts\Response;

class Forms extends \Dotsystems\App\Parts\Controller
{
    public static function index($request)
    {
        return self::formPage('', 0);
    }

    public static function submit($request)
    {
        $attempts = [
            1 => ['Form1', 'textfrom1'],
            2 => ['Form2', 'textfromanother'],
            3 => ['Form3', 'textfromanother'],
        ];

        foreach ($attempts as $num => $spec) {
            $html = $request->form(['POST'], $spec[0], function ($request) use ($num, $spec) {
                $text = (string) ($request->data()[$spec[1]] ?? '');
                return self::formPage($text, $num);
            }, function () {
                return null;
            });

            if (is_string($html) && $html !== '') {
                return $html;
            }
        }

        return self::formPage('', 0);
    }

    private static function formPage(string $text, int $formNumber)
    {
        return self::view('forms', [
            'title' => 'Named forms demo',
            'docsUrl' => '/documentation/examples/forms',
            'btnName' => 'Send',
            'formNumber' => $formNumber,
            'formText' => htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'),
        ]);
    }

    private static function view(string $name, array $vars)
    {
        $r = Renderer::new()->module('Examples')->setView($name, 'clean');
        foreach ($vars as $key => $value) {
            $r->setViewVar($key, $value);
        }

        $html = $r->renderView();
        if ($html === '') {
            Logger::use()->error('Examples view empty', ['view' => $name]);
            return new Response(500, 'Template error');
        }

        return $html;
    }
}

Renderer::new()->module('Examples')->setView('forms', 'clean') vyberie samostatný view pred priradením premenných pomocou setViewVar().

Teória vykresľovania

DotApp vie vykresliť celý view priamo, alebo view, ktorý obsahuje {{ content }} a layout. Táto živá ukážka používa priamy prístup so samostatným view, pretože demo stránka je samostatná.

$r = Renderer::new()->module('Examples')->setView('forms', 'clean');
$r->setViewVar('btnName', 'Send');
$html = $r->renderView();

Vykresľovanie cez layout sa hodí, keď je užitočný zdieľaný obal. Tento návod používa samostatnú stránku forms.view.php.

Živá ukážka

Vyskúšajte živú ukážku na adrese /documentation/examples/run/forms. Odosiela tri pomenované formuláre na jeden endpoint a z kontroléra vracia vykreslenú stránku.