1: <?php
2: 3: 4: 5: 6:
7:
8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
36: class QRadioButtonList extends QListControl {
37: const ButtonModeNone = 0;
38: const ButtonModeJq = 1;
39: const ButtonModeSet = 2;
40: const ButtonModeList = 3;
41:
42:
43:
44:
45:
46:
47: protected $strTextAlign = QTextAlign::Right;
48:
49:
50: protected $strButtonGroupClass;
51:
52:
53: protected $blnHtmlEntities = true;
54:
55:
56: protected $intCellPadding = -1;
57: protected $intCellSpacing = -1;
58: protected $intRepeatColumns = 1;
59: protected $strRepeatDirection = QRepeatDirection::Vertical;
60: protected $objItemStyle = null;
61: protected $intButtonMode;
62: protected $strMaxHeight;
63:
64: public function __construct($objParentObject, $strControlId = null) {
65: parent::__construct($objParentObject, $strControlId);
66: $this->objItemStyle = new QListItemStyle();
67: }
68:
69:
70:
71:
72: public function ParsePostData() {
73: $val = $this->objForm->CheckableControlValue($this->strControlId);
74: if ($val === null) {
75: $this->UnselectAllItems(false);
76: } else {
77: $this->SetSelectedItemsByIndex(array($val), false);
78: }
79: }
80:
81: public function GetEndScript() {
82: $ctrlId = $this->ControlId;
83: if ($this->intButtonMode == self::ButtonModeSet) {
84: QApplication::ExecuteControlCommand($ctrlId, 'buttonset', QJsPriority::High);
85: } elseif ($this->intButtonMode == self::ButtonModeJq) {
86: QApplication::ExecuteSelectorFunction(["input:radio", "#" . $ctrlId], 'button', QJsPriority::High);
87: }
88: $strScript = parent::GetEndScript();
89: return $strScript;
90: }
91:
92: protected function GetItemHtml($objItem, $intIndex, $strTabIndex, $blnWrapLabel) {
93: $objLabelStyles = new QTagStyler();
94: if ($this->objItemStyle) {
95: $objLabelStyles->Override($this->objItemStyle);
96: }
97: if ($objItemStyle = $objItem->ItemStyle) {
98: $objLabelStyles->Override($objItemStyle);
99: }
100:
101: $objStyles = new QTagStyler();
102: $objStyles->SetHtmlAttribute('type', 'radio');
103: $objStyles->SetHtmlAttribute('value', $intIndex);
104: $objStyles->SetHtmlAttribute('name', $this->strControlId);
105: $strIndexedId = $this->strControlId . '_' . $intIndex;
106: $objStyles->SetHtmlAttribute('id', $strIndexedId);
107:
108: if ($strTabIndex) {
109: $objStyles->TabIndex = $strTabIndex;
110: }
111: if (!$this->Enabled) {
112: $objStyles->Enabled = false;
113: }
114:
115: $strLabelText = $this->GetLabelText($objItem);
116:
117: if ($objItem->Selected) {
118: $objStyles->SetHtmlAttribute('checked', 'checked');
119: }
120:
121: $objStyles->SetHtmlAttribute("autocomplete", "off");
122:
123: if (!$blnWrapLabel) {
124: $objLabelStyles->SetHtmlAttribute('for', $strIndexedId);
125: }
126:
127: $this->OverrideItemAttributes($objItem, $objStyles, $objLabelStyles);
128:
129: $strHtml = QHtml::RenderLabeledInput(
130: $strLabelText,
131: $this->strTextAlign == QTextAlign::Left,
132: $objStyles->RenderHtmlAttributes(),
133: $objLabelStyles->RenderHtmlAttributes(),
134: $blnWrapLabel);
135:
136: return $strHtml;
137: }
138:
139: 140: 141: 142: 143: 144: 145:
146: protected function OverrideItemAttributes ($objItem, QTagStyler $objItemAttributes, QTagStyler $objLabelAttributes) {}
147:
148: 149: 150: 151: 152: 153:
154: protected function GetLabelText ($objItem) {
155: $strLabelText = $objItem->Label;
156: if (empty($strLabelText)) {
157: $strLabelText = $objItem->Name;
158: }
159: if ($this->blnHtmlEntities) {
160: $strLabelText = QApplication::HtmlEntities($strLabelText);
161: }
162: return $strLabelText;
163: }
164:
165: protected function GetControlHtml() {
166: $intItemCount = $this->GetItemCount();
167: if (!$intItemCount) return '';
168:
169: if ($this->intButtonMode == self::ButtonModeSet || $this->intButtonMode == self::ButtonModeList) {
170: return $this->RenderButtonSet();
171: }
172: elseif ($this->intRepeatColumns == 1) {
173: $strToReturn = $this->RenderButtonColumn();
174: }
175: else {
176: $strToReturn = $this->RenderButtonTable();
177: }
178:
179: if ($this->strMaxHeight) {
180: $objStyler = new QTagStyler();
181: $objStyler->SetCssStyle('max-height', $this->strMaxHeight, true);
182: $objStyler->SetCssStyle('overflow-y', 'scroll');
183:
184: $strToReturn = QHtml::RenderTag('div', $objStyler->RenderHtmlAttributes(), $strToReturn);
185: }
186: return $strToReturn;
187:
188: }
189:
190: 191: 192: 193:
194: public function RenderButtonTable() {
195:
196: $strToReturn = '';
197: if ($this->ItemCount > 0) {
198:
199: $intRowCount = floor($this->ItemCount / $this->intRepeatColumns);
200: $intWidowCount = ($this->ItemCount % $this->intRepeatColumns);
201: if ($intWidowCount > 0)
202: $intRowCount++;
203:
204:
205: for ($intRowIndex = 0; $intRowIndex < $intRowCount; $intRowIndex++) {
206:
207: if (($intRowIndex == $intRowCount - 1) && ($intWidowCount > 0))
208:
209: $intColCount = $intWidowCount;
210: else
211:
212: $intColCount = $this->intRepeatColumns;
213:
214:
215: $strRowHtml = '';
216: for ($intColIndex = 0; $intColIndex < $intColCount; $intColIndex++) {
217: if ($this->strRepeatDirection == QRepeatDirection::Horizontal)
218: $intIndex = $intColIndex + $this->intRepeatColumns * $intRowIndex;
219: else
220: $intIndex = (floor($this->ItemCount / $this->intRepeatColumns) * $intColIndex)
221: + min(($this->ItemCount % $this->intRepeatColumns), $intColIndex)
222: + $intRowIndex;
223:
224: $strItemHtml = $this->GetItemHtml($this->GetItem($intIndex), $intIndex, $this->GetHtmlAttribute('tabindex'), $this->blnWrapLabel);
225: $strCellHtml = QHtml::RenderTag ('td', null, $strItemHtml);
226: $strRowHtml .= $strCellHtml;
227: }
228:
229: $strRowHtml = QHtml::RenderTag('tr', null, $strRowHtml);
230: $strToReturn .= $strRowHtml;
231: }
232: }
233:
234: return $this->RenderTag('table',
235: null,
236: null,
237: $strToReturn);
238: }
239:
240: 241: 242: 243: 244:
245: public function RenderButtonSet() {
246: $count = $this->ItemCount;
247: $strToReturn = '';
248: for ($intIndex = 0; $intIndex < $count; $intIndex++) {
249: $strToReturn .= $this->GetItemHtml($this->GetItem($intIndex), $intIndex, $this->GetHtmlAttribute('tabindex'), $this->blnWrapLabel) . "\n";
250: }
251: return $this->RenderTag('div',
252: null,
253: null,
254: $strToReturn);
255: }
256:
257: 258: 259: 260:
261: public function RenderButtonColumn() {
262: $count = $this->ItemCount;
263: $strToReturn = '';
264: $groupAttributes = null;
265: if ($this->strButtonGroupClass) {
266: $groupAttributes = ["class"=>$this->strButtonGroupClass];
267: }
268: for ($intIndex = 0; $intIndex < $count; $intIndex++) {
269: $strHtml = $this->GetItemHtml($this->GetItem($intIndex), $intIndex, $this->GetHtmlAttribute('tabindex'), $this->blnWrapLabel);
270: $strToReturn .= QHtml::RenderTag('div', $groupAttributes, $strHtml);
271: }
272: return $this->RenderTag('div',
273: null,
274: null,
275: $strToReturn);
276: }
277:
278: public function Validate() {
279: if ($this->blnRequired) {
280: if ($this->SelectedIndex == -1) {
281: $this->ValidationError = sprintf(QApplication::Translate('%s is required'), $this->strName);
282: return false;
283: }
284: }
285:
286: return true;
287: }
288:
289: 290: 291: 292:
293: protected function RefreshSelection() {
294: $index = $this->SelectedIndex;
295: QApplication::ExecuteSelectorFunction(['input', '#' . $this->ControlId], 'val', [$index]);
296: if ($this->intButtonMode == self::ButtonModeSet ||
297: $this->intButtonMode == self::ButtonModeJq) {
298: QApplication::ExecuteSelectorFunction(['input', '#' . $this->ControlId], 'button', "refresh");
299: }
300: }
301:
302:
303:
304:
305: public function __get($strName) {
306: switch ($strName) {
307:
308: case "TextAlign": return $this->strTextAlign;
309:
310:
311: case "HtmlEntities": return $this->blnHtmlEntities;
312:
313:
314: case "CellPadding": return $this->intCellPadding;
315: case "CellSpacing": return $this->intCellSpacing;
316: case "RepeatColumns": return $this->intRepeatColumns;
317: case "RepeatDirection": return $this->strRepeatDirection;
318: case "ItemStyle": return $this->objItemStyle;
319: case "ButtonMode": return $this->intButtonMode;
320:
321: default:
322: try {
323: return parent::__get($strName);
324: } catch (QCallerException $objExc) {
325: $objExc->IncrementOffset();
326: throw $objExc;
327: }
328: }
329: }
330:
331:
332:
333:
334: public function __set($strName, $mixValue) {
335: switch ($strName) {
336:
337: case "TextAlign":
338: try {
339: if ($this->strTextAlign !== ($mixValue = QType::Cast($mixValue, QType::String))) {
340: $this->blnModified = true;
341: $this->strTextAlign = $mixValue;
342: }
343: break;
344: } catch (QInvalidCastException $objExc) {
345: $objExc->IncrementOffset();
346: throw $objExc;
347: }
348:
349: case "HtmlEntities":
350: try {
351: if ($this->blnHtmlEntities !== ($mixValue = QType::Cast($mixValue, QType::Boolean))) {
352: $this->blnModified = true;
353: $this->blnHtmlEntities = $mixValue;
354: }
355: break;
356: } catch (QInvalidCastException $objExc) {
357: $objExc->IncrementOffset();
358: throw $objExc;
359: }
360:
361:
362: case "CellPadding":
363: try {
364: $this->intCellPadding = QType::Cast($mixValue, QType::Integer);
365: break;
366: } catch (QInvalidCastException $objExc) {
367: $objExc->IncrementOffset();
368: throw $objExc;
369: }
370: case "CellSpacing":
371: try {
372: $this->intCellSpacing = QType::Cast($mixValue, QType::Integer);
373: break;
374: } catch (QInvalidCastException $objExc) {
375: $objExc->IncrementOffset();
376: throw $objExc;
377: }
378: case "RepeatColumns":
379: try {
380: $this->intRepeatColumns = QType::Cast($mixValue, QType::Integer);
381: } catch (QInvalidCastException $objExc) {
382: $objExc->IncrementOffset();
383: throw $objExc;
384: }
385: if ($this->intRepeatColumns < 1)
386: throw new QCallerException("RepeatColumns must be greater than 0");
387: break;
388: case "RepeatDirection":
389: try {
390: $this->strRepeatDirection = QType::Cast($mixValue, QType::String);
391: break;
392: } catch (QInvalidCastException $objExc) {
393: $objExc->IncrementOffset();
394: throw $objExc;
395: }
396: case "ItemStyle":
397: try {
398: $this->objItemStyle = QType::Cast($mixValue, "QListItemStyle");
399: } catch (QInvalidCastException $objExc) {
400: $objExc->IncrementOffset();
401: throw $objExc;
402: }
403: break;
404:
405: case "ButtonMode":
406: try {
407: $this->intButtonMode = QType::Cast($mixValue, QType::Integer);
408: } catch (QInvalidCastException $objExc) {
409: $objExc->IncrementOffset();
410: throw $objExc;
411: }
412: break;
413:
414: default:
415: try {
416: parent::__set($strName, $mixValue);
417: break;
418: } catch (QCallerException $objExc) {
419: $objExc->IncrementOffset();
420: throw $objExc;
421: }
422: }
423: }
424:
425: 426: 427: 428: 429:
430: public static function GetModelConnectorParams() {
431: return array_merge(parent::GetModelConnectorParams(), array(
432: new QModelConnectorParam (get_called_class(), 'TextAlign', '', QModelConnectorParam::SelectionList,
433: array (null=>'Default',
434: 'QTextAlign::Left'=>'Left',
435: 'QTextAlign::Right'=>'Right'
436: )),
437: new QModelConnectorParam (get_called_class(), 'HtmlEntities', 'Set to false to have the browser interpret the labels as HTML', QType::Boolean),
438: new QModelConnectorParam (get_called_class(), 'RepeatColumns', 'The number of columns of checkboxes to display', QType::Integer),
439: new QModelConnectorParam (get_called_class(), 'RepeatDirection', 'Whether to repeat horizontally or vertically', QModelConnectorParam::SelectionList,
440: array (null=>'Default',
441: 'QRepeatDirection::Horizontal'=>'Horizontal',
442: 'QRepeatDirection::Vertical'=>'Vertical'
443: )),
444: new QModelConnectorParam (get_called_class(), 'ButtonMode', 'How to display the buttons', QModelConnectorParam::SelectionList,
445: array (null=>'Default',
446: 'QRadioButtonList::ButtonModeJq'=>'JQuery UI Buttons',
447: 'QRadioButtonList::ButtonModeSet'=>'JQuery UI Buttonset'
448: )),
449: new QModelConnectorParam (get_called_class(), 'MaxHeight', 'If set, will wrap it in a scrollable pane with the given max height', QType::Integer)
450: ));
451: }
452:
453: }