1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: */
11:
12: namespace Nette\Forms;
13:
14: use Nette,
15: Nette\Web\Html;
16:
17:
18:
19: /**
20: * Set of radio button controls.
21: *
22: * @author David Grudl
23: *
24: * @property array $items
25: * @property-read Nette\Web\Html $separatorPrototype
26: * @property-read Nette\Web\Html $containerPrototype
27: */
28: class RadioList extends FormControl
29: {
30: /** @var Nette\Web\Html separator element template */
31: protected $separator;
32:
33: /** @var Nette\Web\Html container element template */
34: protected $container;
35:
36: /** @var array */
37: protected $items = array();
38:
39:
40:
41: /**
42: * @param string label
43: * @param array options from which to choose
44: */
45: public function __construct($label = NULL, array $items = NULL)
46: {
47: parent::__construct($label);
48: $this->control->type = 'radio';
49: $this->container = Html::el();
50: $this->separator = Html::el('br');
51: if ($items !== NULL) $this->setItems($items);
52: }
53:
54:
55:
56: /**
57: * Returns selected radio value.
58: * @param bool
59: * @return mixed
60: */
61: public function getValue($raw = FALSE)
62: {
63: return is_scalar($this->value) && ($raw || isset($this->items[$this->value])) ? $this->value : NULL;
64: }
65:
66:
67:
68: /**
69: * Sets options from which to choose.
70: * @param array
71: * @return RadioList provides a fluent interface
72: */
73: public function setItems(array $items)
74: {
75: $this->items = $items;
76: return $this;
77: }
78:
79:
80:
81: /**
82: * Returns options from which to choose.
83: * @return array
84: */
85: final public function getItems()
86: {
87: return $this->items;
88: }
89:
90:
91:
92: /**
93: * Returns separator HTML element template.
94: * @return Nette\Web\Html
95: */
96: final public function getSeparatorPrototype()
97: {
98: return $this->separator;
99: }
100:
101:
102:
103: /**
104: * Returns container HTML element template.
105: * @return Nette\Web\Html
106: */
107: final public function getContainerPrototype()
108: {
109: return $this->container;
110: }
111:
112:
113:
114: /**
115: * Generates control's HTML element.
116: * @param mixed
117: * @return Nette\Web\Html
118: */
119: public function getControl($key = NULL)
120: {
121: if ($key === NULL) {
122: $container = clone $this->container;
123: $separator = (string) $this->separator;
124:
125: } elseif (!isset($this->items[$key])) {
126: return NULL;
127: }
128:
129: $control = parent::getControl();
130: $id = $control->id;
131: $counter = -1;
132: $value = $this->value === NULL ? NULL : (string) $this->getValue();
133: $label = Html::el('label');
134:
135: foreach ($this->items as $k => $val) {
136: $counter++;
137: if ($key !== NULL && $key != $k) continue; // intentionally ==
138:
139: $control->id = $label->for = $id . '-' . $counter;
140: $control->checked = (string) $k === $value;
141: $control->value = $k;
142:
143: if ($val instanceof Html) {
144: $label->setHtml($val);
145: } else {
146: $label->setText($this->translate($val));
147: }
148:
149: if ($key !== NULL) {
150: return (string) $control . (string) $label;
151: }
152:
153: $container->add((string) $control . (string) $label . $separator);
154: // TODO: separator after last item?
155: }
156:
157: return $container;
158: }
159:
160:
161:
162: /**
163: * Generates label's HTML element.
164: * @param string
165: * @return void
166: */
167: public function getLabel($caption = NULL)
168: {
169: $label = parent::getLabel($caption);
170: $label->for = NULL;
171: return $label;
172: }
173:
174:
175:
176: /**
177: * Filled validator: has been any radio button selected?
178: * @param IFormControl
179: * @return bool
180: */
181: public static function validateFilled(IFormControl $control)
182: {
183: return $control->getValue() !== NULL;
184: }
185:
186: }
187: