Eventanmeldung

Eventanmeldung7 Min. Lesezeit

Anmeldeformular für Helfer mit Schichten, für Events und Festivals

Ein Anmeldeformular für Helfer, in dem man Schichten wählt, mit Telefonnummer für den Tag, und ein Skript, das unterbesetzte Schichten zeigt und den Dienstplan erstellt.

Preet SutharGründer, Ikiform

Lass Helfer in einem Formular jede Schicht ankreuzen, die sie übernehmen können, mit Telefonnummer, T-Shirt-Größe und Notfallkontakt, und sende es an Ikiform. Ikiform speichert jede Anmeldung und informiert die Koordinatoren per E-Mail, besetzt oder schließt aber keine Schichten. Führe also ein kurzes Skript aus, das die Helfer pro Schicht mit dem Bedarf vergleicht und einen Dienstplan schreibt. Fülle unterbesetzte Schichten, indem du die übrigen Helfer direkt fragst.

Was bei Helfern anders ist

Ein RSVP stellt eine Frage: Kommst du? Eine Helferanmeldung fragt nach dem Wann, und die Antwort zählt nur im Verhältnis zu dem, was jede Schicht braucht. Der Aufbau um 7 Uhr braucht sechs Leute und bekommt zwei; der sonnige Nachmittag braucht zehn und bekommt neunzehn. Es geht nicht ums Zählen, sondern um die Abdeckung.

  • Verfügbarkeit statt einer einzigen Wahl. Leute können mehrere Schichten übernehmen. Frag nach jeder Schicht, die sie machen könnten, und teile von dort aus ein, statt sie raten zu lassen, was gebraucht wird.
  • Erreichbarkeit am Tag selbst. E-Mail ist für die Planung. Am Tag selbst brauchst du eine Handynummer und einen Notfallkontakt für jeden Helfer.
  • Dinge zum Bestellen. T-Shirts, Lanyards und Mittagessen, nach Größe und Anzahl.
  • Alter. Viele Events verlangen für jeden Helfer Volljährigkeit oder die Zustimmung eines Erziehungsberechtigten. Frag deine Organisation, was gilt; eine Checkbox hält die Antwort fest, ist aber keine rechtliche Prüfung.

Helferplattformen wie SignUpGenius bieten Anmeldungen mit Slots, die einen Slot schließen, wenn er voll ist. Wenn du harte Limits pro Slot brauchst, nutze so eine Plattform. Ikiform passt zu Organisatoren, die das Formular auf ihrer eigenen Site haben wollen und Schichten gern von Hand aus einer sauberen Liste zuteilen.

Aus der Verfügbarkeit der Helfer einen Dienstplan machen, der die Lücken zeigtAnmeldeformularjede möglicheSchichtIkiformspeichert, mailtKoordinatorenDienstplan-SkriptHelfer proSchicht vs.Bedarfrota.csvNamen undNummern proSchichtAufbau: 2 von6die ÜbrigenfragenPostAPIunterbesetztAus der Verfügbarkeit der Helfer einen Dienstplan machen, der die Lücken zeigtAnmeldeformularjede mögliche SchichtIkiformspeichert, mailtKoordinatorenDienstplan-SkriptHelfer pro Schicht vs.Bedarfrota.csvNamen und Nummern proSchichtAufbau: 2von 6die ÜbrigenfragenPostAPIunterbesetzt
  1. Helfer kreuzen im Anmeldeformular jede Schicht an, die sie übernehmen könnten, und es wird an Ikiform gesendet.
  2. Ikiform speichert jede Anmeldung und informiert die Koordinatoren per E-Mail.
  3. Ein Skript liest die Anmeldungen über die API und vergleicht die Helfer pro Schicht mit dem Bedarf jeder Schicht.
  4. Es schreibt rota.csv mit Namen und Telefonnummern für jede Schicht.
  5. Unterbesetzte Schichten fallen sofort auf, etwa der Aufbau mit 2 von 6, sodass du Helfer fragen kannst, die anderswo übrig sind.
Ikiform hält die Verfügbarkeit fest. Das Skript macht daraus die Abdeckung, und eine Koordinatorin trifft die letzten Entscheidungen.

Das Formular

Gruppiere die Schichten nach Tag, damit man sie überfliegen kann. Die Checkboxen heißen shifts[], daher wird selbst ein einzelnes Häkchen als Liste gespeichert. Es funktioniert als einfaches HTML auf jeder Site und in jedem Baukasten, der Embeds erlaubt:

