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