ProcessWire - FormBuilder (Module): Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
 
(24 dazwischenliegende Versionen von 5 Benutzern werden nicht angezeigt)
Zeile 213: Zeile 213:
  
 
==Tipps und Tricks für Formbuilder==
 
==Tipps und Tricks für Formbuilder==
 +
=== Weiterleitung / Redirect auf Danke Seite ===
 +
 +
=== DatePicker ===
 +
==== Lokalisierung / Sprache einstellen====
 +
Der Formbuilder nutzt das Standard InputField Datetime. Das kann man übersetzen:
 +
https://processwire.com/talk/topic/4547-possibility-to-translate-timepicker-addon-on-datepicker/?tab=comments#comment-49746
 +
 +
In der folgenden datei kann man als Übersetzung den Pfad zur Lokalisierungsdatei von jQuery angeben (ist im PW mit drin).
 +
 +
Die Datei muss man evtl. selber anlegen (im Übersetzungstool) wenn die Indizierung sie nicht schon selbst angelegt hat.
 +
 +
/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeText.php
 +
path: /wire/modules/Jquery/JqueryUI/i18n/jquery.ui.datepicker-de.js
 +
 
=== Links in Checkbox-Label ===
 
=== Links in Checkbox-Label ===
 
HTML geht nicht aber Markdown funktioniert:
 
HTML geht nicht aber Markdown funktioniert:
Zeile 218: Zeile 232:
 
