Created
April 28, 2026 12:33
-
-
Save jenswittmann/49a6a322cb085e3d4e594392f3ff754d to your computer and use it in GitHub Desktop.
A form builder that's simple to use, with fieldsets in a single file and Fenom syntax for MODX.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {var $forms = [ | |
| 'Schule' => [ | |
| 'fields' => [ | |
| 'Adresse' => [ | |
| 'schule' => [ | |
| 'type' => 'text', | |
| 'label' => 'Schule', | |
| 'required' => true, | |
| ], | |
| 'strasse' => [ | |
| 'type' => 'text', | |
| 'label' => 'Straße und Hausnummer', | |
| 'required' => true, | |
| ], | |
| 'plz' => [ | |
| 'type' => 'text', | |
| 'label' => 'PLZ', | |
| 'width' => 30, | |
| 'required' => true, | |
| ], | |
| 'ort' => [ | |
| 'type' => 'text', | |
| 'label' => 'Ort', | |
| 'width' => 60, | |
| 'required' => true, | |
| ], | |
| ], | |
| 'Ansprechperson' => [ | |
| 'vorname' => [ | |
| 'type' => 'text', | |
| 'label' => 'Vorname', | |
| 'width' => 40, | |
| 'required' => true, | |
| ], | |
| 'nachname' => [ | |
| 'type' => 'text', | |
| 'label' => 'Nachname', | |
| 'width' => 50, | |
| 'required' => true, | |
| ], | |
| 'email' => [ | |
| 'type' => 'text', | |
| 'label' => 'E-Mail', | |
| 'required' => true, | |
| 'validate' => ':email' | |
| ], | |
| 'telefon' => [ | |
| 'type' => 'text', | |
| 'label' => 'Telefon', | |
| ], | |
| ], | |
| 'Nachricht an uns' => [ | |
| 'betreff' => [ | |
| 'type' => 'text', | |
| 'label' => 'Betreff', | |
| 'required' => true, | |
| ], | |
| 'nachricht' => [ | |
| 'type' => 'textarea', | |
| 'label' => 'Nachricht', | |
| 'required' => true, | |
| ], | |
| ] | |
| ], | |
| ], | |
| ]} | |
| {var $formKey = $.get.form ?: 'Schule'} | |
| {var $fieldsValidate = []} | |
| {var $emailTplFields = []} | |
| {foreach $forms[$formKey]['fields'] as $title => $section} | |
| {foreach $section as $id => $field} | |
| {if $field['required']} | |
| {var $fieldsValidate[] = $id ~ ( $field['validate'] ?: '' ) ~ ':required'} | |
| {/if} | |
| {var $emailTplFields[] = '<li><strong>' ~ $field['label'] ~ ':</strong> ' ~ $.post[$id] ~ '</li>'} | |
| {/foreach} | |
| {/foreach} | |
| {var $emailTplFields = $emailTplFields | join : ''} | |
| {'!formit' | snippet : [ | |
| 'hooks' => 'FormItSaveForm,email', | |
| 'formName' => $formKey, | |
| 'formEncrypt' => true, | |
| 'emailFrom' => $_modx->config.emailsender, | |
| 'emailTo' => $fieldContent.settings.recipient, | |
| 'emailSubject' => 'Anfrage von Webseite: ' ~ $formKey, | |
| 'emailTpl' => '@CODE: | |
| <h2>Neue Anfrage: ' ~ $formKey ~ '</h2> | |
| <ul> | |
| ' ~ $emailTplFields ~ ' | |
| </ul> | |
| ', | |
| 'placeholderPrefix' => '', | |
| 'clearFieldsOnSuccess' => true, | |
| 'validate' => $fieldsValidate | join : ',', | |
| 'validationErrorMessage' => 'Bitte füllen Sie die erforderlichen Felder aus.', | |
| 'successMessage' => $fieldContent.settings.successMessage, | |
| ]} | |
| <div class="col-full start-2-m end-8-m"> | |
| <h2 id="form" class="f5 b mt4 mb3">Kontaktformular</h2> | |
| <ul class="list flex g1 f0 mb5"> | |
| {foreach $forms as $id => $form} | |
| <li> | |
| <a | |
| href="{$_modx->makeUrl($_modx->resource.id)}?form={$id}#form" | |
| class=" | |
| btn btn--rounded | |
| {if $id == $formKey} | |
| btn--active | |
| {/if} | |
| " | |
| >{$id}</a> | |
| </li> | |
| {/foreach} | |
| </ul> | |
| <form | |
| action="{$.server.REQUEST_URI}#form" | |
| method="post" | |
| class="form" | |
| novalidate | |
| > | |
| {if $_modx->getPlaceholder('error_message') || $_modx->getPlaceholder('validation_error_message') || $_modx->getPlaceholder('success')} | |
| <div | |
| aria-live="assertive" | |
| role="status" | |
| class=" | |
| form__message b p4 mb5 br3 br--bl0 | |
| {if $_modx->getPlaceholder('success')} | |
| bg-green-5 | |
| {else} | |
| bg-red-5 | |
| {/if} | |
| " | |
| > | |
| {$_modx->getPlaceholder('validation_error_message')} | |
| {$_modx->getPlaceholder('error_message')} | |
| {$_modx->getPlaceholder('fi.successMessage')} | |
| </div> | |
| {/if} | |
| {foreach $forms[$formKey]['fields'] as $title => $section} | |
| <fieldset class="flex flex-wrap justify-between g2 mb4 mb5-m bn"> | |
| <legend class="w-100 f4 b mt4 mt5-m mb3-m">{$title}</legend> | |
| {foreach $section as $id => $field} | |
| <div class="form__item w-{$field['width'] ?: '100'}"> | |
| {var $error = $_modx->getPlaceholder('error.' ~ $id)} | |
| {if $field['type'] == 'text'} | |
| <label for="{$id}" class="form__label f2"> | |
| {$field['label']} | |
| {if !$field['required']} | |
| <span class="o-50">(optional)</span> | |
| {/if} | |
| {if $error} | |
| <div id="{$id}_error" class="f2 b red-5">{$error}</div> | |
| {/if} | |
| </label> | |
| <div class="form__field form__field--input"> | |
| <input | |
| type="text" | |
| name="{$id}" | |
| id="{$id}" | |
| value="{$.post[$id]}" | |
| {if $field['required']} | |
| required | |
| {/if} | |
| {if $error} | |
| aria-invalid="true" | |
| aria-errormessage="{$id}_error" | |
| {/if} | |
| /> | |
| </div> | |
| {/if} | |
| {if $field['type'] == 'textarea'} | |
| <label for="{$id}" class="form__label"> | |
| {$field['label']} | |
| {if !$field['required']} | |
| <span class="o-50">(optional)</span> | |
| {/if} | |
| {if $error} | |
| <div id="{$id}_error" class="f2 b red-5">{$error}</div> | |
| {/if} | |
| </label> | |
| <div class="form__field form__field--textarea"> | |
| <textarea | |
| name="{$id}" | |
| id="{$id}" | |
| {if $field['required']} | |
| required | |
| {/if} | |
| {if $error} | |
| aria-invalid="true" | |
| aria-errormessage="{$id}_error" | |
| {/if} | |
| >{$.post[$id]}</textarea> | |
| </div> | |
| {/if} | |
| </div> | |
| {/foreach} | |
| </fieldset> | |
| {/foreach} | |
| <p class="f2 mv4-m sa11y-ignore"> | |
| Wir schützen die übermittelten Daten. Alle Infos dazu in der <a href="{$_modx->makeUrl(23)}" target="_blank" class="bb">Datenschutzerklärung</a>. | |
| </p> | |
| <button | |
| type="submit" | |
| class="btn btn--clean btn--bubble btn--bubble-black" | |
| > | |
| <span>Senden</span> | |
| <span class="icon icon-font"> | |
| {'arrow-right' | svg} | |
| </span> | |
| </button> | |
| </form> | |
| </div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment