This is quite rough still. Its incredibly easy to make this by just extending \Phalcon\Forms\Element. Initially I did it in a roundabout way, which was very difficult, not going to show that :p
$postType = new RadioGroup("post_type", [
'elements' => Posts::postTypes(),
'class' => 'pure-button button-white segment-item'
]);
$postType->setFilters([
'striptags',
'trim'
]);
$postType->addValidators([
new StringLength([
'min' => 1,
'max' => 1,
'messageMaximum' => 'Too many characters for Post Type field',
'messageMinimum' => 'Post Type field cannot be empty',
'cancelOnFail' => true
]),
new Regex([
'pattern' => '/[a-z]/',
'message' => 'Post Type contained out of bounds characters',
'cancelOnFail' => true
]),
]);
if ($post) {
$postType->setChecked($post->post_type);
}
$this->add($postType);
I'd totally appreciate it if anyone has any tips or to share your own code, because this is probably lacking some crucial thing. But it does work for what I need, Phalcon will apply the validators and filters, and bind() also work. As you can see, I didn't have to do anything for that to work, Phalcon did it, nice!
Update: I had a setChecked() method, that was not needed and caused problems on save.
<?php
namespace Library\Forms\Element;
class RadioGroup extends \Phalcon\Forms\Element
{
private $checked = null;
/**
* More decoration than the regular render, does similar things, probably incomplete.
* Supported attributes:
* string `label` The entire group's label
* array `elements` Key, value associated array
* string `class` The CSS selectors for each HTML LABEL element
*
* @param array $attributes Render time attributes, will override what was set earlier.
* @return string A set of HTML radio elements.
*/
public function render($attributes = [])
{
// Overrides any attribute set earlier
if (!empty($attributes)) {
foreach ($attributes as $key => $val) {
$this->setAttribute($key, $val);
}
}
$attr = $this->getAttributes();
$rendered = isset($attr['label']) ? '<h3>' . $attr['label'] . '</h3>' : ''; // H3 NOT FINAL
$cssClass = isset($attr['class']) ? ' class="'.$attr['class'].'"' : '';
$eleName = $this->getName() . '_';
foreach($attr['elements'] as $key => $label) {
$checked = '';
if ($key == $this->getValue()) {
$checked = ' checked="true"';
}
$rendered .= '
<label for="'.$eleName . $key.'"'.$cssClass.'><input type="radio"'.$checked.' id="'.$eleName . $key. '" name="'.$this->getName().'" value="'.$key.'"> ' .
$label . '</label>' ;
}
return $rendered;
}
}
View:
<div class="button-group">
<?php
echo $form->render('post_type'), PHP_EOL;
?>
</div>
Output
<div class="button-group">
<label for="post_type_p" class="segment-item"><input type="radio" id="post_type_p" name="post_type" value="p"> Page</label>
<label for="post_type_b" class="segment-item"><input type="radio" checked="true" id="post_type_b" name="post_type" value="b"> Blog</label>
<label for="post_type_u" class="segment-item"><input type="radio" id="post_type_u" name="post_type" value="u"> Utility</label>
</div>