Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?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