volunteer.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label>Name <input name="name" autocomplete="name" required></label>
  <label>Email <input name="email" type="email" autocomplete="email" required></label>
  <label>Mobile number for the day <input name="phone" type="tel" autocomplete="tel" placeholder="+44 7700 900123" required></label>

  <fieldset>
    <legend>Shifts you can do</legend>
    <p>Saturday</p>
    <label><input type="checkbox" name="shifts[]" value="sat_setup"> 7:00 to 10:00, setup</label>
    <label><input type="checkbox" name="shifts[]" value="sat_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sat_late"> 14:00 to 18:00</label>
    <p>Sunday</p>
    <label><input type="checkbox" name="shifts[]" value="sun_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sun_pack"> 14:00 to 17:00, pack-down</label>
  </fieldset>

  <label>Where you'd like to help
    <select name="role">
      <option value="anywhere">Anywhere</option>
      <option value="welcome">Welcome desk</option>
      <option value="food">Food stall</option>
      <option value="stewarding">Stewarding</option>
    </select>
  </label>
  <label>T-shirt size
    <select name="tshirt" required>
      <option value="s">S</option><option value="m" selected>M</option><option value="l">L</option>
      <option value="xl">XL</option><option value="xxl">XXL</option>
    </select>
  </label>
  <label>Emergency contact name and number <input name="emergency_contact" required maxlength="160"></label>
  <label><input type="checkbox" name="adult" required> I'm 18 or over, or a parent or guardian is filling this in with me</label>

  <input type="hidden" name="_redirect" value="https://fair.example/volunteers/thanks">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Sign me up</button>
</form>

Füge diese Definition im Tab Fields des Formulars ein. Der Server lehnt dann eine Anmeldung ohne Schichten, mit einer Telefonnummer, die keine ist, oder mit nicht angehakter Altersbox ab, egal von welcher Seite sie kommt:

Vorschau

Führt den Validator von Ikiform in deinem Browser aus. Es wird nichts gesendet.

Wir schicken Schichtänderungen per SMS. Gib deine Ländervorwahl mit an.

Schichten, die du übernehmen kannst
shifts ist ein multi_select mit min_items: 1. phone ist ein phone-Feld, das das Format der Nummer prüft. adult muss angehakt sein.
FeldWarum es da ist
phoneSchichtänderungen per SMS schicken und Leute am Tag selbst erreichen
shiftsVerfügbarkeit, aus der du einteilst
roleVorlieben, damit der Empfang die Leute bekommt, die darum gebeten haben
tshirtDie Bestellung, die du zwei Wochen vorher aufgibst
emergency_contactFür das Erste-Hilfe-Team, nicht fürs Marketing
adultDie Altersregel deiner Organisation, festgehalten in einer Einsendung, die ihr eigenes created_at behält
Telefonnummern und Notfallkontakte sind personenbezogene Daten über Menschen, die sich nicht selbst anmelden. Bewahre den Export an einem privaten Ort auf, teile den Dienstplan nur mit den Schichtleitungen und lösche die Einsendungen nach dem Event.

Den Dienstplan erstellen und die Lücken sehen

Führe das mit Node und einem geheimen API-Schlüssel aus, wann immer du den Überblick willst. Es nimmt die neueste Anmeldung jedes Helfers, gibt jede Schicht als besetzt, unterbesetzt oder mit Überschuss aus und schreibt rota.csv mit Namen und Nummern für jede Schicht:

rota.ts
import { writeFileSync } from "node:fs";
import { createClient } from "@ikiform/sdk";

const NEEDED: Record<string, number> = { sat_setup: 6, sat_day: 10, sat_late: 10, sun_day: 8, sun_pack: 6 };
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });
const people = new Map<string, Record<string, unknown>>();

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received", limit: 100 })) {
  const email = String(submission.fields.email ?? "").trim().toLowerCase();
  if (email && !people.has(email)) people.set(email, submission.fields);
}

const cell = (value: unknown) => `"${String(value ?? "").replaceAll('"', '""')}"`;
const rows = [["shift", "name", "phone", "role", "tshirt"].join(",")];

for (const [shift, needed] of Object.entries(NEEDED)) {
  const team = [...people.values()].filter((fields) => (fields.shifts as string[] | undefined)?.includes(shift));
  const state = team.length < needed ? `SHORT ${needed - team.length}` : team.length > needed ? "spare" : "ok";
  console.log(`${shift.padEnd(10)} ${team.length}/${needed} ${state}`);
  for (const fields of team) {
    rows.push([shift, fields.name, fields.phone, fields.role, fields.tshirt].map(cell).join(","));
  }
}