Ich habe die [Datenschutzerklärung](https://fbz-vet.de/datenschutz) gelesen und willige in die dort dargestellte Verarbeitung meiner personenbezogenen Daten ein.
 
Ich habe die [Datenschutzerklärung](https://fbz-vet.de/datenschutz) gelesen und willige in die dort dargestellte Verarbeitung meiner personenbezogenen Daten ein.
 
</pre>
 
</pre>
 +
 +
=== Formbuilder CSV Export der Eingaben automatisch ===
 +
<syntaxhighlight lang="php">
 +
$form = $forms->load('my-formname');
 +
$formBuilderEntries = $form->entries();
 +
$formBuilderEntries->exportCSV($form, "any_field=any_value");
 +
 +
//Same as above, but shorter:
 +
 +
$form = $forms->load('my-formname');
 +
$form->entries()->exportCSV($form, "any_field=any_value");
 +
</syntaxhighlight>
 +
 +
=== Hooks in general ===
 +
https://processwire.com/talk/topic/26362-general-question-on-formbuilder-and-hooks/#comment-218911
 +
 +
==== In Hooks auf Page zugreifen ====
 +
Im Hook
 +
$page = $event->wire()->page; // current $page API var
 +
Oder per use (siehe Beispiel unten)
 +
 +
=== Relevante Hooks ===
 +
Beispiele aus site/ready.php
 +
// if (isset($forms)) //...possible too
 +
<syntaxhighlight lang="php">
 +
 +
<?php namespace ProcessWire;
 +
 +
if(!defined("PROCESSWIRE")) die();
 +
 +
 +
// E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
 +
if($page->template->name=='job'){
 +
 +
  $formname = 'schnellkontakt';
 +
  $emailList = array(
 +
    'intensiv' => 'post@stephanschlegel.de',
 +
    'karlsruhe' => 'post@stephanschlegel.de',
 +
    'rastatt' => 'info@indiharart.de',
 +
    'pforzheim' => 'info@indiharart.de',
 +
    'rheinhausen' => 'info@indiharart.de',
 +
    'tagespflege' => 'info@indiharart.de',
 +
  );
 +
  $organization = $page->job->job_organizationname->title;
 +
  $organizationName = $page->job->job_organizationname->value;
 +
  $jobtitle = $page->title;
 +
 +
  $wire->addHookBefore('FormBuilderProcessor::renderReady',
 +
    function($event) use($organization, $jobtitle, $formname) {
 +
      $form = $event->arguments(0);
 +
      if($form->name !== $formname) return;
 +
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')
 +
        ->val($organization)
 +
        ->attr('disabled', 'disabled');
 +
      $form->getChildByName('ich_bewerbe_mich_als')
 +
        ->val($jobtitle)
 +
        ->attr('disabled', 'disabled');
 +
    }
 +
  );
 +
  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
 +
  $wire->addHook('FormBuilderProcessor::processInputDone',
 +
    function($event) use($organization, $jobtitle, $formname) {
 +
      $form = $event->arguments(0);
 +
      if($form->name !== $formname) return;
 +
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')->val($organization);
 +
      $form->getChildByName('ich_bewerbe_mich_als')->val($jobtitle); 
 +
    }
 +
  );
 +
  // change email based on job
 +
  $wire->addHookBefore('FormBuilderProcessor::emailForm',
 +
    function($event) use($organizationName, $emailList, $formname) {
 +
      $processor = $event->object;
 +
      if($processor->formName != $formname) return;
 +
      if(array_key_exists($organizationName,$emailList)){
 +
        $processor->emailTo = $emailList[$organizationName]; // tell FormBuilder to use that email
 +
      }
 +
    }
 +
  );
 +
 +
}
 +
 +
</syntaxhighlight>
 +
 +
=== Werte in Success Meldung anzeigen ===
 +
https://processwire.com/talk/topic/12874-mini-how-to-display-submitted-values-in-success-message/#comment-116913
 +
In site/ready.php I add this code...
 +
<syntaxhighlight lang="php">
 +
$forms->addHookAfter('FormBuilderProcessor::formSubmitSuccess', function($event) {
 +
    $form = $event->object;
 +
    if ($form->formName == 'YOUR-FORM-NAME-HERE' && $form->isSubmitted()) {
 +
        $values = $form->getValues();
 +
        array_walk($values, function(&$i){ $i = htmlentities($i, ENT_QUOTES, 'UTF-8', false); });
 +
        $form->successMessage = wirePopulateStringTags($form->successMessage, $values);
 +
    }
 +
});
 +
</syntaxhighlight>
 +
... changing 'YOUR-FORM-NAME-HERE' for the actual name of your form.
 +
 +
I can now include submitted values in my success messages. Like this;
 +
 +
Thank you, {name}. A confirmation email has been sent to {email}.
 +
 +
If I also want to clean up submitted values, prior to the form entry being saved (and, therefore, prior to success message display) I do that in another ready.php hook. In the following example I simply make sure that my collected email field is all lowercase...
 +
 +
<syntaxhighlight lang="php">
 +
$forms->addHookBefore('FormBuilderProcessor::saveForm', function($event) {
 +
    $form  = $event->arguments(0);
 +
    if($form->name == 'YOUR-FORM-NAME-HERE') {
 +
        // Sanitise the email field (all lower case)...
 +
        $f = $form->get('email');
 +
        $email = strtolower($f->value);
 +
        $f->attr('value', "$email");
 +
    }
 +
});
 +
</syntaxhighlight>
 +
 +
=== E-Mail Adressen per Hook manipulieren ===
 +
==== Admin E-Mail via User Option Feld auswählen ====
 +
Im Formular Feld "auswahl"
 +
 +
<pre>
 +
+Standortauswahl
 +
salusklinik=Salus Klinik Bad Reichenhall
 +
mvzreichenhall=MVZ Bad Reichenhall
 +
mvztraunstein=MVZ Traunstein
 +
mvzfeldmoching=MVZ Außenstelle Feldmoching
 +
</pre>
 +
site/ready.php
 +
<syntaxhighlight lang="php">
 +
// E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
 +
if($page->template->name=='layout-blocks'){
 +
 +
  $formName = 'kontakt';
 +
  $optionField = 'auswahl';
 +
  $emailList = array(
 +
    // We could use e-mail adresses as a value in the select field. But to keep it more secret we use a table.
 +
    'salusklinik' => 'post@stephanschlegel.de',
 +
    'mvzreichenhall' => 'stephanschlegel@gmx.de',
 +
    'mvztraunstein' => 'info@mvztraunstein.de',
 +
    'mvzfeldmoching' => 'info@hautarzt-feldmoching.de'
 +
  );
 +
 +
  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
 +
  $wire->addHook('FormBuilderProcessor::processInputDone',
 +
    function($event) use($formName, $optionField, $emailList) {
 +
      $processor = $event->object;
 +
      $form = $event->arguments(0);
 +
      if($form->name !== $formName) return;
 +
      $values = $processor->getValues();
 +
      if($email = $values[$optionField]){
 +
        //bd($email,'email');
 +
        if(array_key_exists($email, $emailList)) {
 +
          $processor->emailTo = $emailList[$email];
 +
          //bd($processor->emailTo,"email to");
 +
        }
 +
      }
 +
      //$form->getChildByName('message')->val($email.' email'); // use for debugging
 +
    }
 +
  );
 +
}
 +
</syntaxhighlight>
 +
==== Beispiel Forum ====
 +
Nicht getestet. Von:
 +
https://processwire.com/talk/topic/26261-solved-send-email-to-email-address-field-in-dynamic-page/#comment-218230
 +
In ready.php
 +
<syntaxhighlight lang="php">
 +
$wire->addHookBefore('FormBuilderProcessor::emailForm', function($event) {
 +
  $processor = $event->object;
 +
  if($processor->formName != 'myFormName') return;
 +
  $page = $event->wire()->page; // current $page API var
 +
  $email = $page->get('emailFieldName'); // get "email" field from current page
 +
  $processor->emailTo .= "\n" . $email; // use that email + admin Mail (Formbuilder uses one per line)
 +
});
 +
</syntaxhighlight>
 +
 +
==== Beispiel 2 - RepeaterMatrix ====
 +
In Repeatern oder einer RepeaterMatrix ist es evtl. geschickter auf andere Weise auf das richtige Feld des Formulars zuzugreifen. Den genauen Grund warum ich hier diesen Hook verwendet habe weiß ich nicht mehr. Er funktioniert auf alle Fälle gut in der RepeaterMatrix.
 +
<syntaxhighlight lang="php">
 +
$emailList = array(
 +
  'auftrag' => 'stephanschlegel@gmx.de',
 +
  'marketing' => 'post@stephanschlegel.de',
 +
  'personal' => 'post@stephanschlegel.de',
 +
  'gold' => 'post@stephanschlegel.de',
 +
  'technik' => 'post@stephanschlegel.de',
 +
  'beanstandungen' => 'post@stephanschlegel.de',
 +
  'sonstiges' => 'post@stephanschlegel.de',
 +
);
 +
 +
// HOOKS FÜR E-MAIL VERTEILER SCHNELLKONTAKT
 +
if($page->template->name=='layout-blocks'){ // check if template is correct
 +
  $formname = 'schnellkontakt';
 +
  $fieldname = 'bereich'; // take value of this field as selector
 +
  $wire->addHookBefore('FormBuilderProcessor::emailForm',
 +
    function($event) use($emailList, $formname, $fieldname) {
 +
      $processor = $event->object;
 +
      if($processor->formName != $formname) return; // check if we are in correct form
 +
      $form = $event->arguments(0);
 +
      $name = $form->getChildByName($fieldname)->val();
 +
      if(array_key_exists($name,$emailList)){
 +
        $processor->emailTo = $emailList[$name]; // tell FormBuilder to use that email
 +
      }
 +
    }
 +
  );
 +
}
 +
</syntaxhighlight>
 +
 +
==== Beispiel 3 ====
 +
Beispiel mit mehreren Formularen
 +
<syntaxhighlight lang="php">
 +
<?php namespace ProcessWire;
 +
 +
if(!defined("PROCESSWIRE")) die();
 +
 +
$emailList = array(
 +
  'organisationeins' => 'stephanschlegel@gmx.de',
 +
  'organisationzwei' => 'post@stephanschlegel.de',
 +
  'organisationdrei' => 'post@stephanschlegel.de',
 +
  'technik' => 'post@stephanschlegel.de',
 +
  'beanstandungen' => 'post@stephanschlegel.de',
 +
  'sonstiges' => 'post@stephanschlegel.de',
 +
);
 +
 +
// HOOKS FÜR BEWERBUNG IM JOBTEMPLATE
 +
if($page->template->name=='job'){
 +
  $formname = 'schnellkontakt';
 +
  // E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
 +
  $organization = $page->job->job_organizationname->title;
 +
  $organizationName = $page->job->job_organizationname->value;
 +
  $jobtitle = $page->title;
 +
 +
  $wire->addHookBefore('FormBuilderProcessor::renderReady',
 +
    function($event) use($organization, $jobtitle, $formname) {
 +
     
 +
      $form = $event->arguments(0);
 +
      if($form->name !== $formname) return;
 +
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')
 +
        ->val($organization)
 +
        ->attr('disabled', 'disabled');
 +
      $form->getChildByName('ich_bewerbe_mich_als')
 +
        ->val($jobtitle)
 +
        ->attr('disabled', 'disabled');
 +
    }
 +
  );
 +
  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
 +
  $wire->addHook('FormBuilderProcessor::processInputDone',
 +
    function($event) use($organization, $jobtitle, $formname) {
 +
      $form = $event->arguments(0);
 +
      if($form->name !== $formname) return;
 +
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')->val($organization);
 +
      $form->getChildByName('ich_bewerbe_mich_als')->val($jobtitle); 
 +
    }
 +
  );
 +
  // change email based on job
 +
  $wire->addHookBefore('FormBuilderProcessor::emailForm',
 +
    function($event) use($organizationName, $emailList, $formname) {
 +
      $processor = $event->object;
 +
      if($processor->formName != $formname) return;
 +
      if(array_key_exists($organizationName,$emailList)){
 +
        $processor->emailTo = $emailList[$organizationName]; // tell FormBuilder to use that email
 +
      }
 +
    }
 +
  );
 +
}else{
 +
  // HOOKS FÜR INITIATIVBEWERBUNG
 +
  // change email based on job
 +
  $wire->addHookBefore('FormBuilderProcessor::emailForm',
 +
    function($event) use($emailList) {
 +
      $processor = $event->object;
 +
      if($processor->formName != 'schnellkontakt') return;
 +
      $form = $event->arguments(0);
 +
      $name = $form->getChildByName('bereich')->val();
 +
      if(array_key_exists($name,$emailList)){
 +
        $processor->emailTo = $emailList[$name]; // tell FormBuilder to use that email
 +
      }
 +
    }
 +
  );
 +
}
 +
 +
</syntaxhighlight>
 +
 +
=== Feld Read Only bei Formular Rendering ===
 +
https://processwire.com/talk/topic/26373-making-field-read-only/#comment-218986
 +
 +
=== Prepopulated Fields ===
 +
https://processwire.com/talk/topic/25517-solved-pre-populated-fields/#comment-218903
 +
 +
=== PDF Download nach Form Submission ===
 +
https://processwire.com/talk/topic/26309-solved-download-pdf-file-after-submitting-the-contact-form/#comment-218905
 +
 +
=== JavaScript ausführen wenn Fehler im Formular sind ===
 +
Das ist z.B. nützlich wenn man das Formular in einem Modalfenster anzeigt und dieses nach dem Absenden nicht geöffnet ist. Dazu checkt man einfach ob in der Fehlerausgabe Daten sind:
 +
 +
JavaScript / jQuery
 +
<syntaxhighlight lang="javascript">
 +
if($("#FormBuilderSubmitted").length) {
 +
  // form was submitted and has errors -> open
 +
  showForm();
 +
}else{
 +
  hideModal();
 +
}
 +
</syntaxhighlight>
 +
 +
=== Eigene Templates für E-Mails ===
 +
==== Administrator E-Mail ====
 +
Hilfe bekommst du bereits beim Erstellen im Backend:
 +
o customize the email body, copy the template file
 +
/site/modules/FormBuilder/email-administrator.php
 +
into
 +
/site/templates/FormBuilder/email-administrator.php
 +
or
 +
/site/templates/FormBuilder/email-administrator-testform.php
 +
(creating the directory if not there already) and modify it to suit your needs.
 +
==== Beispiel: Nur ausgefüllte Felder anzeigen ====
 +
Im Template werden in der Variable $values bereits Formatiert gespeichert. Das bedeutet auch nicht übermittelte Felder enthalten Werte. Wir müssen daher die Rohwerte testen. Hier ein Beispiel wie man es machen kann:
 +
 +
<syntaxhighlight lang="php">
 +
<?php namespace ProcessWire;
 +
 +
/**
 +
* This is the email template used by the 'Email administrators' feature in Form Builder
 +
*
 +
* CUSTOMIZE
 +
* =========
 +
* To customize this email, copy this file to /site/templates/FormBuilder/email-administrator.php and modify it as needed.
 +
* To make it just for a one form, name it email-administrator-myform.php, replacing "myform" with form name.
 +
* It's preferable to do this so that your email template doesn't get overwritten during FormBuilder upgrades.
 +
* Inline styles are recommended in the markup since not all email clients will use <style></style> declarations.
 +
*
 +
* VARIABLES
 +
* =========
 +
* @var array $values This is an array of all submitted field values with ('field name' => 'field value') where the 'field value' is ready for output.
 +
* @var array $labels This is an array of all field labels with ('field name' => 'field label') where the 'field label' is ready for output.
 +
* @var array $formData Raw form data array, which is the same as $values but unformatted and with additional properties like 'entryID' and '_savePage' id.
 +
* @var FormBuilderEmail $formBuilderEmail Instance of FormBuilderEmail that is sending the message.
 +
* @var InputfieldForm $form Containing the entire form if you want grab anything else from it.
 +
* @var string $viewEntryUrl URL to view entry in the admin
 +
*
 +
*
 +
*/
 +
 +
if(!defined("PROCESSWIRE")) die();
 +
$out = '';
 +
$fieldsMarkup = '';
 +
$emptyFieldsMarkup = '';
 +
$styles = array(
 +
'table' => 'width:100%;border-bottom: 1px solid #ccc',
 +
'label' => 'width:30%;text-align:right;font-weight:bold;padding:10px 10px 10px 0;vertical-align:top;border-top:1px solid #ccc',
 +
'value' => 'width:70%;padding: 10px 0 10px 0;border-top: 1px solid #ccc',
 +
);
 +
//bd($formData, '$formData');
 +
foreach($values as $name => $value){
 +
  //bd($value);
 +
  if( !empty( $formData[$name] ) ){
 +
    $label = (isset($labels[$name]) ? $labels[$name] : '&nbsp;');
 +
    $fieldsMarkup .= '
 +
      <tr>
 +
        <th class="label" style="' . $styles["label"] . '">' . $label . '</th>
 +
        <td class="value" style="' . $styles['value'] . '">' . $value . '</td>
 +
      </tr>
 +
    ';
 +
  }else{
 +
    $emptyFieldsMarkup .= '
 +
      <p> ' . $label . '</p>';
 +
  }
 +
}
 +
 +
ob_start();
 +
?><!DOCTYPE html>
 +
<html>
 +
<head>
 +
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 +
<title><?= $form->name ?> email</title>
 +
</head>
 +
<body>
 +
<table style="<?= $styles['table']?>" cellspacing="0">
 +
    <?= $fieldsMarkup ?>
 +
  </table>
 +
  <div>
 +
    <p>Leere Felder oder kein Wert gewählt:</p>
 +
    <?= $emptyFieldsMarkup ?>
 +
  </div>
 +
<p><small><?= date('d.m.Y g:i') ?></small></p>
 +
</body>
 +
</html>
 +
<?php
 +
$out = ob_get_clean();
 +
echo $out;
 +
?>
 +
</syntaxhighlight>
 +
 +
== FormBuilder File Upload ==
 +
=== Links ===
 +
 +
== Feldtypen hinzufügen ==
 +
In den Settings von Formbuilder kann man Felder auswählen die man im Formular verwenden möchte. Z.B. erlaubt das Markup Feld das Einfügen von Text etc.
 +
=== Text im Formular einfügen ===
 +
Z.B. mit Markup Feld.
 +
 +
Vorsicht CK-Editor funktioniert nicht. Mit diesem stellst du dem User ein Eingabefeld mit Editor zur Verfügung (ungetestet - evtl. funktioniert das auch nicht oder erzeugt eine Sicherheitslücke).

Aktuelle Version vom 30. April 2025, 13:59 Uhr

https://processwire.com/store/form-builder/

Mails per smtp versenden[Bearbeiten]

ProcessWire - WireMailSmtp (Module)

CSS bei einfachem embed per iFrame anpassen[Bearbeiten]

Einfache Lösung:

  • auf Basic Output stellen
  • Standard CSS von /site/templates/FormBuilder/main.css kopieren
  • Neuen Pfad im Formbuilder Formular eingeben.

Nachteil, das könnte für den User zu kompliziert sein.

Import Daten für Standard Formular[Bearbeiten]

Hiermit kann man schnell ein Formular erstellen. Einfach in Import Feld des Formbuilder kopieren. Einfaches Standardformular:

{
    "action": "./",
    "method": "post",
    "roles": {
        "form-submit": [
            "guest"
        ],
        "form-list": [],
        "form-edit": [],
        "form-delete": [],
        "entries-list": [],
        "entries-edit": [],
        "entries-delete": [],
        "entries-page": []
    },
    "framework": "Basic",
    "submitText": "Senden",
    "successMessage": "Vielen Dank, ihre Nachricht wurde versendet.",
    "errorMessage": "Entschuldigung, das Formular konnte nicht versendet werden. Bitte füllen Sie alle Pflichtfelder aus. Zur Kontaktaufnahme benötigen wir entweder Ihre E-Mail oder Ihre Telefonnummer.",
    "emailSubject": "Nachricht über Ihr Kontaktformular",
    "responderSubject": "Auto-Response",
    "saveFlags": 2,
    "emailTo": "post@stephanschlegel.de",
    "emailFrom": "e_mail",
    "submitText1018": "Senden",
    "successMessage1018": "Vielen Dank, ihre Nachricht wurde versendet.",
    "errorMessage1018": "Entschuldigung, das Formular konnte nicht versendet werden. Bitte füllen Sie alle Pflichtfelder aus.",
    "frBasic_cssURL": "/site/templates/styles/forms.css",
    "frFoundation_foundationURL": "/site/modules/FormBuilder/frameworks/foundation/",
    "frFoundation_horizHeaderClass": "small-5 medium-3 right inline",
    "frFoundation_horizContentClass": "small-7 medium-9",
    "frUikit_ukURL": "/site/modules/FormBuilder/frameworks/uikit/",
    "frUikit_css": "uikit.gradient.min.css",
    "frUikit_horizHeaderWidth": 30,
    "frAdmin_styleSet": "AdminThemeDefault/styles/main-classic.css",
    "frBootstrap_bootURL": "/site/modules/FormBuilder/frameworks/bootstrap/",
    "frBootstrap_bootHorizHeaderClass": "col-xs-5 col-sm-4 col-md-3",
    "frBootstrap_bootHorizContentClass": "col-xs-7 col-sm-8 col-md-9",
    "children": {
        "name_1": {
            "type": "Text",
            "label": "Name",
            "label1018": "Ihr Name",
            "maxlength": 2048,
            "requiredAttr": 1
        },
        "telefon": {
            "type": "Text",
            "label": "Telefon",
            "required": 1,
            "columnWidth": 50,
            "label1018": "Ihre Telefonnummer",
            "maxlength": 2048,
            "requiredAttr": 1,
            "requiredIf": "e_mail=''",
            "stripTags": 1
        },
        "e_mail": {
            "type": "Text",
            "label": "E-Mail",
            "required": 1,
            "columnWidth": 50,
            "label1018": "Ihre E-Mail",
            "maxlength": 2048,
            "requiredIf": "telefon=''",
            "stripTags": 1
        },
        "ihre_nachricht": {
            "type": "Textarea",
            "label": "Ihre Nachricht",
            "required": 1,
            "label1018": "Ihre Nachricht",
            "rows": 5
        },
        "datenschutz": {
            "type": "Checkbox",
            "label": "Datenschutz",
            "description": "Mit meiner Kontaktaufnahme willige ich ein, dass meine Daten gespeichert und zur Bearbeitung meiner Anfrage/Kontaktaufnahme genutzt werden. Meine Daten werden niemals an Dritte weitergeleitet. Diese Einwilligung kann jederzeit widerrufen werden.",
            "required": 1,
            "label1018": "Datenschutz",
            "description1018": "Mit meiner Kontaktaufnahme willige ich ein, dass meine Daten gespeichert und zur Bearbeitung meiner Anfrage/Kontaktaufnahme genutzt werden. Meine Daten werden niemals an Dritte weitergeleitet. Diese Einwilligung kann jederzeit widerrufen werden.",
            "checkedValue": "Ich stimme zu"
        }
    }
}

Mit Adresse...

{
    "roles": {
        "form-submit": [
            "guest"
        ],
        "form-list": [],
        "form-edit": [],
        "form-delete": [],
        "entries-list": [],
        "entries-edit": [],
        "entries-delete": [],
        "entries-page": []
    },
    "framework": "Basic",
    "submitText": "Senden",
    "successMessage": "Vielen Dank, ihre Nachricht wurde versendet.",
    "errorMessage": "Entschuldigung, das Formular konnte nicht versendet werden. Bitte füllen Sie alle Pflichtfelder aus. Zur Kontaktaufnahme benötigen wir entweder Ihre E-Mail oder Ihre Telefonnummer.",
    "emailSubject": "Nachricht über Ihr Kontaktformular",
    "responderSubject": "Auto-Response",
    "saveFlags": 2,
    "emailTo": "post@stephanschlegel.de",
    "emailFrom": "e_mail",
    "submitText1018": "Senden",
    "successMessage1018": "Vielen Dank, ihre Nachricht wurde versendet.",
    "errorMessage1018": "Entschuldigung, das Formular konnte nicht versendet werden. Bitte füllen Sie alle Pflichtfelder aus.",
    "frBasic_cssURL": "/site/templates/styles/forms.css",
    "frFoundation_foundationURL": "/site/modules/FormBuilder/frameworks/foundation/",
    "frFoundation_horizHeaderClass": "small-5 medium-3 right inline",
    "frFoundation_horizContentClass": "small-7 medium-9",
    "frUikit_ukURL": "/site/modules/FormBuilder/frameworks/uikit/",
    "frUikit_css": "uikit.gradient.min.css",
    "frUikit_horizHeaderWidth": 30,
    "frAdmin_styleSet": "AdminThemeDefault/styles/main-classic.css",
    "frBootstrap_bootURL": "/site/modules/FormBuilder/frameworks/bootstrap/",
    "frBootstrap_bootHorizHeaderClass": "col-xs-5 col-sm-4 col-md-3",
    "frBootstrap_bootHorizContentClass": "col-xs-7 col-sm-8 col-md-9",
    "children": {
        "name_1": {
            "type": "Text",
            "label": "Name",
            "label1018": "Ihr Name",
            "maxlength": 2048,
            "requiredAttr": 1
        },
        "telefon": {
            "type": "Text",
            "label": "Telefon",
            "required": 1,
            "columnWidth": 50,
            "label1018": "Ihre Telefonnummer",
            "maxlength": 2048,
            "requiredAttr": 1,
            "requiredIf": "e_mail=''",
            "stripTags": 1
        },
        "e_mail": {
            "type": "Text",
            "label": "E-Mail",
            "required": 1,
            "columnWidth": 50,
            "label1018": "Ihre E-Mail",
            "maxlength": 2048,
            "requiredIf": "telefon=''",
            "stripTags": 1
        },
        "ihre_adresse": {
            "type": "Text",
            "label": "Straße",
            "columnWidth": 80,
            "label1018": "Straße",
            "requiredAttr": 1,
            "maxlength": 2048,
            "size": 100
        },
        "hausnummer": {
            "type": "Text",
            "label": "Hausnr.",
            "required": 1,
            "columnWidth": 20,
            "label1018": "Hausnr.",
            "maxlength": 2048
        },
        "plz_ort": {
            "type": "Text",
            "label": "PLZ Ort",
            "label1018": "PLZ Ort",
            "maxlength": 2048
        },
        "ihre_nachricht": {
            "type": "Textarea",
            "label": "Ihre Nachricht",
            "required": 1,
            "label1018": "Ihre Nachricht",
            "rows": 5,
            "requiredAttr": 1
        },
        "datenschutz": {
            "type": "Checkbox",
            "label": "Datenschutz",
            "description": "Mit meiner Kontaktaufnahme willige ich ein, dass meine Daten gespeichert und zur Bearbeitung meiner Anfrage/Kontaktaufnahme genutzt werden. Meine Daten werden niemals an Dritte weitergeleitet. Diese Einwilligung kann jederzeit widerrufen werden.",
            "required": 1,
            "label1018": "Datenschutz",
            "description1018": "Mit meiner Kontaktaufnahme willige ich ein, dass meine Daten gespeichert und zur Bearbeitung meiner Anfrage/Kontaktaufnahme genutzt werden. Meine Daten werden niemals an Dritte weitergeleitet. Diese Einwilligung kann jederzeit widerrufen werden.",
            "checkedValue": "1"
        }
    }
}

Tipps und Tricks für Formbuilder[Bearbeiten]

Weiterleitung / Redirect auf Danke Seite[Bearbeiten]

DatePicker[Bearbeiten]

Lokalisierung / Sprache einstellen[Bearbeiten]

Der Formbuilder nutzt das Standard InputField Datetime. Das kann man übersetzen:

https://processwire.com/talk/topic/4547-possibility-to-translate-timepicker-addon-on-datepicker/?tab=comments#comment-49746

In der folgenden datei kann man als Übersetzung den Pfad zur Lokalisierungsdatei von jQuery angeben (ist im PW mit drin).

Die Datei muss man evtl. selber anlegen (im Übersetzungstool) wenn die Indizierung sie nicht schon selbst angelegt hat.

/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeText.php
path: /wire/modules/Jquery/JqueryUI/i18n/jquery.ui.datepicker-de.js

Links in Checkbox-Label[Bearbeiten]

HTML geht nicht aber Markdown funktioniert:

Ich habe die [Datenschutzerklärung](https://fbz-vet.de/datenschutz) gelesen und willige in die dort dargestellte Verarbeitung meiner personenbezogenen Daten ein.

Formbuilder CSV Export der Eingaben automatisch[Bearbeiten]

$form = $forms->load('my-formname');
$formBuilderEntries = $form->entries();
$formBuilderEntries->exportCSV($form, "any_field=any_value");

//Same as above, but shorter:

$form = $forms->load('my-formname');
$form->entries()->exportCSV($form, "any_field=any_value");

Hooks in general[Bearbeiten]

https://processwire.com/talk/topic/26362-general-question-on-formbuilder-and-hooks/#comment-218911

In Hooks auf Page zugreifen[Bearbeiten]

Im Hook

$page = $event->wire()->page; // current $page API var

Oder per use (siehe Beispiel unten)

Relevante Hooks[Bearbeiten]

Beispiele aus site/ready.php

// if (isset($forms)) //...possible too
<?php namespace ProcessWire;

if(!defined("PROCESSWIRE")) die();


// E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
if($page->template->name=='job'){

  $formname = 'schnellkontakt';
  $emailList = array(
    'intensiv' => 'post@stephanschlegel.de',
    'karlsruhe' => 'post@stephanschlegel.de',
    'rastatt' => 'info@indiharart.de',
    'pforzheim' => 'info@indiharart.de',
    'rheinhausen' => 'info@indiharart.de',
    'tagespflege' => 'info@indiharart.de',
  );
  $organization = $page->job->job_organizationname->title;
  $organizationName = $page->job->job_organizationname->value;
  $jobtitle = $page->title;

  $wire->addHookBefore('FormBuilderProcessor::renderReady', 
    function($event) use($organization, $jobtitle, $formname) {
      $form = $event->arguments(0);
      if($form->name !== $formname) return;
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')
        ->val($organization)
        ->attr('disabled', 'disabled'); 
      $form->getChildByName('ich_bewerbe_mich_als')
        ->val($jobtitle)
        ->attr('disabled', 'disabled');
    }
  ); 
  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
  $wire->addHook('FormBuilderProcessor::processInputDone', 
    function($event) use($organization, $jobtitle, $formname) {
      $form = $event->arguments(0);
      if($form->name !== $formname) return;
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')->val($organization);
      $form->getChildByName('ich_bewerbe_mich_als')->val($jobtitle);  
    }
  ); 
  // change email based on job
  $wire->addHookBefore('FormBuilderProcessor::emailForm', 
    function($event) use($organizationName, $emailList, $formname) {
      $processor = $event->object;
      if($processor->formName != $formname) return; 
      if(array_key_exists($organizationName,$emailList)){
        $processor->emailTo = $emailList[$organizationName]; // tell FormBuilder to use that email
      }
    }
  );

}

Werte in Success Meldung anzeigen[Bearbeiten]

https://processwire.com/talk/topic/12874-mini-how-to-display-submitted-values-in-success-message/#comment-116913

In site/ready.php I add this code...

$forms->addHookAfter('FormBuilderProcessor::formSubmitSuccess', function($event) {
    $form = $event->object;
    if ($form->formName == 'YOUR-FORM-NAME-HERE' && $form->isSubmitted()) {
        $values = $form->getValues();
        array_walk($values, function(&$i){ $i = htmlentities($i, ENT_QUOTES, 'UTF-8', false); });
        $form->successMessage = wirePopulateStringTags($form->successMessage, $values);
    }
});

... changing 'YOUR-FORM-NAME-HERE' for the actual name of your form.

I can now include submitted values in my success messages. Like this;

Thank you, {name}. A confirmation email has been sent to {email}.

If I also want to clean up submitted values, prior to the form entry being saved (and, therefore, prior to success message display) I do that in another ready.php hook. In the following example I simply make sure that my collected email field is all lowercase...

$forms->addHookBefore('FormBuilderProcessor::saveForm', function($event) {
    $form  = $event->arguments(0);
    if($form->name == 'YOUR-FORM-NAME-HERE') {
        // Sanitise the email field (all lower case)...
        $f = $form->get('email');
        $email = strtolower($f->value);
        $f->attr('value', "$email");
    }
});

E-Mail Adressen per Hook manipulieren[Bearbeiten]

Admin E-Mail via User Option Feld auswählen[Bearbeiten]

Im Formular Feld "auswahl"

+Standortauswahl
salusklinik=Salus Klinik Bad Reichenhall
mvzreichenhall=MVZ Bad Reichenhall
mvztraunstein=MVZ Traunstein
mvzfeldmoching=MVZ Außenstelle Feldmoching

site/ready.php

// E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
if($page->template->name=='layout-blocks'){

  $formName = 'kontakt';
  $optionField = 'auswahl';
  $emailList = array(
    // We could use e-mail adresses as a value in the select field. But to keep it more secret we use a table.
    'salusklinik' => 'post@stephanschlegel.de',
    'mvzreichenhall' => 'stephanschlegel@gmx.de',
    'mvztraunstein' => 'info@mvztraunstein.de',
    'mvzfeldmoching' => 'info@hautarzt-feldmoching.de'
  );

  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
  $wire->addHook('FormBuilderProcessor::processInputDone', 
    function($event) use($formName, $optionField, $emailList) {
      $processor = $event->object;
      $form = $event->arguments(0);
      if($form->name !== $formName) return;
      $values = $processor->getValues();
      if($email = $values[$optionField]){
        //bd($email,'email');
        if(array_key_exists($email, $emailList)) {
          $processor->emailTo = $emailList[$email];
          //bd($processor->emailTo,"email to");
        }
      }
      //$form->getChildByName('message')->val($email.' email'); // use for debugging
    }
  ); 
}

Beispiel Forum[Bearbeiten]

Nicht getestet. Von:

https://processwire.com/talk/topic/26261-solved-send-email-to-email-address-field-in-dynamic-page/#comment-218230

In ready.php

$wire->addHookBefore('FormBuilderProcessor::emailForm', function($event) {
  $processor = $event->object; 
  if($processor->formName != 'myFormName') return; 
  $page = $event->wire()->page; // current $page API var
  $email = $page->get('emailFieldName'); // get "email" field from current page
  $processor->emailTo .= "\n" . $email; // use that email + admin Mail (Formbuilder uses one per line)
});

Beispiel 2 - RepeaterMatrix[Bearbeiten]

In Repeatern oder einer RepeaterMatrix ist es evtl. geschickter auf andere Weise auf das richtige Feld des Formulars zuzugreifen. Den genauen Grund warum ich hier diesen Hook verwendet habe weiß ich nicht mehr. Er funktioniert auf alle Fälle gut in der RepeaterMatrix.

$emailList = array(
  'auftrag' => 'stephanschlegel@gmx.de',
  'marketing' => 'post@stephanschlegel.de',
  'personal' => 'post@stephanschlegel.de',
  'gold' => 'post@stephanschlegel.de',
  'technik' => 'post@stephanschlegel.de',
  'beanstandungen' => 'post@stephanschlegel.de',
  'sonstiges' => 'post@stephanschlegel.de',
);

// HOOKS FÜR E-MAIL VERTEILER SCHNELLKONTAKT
if($page->template->name=='layout-blocks'){ // check if template is correct
  $formname = 'schnellkontakt';
  $fieldname = 'bereich'; // take value of this field as selector
  $wire->addHookBefore('FormBuilderProcessor::emailForm', 
    function($event) use($emailList, $formname, $fieldname) {
      $processor = $event->object;
      if($processor->formName != $formname) return; // check if we are in correct form
      $form = $event->arguments(0);
      $name = $form->getChildByName($fieldname)->val();
      if(array_key_exists($name,$emailList)){
        $processor->emailTo = $emailList[$name]; // tell FormBuilder to use that email
      }
    }
  );
}

Beispiel 3[Bearbeiten]

Beispiel mit mehreren Formularen

<?php namespace ProcessWire;

if(!defined("PROCESSWIRE")) die();

$emailList = array(
  'organisationeins' => 'stephanschlegel@gmx.de',
  'organisationzwei' => 'post@stephanschlegel.de',
  'organisationdrei' => 'post@stephanschlegel.de',
  'technik' => 'post@stephanschlegel.de',
  'beanstandungen' => 'post@stephanschlegel.de',
  'sonstiges' => 'post@stephanschlegel.de',
);

// HOOKS FÜR BEWERBUNG IM JOBTEMPLATE
if($page->template->name=='job'){
  $formname = 'schnellkontakt';
  // E-Mails (Wert aus Template 'job' Feld: job_organizationname => Mailadresse)
  $organization = $page->job->job_organizationname->title;
  $organizationName = $page->job->job_organizationname->value;
  $jobtitle = $page->title;

  $wire->addHookBefore('FormBuilderProcessor::renderReady', 
    function($event) use($organization, $jobtitle, $formname) {
      
      $form = $event->arguments(0);
      if($form->name !== $formname) return;
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')
        ->val($organization)
        ->attr('disabled', 'disabled'); 
      $form->getChildByName('ich_bewerbe_mich_als')
        ->val($jobtitle)
        ->attr('disabled', 'disabled');
    }
  ); 
  // nach dem übermitteln der eingaben (user kann nichts mehr ändern)
  $wire->addHook('FormBuilderProcessor::processInputDone', 
    function($event) use($organization, $jobtitle, $formname) {
      $form = $event->arguments(0);
      if($form->name !== $formname) return;
      $form->getChildByName('ich_bewerbe_mich_fur_folgende_einrichtung')->val($organization);
      $form->getChildByName('ich_bewerbe_mich_als')->val($jobtitle);  
    }
  ); 
  // change email based on job
  $wire->addHookBefore('FormBuilderProcessor::emailForm', 
    function($event) use($organizationName, $emailList, $formname) {
      $processor = $event->object;
      if($processor->formName != $formname) return; 
      if(array_key_exists($organizationName,$emailList)){
        $processor->emailTo = $emailList[$organizationName]; // tell FormBuilder to use that email
      }
    }
  );
}else{
  // HOOKS FÜR INITIATIVBEWERBUNG
  // change email based on job
  $wire->addHookBefore('FormBuilderProcessor::emailForm', 
    function($event) use($emailList) {
      $processor = $event->object;
      if($processor->formName != 'schnellkontakt') return; 
      $form = $event->arguments(0);
      $name = $form->getChildByName('bereich')->val();
      if(array_key_exists($name,$emailList)){
        $processor->emailTo = $emailList[$name]; // tell FormBuilder to use that email
      }
    }
  );
}

Feld Read Only bei Formular Rendering[Bearbeiten]

https://processwire.com/talk/topic/26373-making-field-read-only/#comment-218986

Prepopulated Fields[Bearbeiten]

https://processwire.com/talk/topic/25517-solved-pre-populated-fields/#comment-218903

PDF Download nach Form Submission[Bearbeiten]

https://processwire.com/talk/topic/26309-solved-download-pdf-file-after-submitting-the-contact-form/#comment-218905

JavaScript ausführen wenn Fehler im Formular sind[Bearbeiten]

Das ist z.B. nützlich wenn man das Formular in einem Modalfenster anzeigt und dieses nach dem Absenden nicht geöffnet ist. Dazu checkt man einfach ob in der Fehlerausgabe Daten sind:

JavaScript / jQuery

if($("#FormBuilderSubmitted").length) {
  // form was submitted and has errors -> open
  showForm();
}else{
  hideModal();
}

Eigene Templates für E-Mails[Bearbeiten]

Administrator E-Mail[Bearbeiten]

Hilfe bekommst du bereits beim Erstellen im Backend: o customize the email body, copy the template file

/site/modules/FormBuilder/email-administrator.php 

into

/site/templates/FormBuilder/email-administrator.php 

or

/site/templates/FormBuilder/email-administrator-testform.php 

(creating the directory if not there already) and modify it to suit your needs.

Beispiel: Nur ausgefüllte Felder anzeigen[Bearbeiten]

Im Template werden in der Variable $values bereits Formatiert gespeichert. Das bedeutet auch nicht übermittelte Felder enthalten Werte. Wir müssen daher die Rohwerte testen. Hier ein Beispiel wie man es machen kann:

<?php namespace ProcessWire;

/**
 * This is the email template used by the 'Email administrators' feature in Form Builder
 *
 * CUSTOMIZE
 * =========
 * To customize this email, copy this file to /site/templates/FormBuilder/email-administrator.php and modify it as needed.
 * To make it just for a one form, name it email-administrator-myform.php, replacing "myform" with form name.
 * It's preferable to do this so that your email template doesn't get overwritten during FormBuilder upgrades.
 * Inline styles are recommended in the markup since not all email clients will use <style></style> declarations.
 *
 * VARIABLES
 * =========
 * @var array $values This is an array of all submitted field values with ('field name' => 'field value') where the 'field value' is ready for output.
 * @var array $labels This is an array of all field labels with ('field name' => 'field label') where the 'field label' is ready for output.
 * @var array $formData Raw form data array, which is the same as $values but unformatted and with additional properties like 'entryID' and '_savePage' id. 
 * @var FormBuilderEmail $formBuilderEmail Instance of FormBuilderEmail that is sending the message.
 * @var InputfieldForm $form Containing the entire form if you want grab anything else from it.
 * @var string $viewEntryUrl URL to view entry in the admin
 *
 *
 */

if(!defined("PROCESSWIRE")) die();
$out = '';
$fieldsMarkup = '';
$emptyFieldsMarkup = '';
$styles = array(
	'table' => 'width:100%;border-bottom: 1px solid #ccc',
	'label' => 'width:30%;text-align:right;font-weight:bold;padding:10px 10px 10px 0;vertical-align:top;border-top:1px solid #ccc',
	'value' => 'width:70%;padding: 10px 0 10px 0;border-top: 1px solid #ccc',
);	
//bd($formData, '$formData');
foreach($values as $name => $value){
  //bd($value);
  if( !empty( $formData[$name] ) ){
    $label = (isset($labels[$name]) ? $labels[$name] : '&nbsp;');
    $fieldsMarkup .= '
      <tr> 
        <th class="label" style="' . $styles["label"] . '">' . $label . '</th>
        <td class="value" style="' . $styles['value'] . '">' . $value . '</td>
      </tr>
    '; 
  }else{
    $emptyFieldsMarkup .= '
      <p> ' . $label . '</p>';
  }
}

ob_start();
?><!DOCTYPE html>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<title><?= $form->name ?> email</title>
</head>
<body>
	<table style="<?= $styles['table']?>" cellspacing="0">
    <?= $fieldsMarkup ?>
  </table>
  <div>
    <p>Leere Felder oder kein Wert gewählt:</p>
    <?= $emptyFieldsMarkup ?>
  </div>
	<p><small><?= date('d.m.Y g:i') ?></small></p>
</body>
</html>
<?php
$out = ob_get_clean();
echo $out;
?>

FormBuilder File Upload[Bearbeiten]

Links[Bearbeiten]

Feldtypen hinzufügen[Bearbeiten]

In den Settings von Formbuilder kann man Felder auswählen die man im Formular verwenden möchte. Z.B. erlaubt das Markup Feld das Einfügen von Text etc.

Text im Formular einfügen[Bearbeiten]

Z.B. mit Markup Feld.

Vorsicht CK-Editor funktioniert nicht. Mit diesem stellst du dem User ein Eingabefeld mit Editor zur Verfügung (ungetestet - evtl. funktioniert das auch nicht oder erzeugt eine Sicherheitslücke).