Multiple Forms on one page, problem with validation

Hi Kirby Community. I’m having a very similar problem with the plugin uniform like this one: Uniform: Multiple Forms on one page

Except that one form is in a snippet (footer). I have followed all the steps as for the other problem and I can also submit both forms. My problem is when one form is submitted, the other shows a validation error and vice versa.

The code looks like this:
registration.php (with own controller)

<?php if ($registration_form->success()): ?>
...html...
<?php elseif ($registration_form->error()): ?>
  <?php snippet("uniform/errors", ["form" => $registration_form,]); ?>
<?php endif; ?>

footer.php (snippet without controller)

<?php if ($form->success()): ?>
  ...html...
<?php elseif ($form->error()): ?>
  <?php snippet("uniform/errors", ["form" => $form]); ?>
<?php endif; ?>

Does anyone have any tips for me on what I could do?

We would need the complete code to see where it’s going wrong…

of course.

snippets/footer.php

<?php

require "....../autoload.php";

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

use Uniform\Form;

$form = new Form(
  [
    "email_address" => [
      "rules" => ["required", "email"],
      "message" => "Bitte geben Sie eine korrekte E-Mail Adresse an",
    ],
  ],
  "newsletter-form"
);

if ($kirby->request()->is("POST")) {
  $form->MjSubscribeAction([
    "private" => $_ENV["MJ_PRIVATE"],
    "public" => $_ENV["MJ_PUBLIC"],
    "email_address" => get("email_address"),
  ]);
}
?>

<div class="col-lg-5 newsletter">
            <h4 class="text-thin">Newsletter</h4>
            <p>Bleiben Sie auf dem laufenden mit unserem halbjährlichen E-Mail Newsletter </p>
            <form action="<?= $page->url() ?>/" id="newsletter-form" class="newsletter-form" method="POST">
              <div class="form-group">
                <input type="email" name="email_address" placeholder="Ihre E-Mail Adresse" class="form-control">
                <?php echo csrf_field(); ?>
                <?php echo honeypot_field(); ?>
                <button type="submit">Anmelden</button>
              </div>
            </form>
            <?php if ($form->success()): ?>
              <div class="alert alert-success mt-3" role="alert">
                Vielen Dank. Wir haben Ihre E-Mail Adresse für den Newsletter eingetragen.
              </div>
            <?php elseif ($form->error()): ?>
              <div class="alert alert-warning mt-3" role="alert">
                <?php snippet("uniform/errors", ["form" => $form]); ?>
              </div>
            <?php endif; ?>

controllers/registration.php

<?php

use Uniform\Form;

return function ($kirby) {
  if ($kirby->user()) {
    go("/portal/uebersicht");
  }

  $registration_form = new Form(
    [
      "fullname" => [
        "rules" => ["required"],
        "message" => "Bitte geben Sie Ihren Vor- und Nachnamen ein.",
      ],
      "regemail" => [
        "rules" => ["required", "email"],
        "message" =>
          "Bitte geben Sie eine gültige E-Mail Adresse an. Die E-Mail muss im nächsten Schritt bestätigt werden.",
      ],
    ],
    "registration-form"
  );

  if ($kirby->request()->is("POST")) {
    $registration_form->emailAction([
      "to" => get("regemail"),
      "from" => "xyz@example.com",
      "subject" => "xyz",
    ]);
  }

  return compact("registration_form");
};

templates/registration.php

<form id="registration_form" method="post" action="<?php echo $page->url(); ?>" class="custom-form form">
                <div class="controls">
                  <div class="row">
                    <div class="col-sm-6">
                      <div class="form-group">
                        <label for="fullname" class="form-label">Ihren Vor- und Nachnamen *</label>
                        <input type="text" name="fullname" id="fullname" placeholder="Vor- und Nachnamen" required="required" value="<?php echo $registration_form->old(
                          "fullname"
                        ); ?>" class="form-control">
                      </div>
                    </div>
                    <div class="col-sm-6">
                      <div class="form-group">
                        <label for="regemail" class="form-label">Ihre E-Mail Adresse *</label>
                        <input type="email" name="regemail" id="regemail" placeholder="E-Mail Adresse" required="required" class="form-control">
                      </div>
                    </div>
                  </div>
                  <?php echo csrf_field(); ?>
                  <?php echo honeypot_field(); ?>
                  <button type="submit" class="btn btn-primary">Registrieren</button>
                </div>
              </form>
              <?php print_r($registration_form); ?>
              <?php if ($registration_form->success()): ?>
            </div>
            <div class="col-md-5">
              <h3>Registration erfolgreich</h3>
              <p class="text-small">Bitte bestätigen Sie Ihre E-Mail Adresse. Das E-Mail kann im SPAM-Ordner gelandet sein.</p>
            </div>
              <?php elseif ($registration_form->error()): ?>
              <div class="alert alert-warning mt-3" role="alert">
                <?php snippet("uniform/errors", [
                  "form" => $registration_form,
                ]); ?>
              </div>
            </div>
              <?php endif; ?>
...
<?php snippet("footer"); ?>

I think the problem is that you only check if a post request was received but not from which form. So you should really give each submit button a name attribute and then check for this attribute as well.

okay, thanks, I’ll try that. I have thought that this is already done with the “special form names”.

For the completeness: here is what I have done.

Adding a hidden field to any form:

...
<input type="hidden" name="form" value="contact">
<?php echo csrf_field(); ?>
<?php echo honeypot_field(); ?>
...

Add check in controller or snippet:

...
if ($kirby->request()->is("POST") && $form->data("form") === "contact") {
...

Thank you for your awesome support.

The easy way to have multiple forms on one page is this plugin: GitHub - youngcut/kirby-form-blocks

Enjoy it!