This file contains 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
<?php | |
function renderForm ($endpoint) { | |
// get the data from the API and convert it to a PHP object | |
$formResult = file_get_contents($endpoint); | |
$formContent = json_decode($formResult); | |
$formFields = $formContent->fields; | |
// start building the DOM | |
$dom = new DOMDocument(); | |
$form = $dom->createElement('form'); | |
// init tracking of rows | |
$row = 0; | |
$rowElement = $dom->createElement('div'); | |
$rowElement->setAttribute('class', 'field-row'); | |
// iterate over the fields and build each one | |
foreach ($formFields as $field) { | |
// build the container `<label>` | |
$element = $dom->createElement('label'); | |
$element->setAttribute('class', 'field'); | |
$element->setAttribute('data-row', $field->row); | |
$element->setAttribute('data-column', $field->column); | |
// reset input values | |
$input = null; | |
$label = null; | |
$validation = null; | |
// add a `<span>` for the label if it is set | |
if ($field->label) { | |
$label = $dom->createElement('span', $field->label); | |
$label->setAttribute('class', 'label'); | |
} | |
// add a `<em>` for the validation message if it is set | |
if (isset($field->validation_message)) { | |
$validation = $dom->createElement('em'); | |
$fragment = $dom->createDocumentFragment(); | |
$fragment->appendXML($field->validation_message); | |
$validation->appendChild($fragment); | |
$validation->setAttribute('class', 'validation-message'); | |
$validation->setAttribute('hidden', 'hidden'); | |
} | |
// if we've reached a new row, create a new $rowElement | |
if ($field->row > $row) { | |
$row = $field->row; | |
$rowElement = $dom->createElement('div'); | |
$rowElement->setAttribute('class', 'field-row'); | |
} | |
// build the input element | |
switch ($field->type) { | |
case 'text': | |
case 'email': | |
case 'telephone': | |
$input = $dom->createElement('input'); | |
$input->setAttribute('placeholder', ' '); | |
if ($field->type === 'email') $input->setAttribute('type', 'email'); | |
if ($field->type === 'telephone') $input->setAttribute('type', 'tel'); | |
break; | |
case 'text_area': | |
$input = $dom->createElement('textarea'); | |
$input->setAttribute('placeholder', ' '); | |
if ($rows = $field->field_metadata->rows) $input->setAttribute('rows', $rows); | |
break; | |
case 'checkbox': | |
$element->setAttribute('class', 'field single-checkbox'); | |
$input = $dom->createElement('input'); | |
$input->setAttribute('type', 'checkbox'); | |
if ($field->field_metadata->initially_checked === true) $input->setAttribute('checked', 'checked'); | |
break; | |
case 'hidden': | |
$input = $dom->createElement('input'); | |
$input->setAttribute('type', 'hidden'); | |
$input->setAttribute('value', $field->field_metadata->value); | |
$element->setAttribute('hidden', 'hidden'); | |
$element->setAttribute('style', 'display: none;'); | |
$label->textContent = ''; | |
break; | |
case 'select': | |
$element->setAttribute('class', 'field select'); | |
$input = $dom->createElement('select'); | |
$input->setAttribute('required', 'required'); | |
if ($field->field_metadata->multi_select === true) | |
$input->setAttribute('multiple', 'multiple'); | |
$options = []; | |
// track whether there's a pre-selected option | |
$optionSelected = false; | |
foreach ($field->field_metadata->values as $value) { | |
$option = $dom->createElement('option', htmlspecialchars($value->label)); | |
// bail if there's no value | |
if (!$value->value) continue; | |
// set pre-selected option | |
if ($value->selected === true) { | |
$option->setAttribute('selected', 'selected'); | |
$optionSelected = true; | |
} | |
$option->setAttribute('value', $value->value); | |
$options[] = $option; | |
} | |
// if there is not pre-selected option, build an empty placeholder option | |
if ($optionSelected === false) { | |
$emptyOption = $dom->createElement('option'); | |
// set option to hidden, disabled, and selected | |
foreach (['hidden', 'disabled', 'selected'] as $attribute) | |
$emptyOption->setAttribute($attribute, $attribute); | |
$input->appendChild($emptyOption); | |
} | |
// add options from array to `<select>` | |
foreach ($options as $option) { | |
$input->appendChild($option); | |
} | |
break; | |
case 'multiple_choice': | |
$choiceType = $field->field_metadata->multi_select === true ? 'checkbox' : 'radio'; | |
$element->setAttribute('class', "field {$choiceType}-group"); | |
$input = $dom->createElement('fieldset'); | |
// build a choice `<input>` for each option in the fieldset | |
foreach ($field->field_metadata->values as $choiceValue) { | |
$choiceField = $dom->createElement('div'); | |
$choiceField->setAttribute('class', 'choice'); | |
// set a unique ID using the field ID + the choice ID | |
$choiceID = "{$field->id}-{$choiceValue->value}"; | |
// build the `<input>` element | |
$choice = $dom->createElement('input'); | |
$choice->setAttribute('type', $choiceType); | |
$choice->setAttribute('value', $choiceValue->value); | |
$choice->setAttribute('id', $choiceID); | |
$choice->setAttribute('name', $field->id); | |
$choiceField->appendChild($choice); | |
// build the `<label>` element | |
$choiceLabel = $dom->createElement('label', $choiceValue->label); | |
$choiceLabel->setAttribute('for', $choiceID); | |
$choiceField->appendChild($choiceLabel); | |
$input->appendChild($choiceField); | |
} | |
break; | |
case 'instruction': | |
$element->setAttribute('class', 'field text'); | |
$fragment = $dom->createDocumentFragment(); | |
$fragment->appendXML($field->text); | |
$input = $dom->createElement('p'); | |
$input->appendChild($fragment); | |
break; | |
} | |
// add the input element to the row | |
if ($input) { | |
$input->setAttribute('id', $field->id); | |
if ($field->required) | |
$input->setAttribute('required', 'required'); | |
if (isset($field->max_length)) | |
$input->setAttribute('maxlength', $field->max_length); | |
$element->appendChild($input); | |
if ($label) | |
$element->appendChild($label); | |
if ($validation) | |
$element->appendChild($validation); | |
$rowElement->appendChild($element); | |
// automatically de-duped | |
$form->appendChild($rowElement); | |
} | |
} | |
// build the submit button | |
$submitButtonLabel = $formContent->submit_button_label; | |
$submitButtonField = $dom->createElement('div'); | |
$submitButtonField->setAttribute('class', 'field submit'); | |
$submitButton = $dom->createElement('button', $submitButtonLabel); | |
$submitButtonField->appendChild($submitButton); | |
$form->appendChild($submitButtonField); | |
// get the HTML output | |
$dom->appendChild($form); | |
$htmlString = $dom->saveHTML(); | |
echo $htmlString; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment