function render()
{
$disabled = "";
$inputclass = "";
$groupclass = "";
$placeholder = "";
$value = $this->value();
$label = $this->option("label");
$prop = $this->option("prop");
$helpblock = "";
$popover = "";
if ($this->option("readonly") === true) {
$inputclass .= " disabled";
$disabled = " disabled";
}
if ($this->option("error") === true) {
$groupclass .= " error";
}
$aOptions = $this->option("options");
if (!is_array($aOptions)) {
throw new \Exception("\\Formal\\Element\\Listbox->render(): 'options' has to be an array.");
}
if (($sHelp = trim($this->option("help"))) !== "") {
$helpblock = "<p class=\"help-block\">" . $sHelp . "</p>";
}
if (($aPopover = $this->option("popover")) !== "") {
$inputclass .= " popover-focus ";
$popover = " title=\"" . htmlspecialchars($aPopover["title"]) . "\" ";
$popover .= " data-content=\"" . htmlspecialchars($aPopover["content"]) . "\" ";
}
$clientvalue = htmlspecialchars($value);
$aRenderedOptions = [];
if (\Flake\Util\Tools::arrayIsSeq($aOptions)) {
# Array is sequential
reset($aOptions);
foreach ($aOptions as $sOptionValue) {
$selected = $sOptionValue === $value ? " selected=\"selected\"" : "";
$aRenderedOptions[] = "<option" . $selected . ">" . htmlspecialchars($sOptionValue) . "</option>";
}
} else {
# Array is associative
reset($aOptions);
foreach ($aOptions as $sOptionValue => $sOptionCaption) {
$selected = $sOptionValue === $value ? " selected=\"selected\"" : "";
$aRenderedOptions[] = "<option value=\"" . htmlspecialchars($sOptionValue) . "\"" . $selected . ">" . htmlspecialchars($sOptionCaption) . "</option>";
}
}
reset($aRenderedOptions);
$sRenderedOptions = implode("\n", $aRenderedOptions);
unset($aRenderedOptions);
$sHtml = <<<HTML
\t<div class="control-group{$groupclass}">
\t\t<label class="control-label" for="{$prop}">{$label}</label>
\t\t<div class="controls">
\t\t\t<select class="{$inputclass}" id="{$prop}" name="data[{$prop}]"{$disabled}{$popover}>
\t\t\t\t{$sRenderedOptions}
\t\t\t</select>
\t\t\t{$helpblock}
\t\t</div>
\t</div>
HTML;
return $sHtml . $this->renderWitness();
}