writeFileSync("rota.csv", `${rows.join("\n")}\n`);
  • Listen kommen neueste zuerst, daher wird ein Helfer, der sich mit geänderter Verfügbarkeit erneut anmeldet, mit seiner neuesten Antwort gezählt.
  • Eine Person erscheint unter jeder Schicht, die sie angekreuzt hat. Das ist Verfügbarkeit. Reduziere sie in der CSV auf Zuteilungen und sag jeder Person ihre endgültigen Schichten.
  • Kommas und Anführungszeichen in Namen werden escaped, sodass die CSV in jeder Tabellenkalkulation sauber aufgeht.

Für einen schnellen Blick ohne Code exportiere die CSV unter Submissions und filtere die Spalte shifts nach dem Wert einer Schicht, etwa sat_setup. Mehrfachauswahl-Werte stehen im Export zusammen in einer Zelle.

Von der Verfügbarkeit zur Zuteilung

  1. Führe zwei Wochen vorher den Dienstplan aus und bestelle T-Shirts anhand der Zahlen in tshirt.
  2. Schreib für jede unterbesetzte Schicht den Helfern, die übrig sind und diese Schicht auch angekreuzt haben. Sie haben schon gesagt, dass sie können.
  3. Schick jedem Helfer seine endgültigen Schichten aus deinem E-Mail- oder Messaging-Tool. Reply in der Benachrichtigungs-E-Mail geht direkt an ihn.
  4. Druck am Vortag den Dienstplan mit Telefonnummern für die Schichtleitungen aus.

Ikiform schickt der Person, die das Formular ausfüllt, keine E-Mail. Benachrichtigungs-E-Mails gehen nur an dich und dein Team, es gibt also keinen Autoresponder, keine Bestätigungs-E-Mail und kein Double-Opt-in. Verschicke sie aus deinem E-Mail-Tool, ausgelöst durch einen Webhook. Helfer vergessen, wofür sie sich eingetragen haben, also schick den endgültigen Dienstplan eine Woche vorher persönlich und noch einmal am Vorabend.

Um von jeder Anmeldung dort zu erfahren, wo dein Team ohnehin kommuniziert, schick den Webhook an Slack oder Discord. Die Koordinatoren sehen dann, wie sich eine unterbesetzte Schicht füllt.

Vor der Helfersuche prüfen

  1. Füge unter Allowed domains des Formulars die Domain deiner Site hinzu, plus localhost, während du entwickelst. Lass das Feld leer, um Posts von überall anzunehmen.
  2. Melde dich mit einer angekreuzten Schicht an. Im Dashboard ist shifts eine Liste mit einem Wert.
  3. Versuch, dich ohne Schichten oder mit nicht angehakter Altersbox anzumelden. Der Browser hält dich auf, und ein manipulierter Post bekommt 422.
  4. Prüfe das Postfach jedes Benachrichtigungsempfängers. Jeder bekommt eine E-Mail mit den Feldern, und Reply geht an den Absender, wenn das Formular ein email-Feld hat.
  5. Führe das Dienstplan-Skript aus. Dein Test erscheint unter seiner Schicht, und jede andere Schicht wird als unterbesetzt angezeigt.
  6. Öffne rota.csv in einer Tabellenkalkulation und prüfe die Spalte mit den Telefonnummern.

Stolperfallen

ProblemWas zu tun ist
Eine einzelne Schicht wird als Text gespeichert, nicht als ListeDie Checkboxen heißen shifts ohne [], und es ist kein Feld definiert. Benenne sie in shifts[] um oder definiere shifts als multi_select.
422 bei phoneDie Nummer sieht nicht wie eine Telefonnummer aus. Bitte im Hilfetext um die Ländervorwahl, wie es die Definition tut.
Ein Helfer erscheint zweimal im DienstplanEr hat sich mit zwei verschiedenen E-Mail-Adressen angemeldet. Führe die Einträge von Hand zusammen; das Skript ordnet nach E-Mail-Adresse zu.
422 validation_failedDer Post passt nicht zur Felddefinition des Formulars. error.fields nennt jedes Feld und den Grund. Gleiche den name des Eingabefelds an die Feld-ID an.
429 rate_limitedEin Besucher hat mehr gesendet, als das Rate-Limit des Formulars erlaubt. Standard erlaubt 5 pro Minute und Besucher. Warte Retry-After ab oder wähle Relaxed oder Custom für Formulare, die von einer gemeinsamen IP aus senden.

Fragen

Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.