A radio button element generator will share similarities with the generic HTML form element generator. As with any generic element, a set of radio buttons needs the ability to display an overall label and errors. There are two major differences, however:
Application\Form\Element\Radio class that extends Application\Form\Generic:namespace Application\Form\Element; use Application\Form\Generic; class Radio extends Generic { // code }
spacer, which will be placed between the radio button and its label. We also need to decide whether to place the radio button label before or after the actual button, thus, we use the $after flag. If we need a default, or if we are re-displaying existing form data, we need a way of designating the selected key. Finally, we need an array of options from which we will populate the list of buttons:const DEFAULT_AFTER = TRUE;
const DEFAULT_SPACER = '&nbps;';
const DEFAULT_OPTION_KEY = 0;
const DEFAULT_OPTION_VALUE = 'Choose';
protected $after = self::DEFAULT_AFTER;
protected $spacer = self::DEFAULT_SPACER;
protected $options = array();
protected $selectedKey = DEFAULT_OPTION_KEY;Application\Form\Generic, we have the option of expanding the __construct() method, or, alternatively, simply defining a method that can be used to set specific options. For this illustration, we have chosen the latter course.$this->options is populated, the first parameter ($options) is defined as mandatory (without a default). All other parameters are optional.public function setOptions(array $options,
$selectedKey = self::DEFAULT_OPTION_KEY,
$spacer = self::DEFAULT_SPACER,
$after = TRUE)
{
$this->after = $after;
$this->spacer = $spacer;
$this->options = $options;
$this->selectedKey = $selectedKey;
} getInputOnly() method.id attribute into an independent variable, $baseId, and later combine it with $count so that each id attribute is unique. If the option associated with the selected key is defined, it is assigned as the value; otherwise, we use the default:public function getInputOnly()
{
$count = 1;
$baseId = $this->attributes['id'];foreach() loop we check to see if the key is the one selected. If so, the checked attribute is added for that radio button. We then call the parent class getInputOnly() method to return the HTML for each button. Note that the value attribute of the input element is the options array key. The button label is the options array element value:foreach ($this->options as $key => $value) {
$this->attributes['id'] = $baseId . $count++;
$this->attributes['value'] = $key;
if ($key == $this->selectedKey) {
$this->attributes['checked'] = '';
} elseif (isset($this->attributes['checked'])) {
unset($this->attributes['checked']);
}
if ($this->after) {
$html = parent::getInputOnly() . $value;
} else {
$html = $value . parent::getInputOnly();
}
$output .= $this->spacer . $html;
}
return $output;
}Copy the preceding code into a new Radio.php file in the Application/Form/Element folder. You can then define a chap_06_form_element_radio.php calling script that sets up autoloading and anchors the new class:
<?php require __DIR__ . '/../Application/Autoload/Loader.php'; Application\Autoload\Loader::init(__DIR__ . '/..'); use Application\Form\Generic; use Application\Form\Element\Radio;
Next, define the wrappers using the $wrappers array defined in the previous recipe.
Then you can define a $status array and create an element instance by passing parameters to the constructor:
$statusList = [
'U' => 'Unconfirmed',
'P' => 'Pending',
'T' => 'Temporary Approval',
'A' => 'Approved'
];
$status = new Radio('status',
Generic::TYPE_RADIO,
'Status',
$wrappers,
['id' => 'status']);Now you can see if there is any status input from $_GET and set the options. Any input will become the selected key. Otherwise, the selected key is the default:
$checked = $_GET['status'] ?? 'U'; $status->setOptions($statusList, $checked, '<br>', TRUE);
Lastly, don't forget to define a submit button:
$submit = new Generic('submit',
Generic::TYPE_SUBMIT,
'Process',
$wrappers,
['id' => 'submit','title' =>
'Click to process','value' => 'Click Here']);The display logic might look like this:
<form name="status" method="get">
<table id="status" class="display" cellspacing="0" width="100%">
<tr><?= $status->render(); ?></tr>
<tr><?= $submit->render(); ?></tr>
<tr>
<td colspan=2>
<br>
<pre><?php var_dump($_GET); ?></pre>
</td>
</tr>
</table>
</form>Here is the actual output:
