Form validation - checkbox?

Hey there,
I followed the cookbook example on how to save input as structure field, everything works fine, but … question there, how does one save the output of a checkbox input as structure field?

Cheers!

Do you mean a single checkbox or checkboxes?

<!-- single checkbox -->
<input type="checkbox">

Kirby saves the output of a checkbox field as 0 for unchecked and 1 for checked. But I’m not sure this is what your are asking?

ofc, gotta check value and return predefined text - stupid me!

ahh, well, not so the html input element … checked MDN but nothing useful there. echoing my checkbox value returns an empty string, it seems.

Could you post your complete code (or at least the relevant parts, form, validation, template code), I’m not sure where exactly your problem is?

<!-- snippets/form.php -->
<form class="form" method="post">

  <h2>Bestellformular</h2>

  <div class="form__item">
    <label for="full_name">Name:<span class="required"> (erforderlich)</span></label>
    <input type="text" id="full_name" name="full_name" placeholder="Name" value="<?= isset($data['full_name']) ? $data['full_name'] : '' ?>" required/>
  </div>

  <div class="form__item">
    <label for="email">Email:<span class="required"> (erforderlich)</span></label>
    <input type="email" name="email" id="email" placeholder="mail@beispiel.de" value="<?= isset($data['email']) ? $data['email'] : '' ?>" required/>
  </div>

  <div class="form__item">
    <label for="telefon">Telefon: </label>
    <input type="text" id="telefon" name="telefon" placeholder="Telefon" value="<?= isset($data['telefon']) ? $data['telefon'] : '' ?>"/>
  </div>

  <div class="form__item">
    <label for="datum">Datum der Veranstaltung: </label>
    <input type="text" id="datum" name="datum" placeholder="Datum der Veranstaltung" value="<?= isset($data['datum']) ? $data['datum'] : '' ?>"/>
  </div>

  <div class="form__item">
    <label for="art">Art der Veranstaltung: </label>
    <input type="text" id="art" name="art" placeholder="Art der Veranstaltung" value="<?= isset($data['art']) ? $data['art'] : '' ?>"/>
  </div>

  <div class="form__item">
    <label for="vegan">Vegan? </label>
    <input type="checkbox" id="vegan" name="vegan" placeholder="vegan" value="<?= isset($data['vegan']) ? $data['vegan'] : '' ?>"/>
  </div>

  <div class="form__item">
    <label for="nachricht">Nachricht:<span class="required"> (erforderlich)</span></label>
    <textarea name="nachricht" id="nachricht" placeholder="Wir freuen uns auf Ihre Bestellung!"><?= isset($data['nachricht']) ? $data['nachricht'] : '' ?></textarea>
  </div>

  <div class="honey">
     <label for="nachricht">If you are a human, leave this field empty</label>
     <input type="website" name="website" id="website" placeholder="http://example.com" value="<?= isset($data['website']) ? $data['website'] : '' ?>"/>
  </div>

  <button type="submit" name="order" value="Bestellen">Bestellen</button>

</form>
// controllers/form.php

<?php

return function($site, $pages, $page) {

  // for further information, see https://getkirby.com/docs/cookbook/creating-pages-from-frontend

  $alert = null;

  if(r::is('post') && get('order')) {
    if(!empty(get('website'))) {
      // lets tell the bot that everything is ok
      go($page->url());
      exit;
    }
    $data = array(
      'full_name'   => esc(get('full_name')),
      'email'       => esc(get('email')),
      'telefon'     => esc(get('telefon')),
      'datum'       => esc(get('datum')),
      'art'         => esc(get('art')),
      'vegan'       => esc(get('vegan')),
      'nachricht'   => esc(get('nachricht'))
    );

    $rules = array(
      'full_name'   => array('required'),
      'email'       => array('required', 'email'),
      'nachricht'   => array('required'),
    );
    $messages = array(
      'full_name'   => 'Name vergessen?',
      'email'       => 'Ungültige Mailadresse!',
      'nachricht'   => 'Bestellung vergessen?',
    );

    // some of the data is invalid
    if($invalid = invalid($data, $rules, $messages)) {
      $alert = $invalid;

    // the data is fine, let's send the email
    } else {

      // create the body from a simple snippet
      $body  = snippet('mailorder', $data, true);

      // build the email
      $email = email(array(
        'to'      => 'some@sender.io',
        'from'    => 'catering@some-mail.de',
        'subject' => 'Catering-Anfrage',
        'replyTo' => $data['email'],
        'body'    => $body
      ));

      // try to send it and redirect to the thank you page if it worked
      if(!$email->send()) {
        // go('catering/jetzt-bestellen');

      // add the error to the alert list if it failed
      // } else {
        $alert = array($email->error());
      }

      // function for saving data as structure field
      function addToStructure($p, $field, $data = array()) {
        $fieldData = $p->$field()->yaml();
        $fieldData[] = $data;
        $fieldData = yaml::encode($fieldData);
        $p->update(array(
          $field => $fieldData
        ));
      }

      // let's try to create a new order inside the structure field
      try {
        addToStructure($page, 'orders', $data);

        $success = 'Ihre Bestellung war erfolgreich!';
        $data = array();

      } catch(Exception $e) {
        echo 'Ihre Bestellung ist fehlgeschlagen: ' . $e->getMessage();
      }
    }
  }

  return compact('alert', 'data', 'success');
};
// templates/form.php
<?php snippet('header') ?>

  <section class="page">
    <?php
      // if the form was successfully submitted and the page created, show the success message
      if(isset($success)) :
    ?>
    <?= $page->text()->kt(); ?>
    <div class="form__message">
      <?= $success; ?>
    </div>
    <?php endif ?>

    <?php
      if(!isset($success)) {
        // if the $success variable is not set, show the form (i.e. when the page is first loaded or the form submission was not successful)
        echo $page->text()->kt();
        snippet('form', compact('data'));
      }
    ?>
    <?php
      if($alert) :
      // if the form input does not validate, show a list of alerts ?>
      <div class="form__alert">
        <h2>Achtung:</h2>
        <ul>
          <?php foreach($alert as $message) : ?>
            <li><?= html($message) ?></li>
          <?php endforeach ?>
        </ul>
      </div>
    <?php endif ?>


  </section>

<?php snippet('footer') ?>

Question of the day: How to check $vegan value which comes from <input type="checkbox">:

// snippets/mailorder.php
Von: <?= $full_name ?> (<?= $email ?>)

<?= $nachricht ?>

----
Weitere Informationen:

Telefon: <?= $email ?>
Datum: <?= $datum ?>
Art: <?= $art ?>
Vegan: <?php e($vegan == '', '👍', '👎') ?>

Update: string is empty no matter what I check - is it maybe when fetching the parameter at the beginning of the controller?

You can set any value to the value attribute, e.g. “vegan”. If the checkbox is unchecked, nothing is sent to the server; if the box is checked, the value is sent to the server. Then you can check the value and depending on what you want stored in your field, react on that. E.g. if the value is “vegan”, store “vegan” or 1 in the content file, if the field has no value, store 0 or an empty string.

ahh right, whatever key belongs to value is send, and in my example value always was empty.
stupid, thanks!