1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12:
13: if (!defined('__FONT_AWESOME__')) {
14: define('__FONT_AWESOME__', 'https://opensource.keycdn.com/fontawesome/4.6.3/font-awesome.min.css');
15: }
16:
17: class QDataGrid_SortEvent extends QEvent {
18: const JsReturnParam = 'ui';
19: const EventName = 'qdg2sort';
20: }
21:
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
42: class QDataGridBase extends QHtmlTable
43: {
44:
45: const SortAscending = 1;
46: const SortDescending = -1;
47:
48:
49: protected $intLastColumnId = 0;
50:
51:
52: protected $strSortColumnId;
53:
54:
55: protected $intSortDirection = self::SortAscending;
56:
57:
58: protected $strCssClass = 'datagrid';
59:
60:
61: 62: 63: 64: 65:
66: public function __construct($objParentObject, $strControlId = null) {
67: try {
68: parent::__construct($objParentObject, $strControlId);
69:
70: $this->AddCssFile(__FONT_AWESOME__);
71:
72: $this->AddActions();
73:
74: } catch (QCallerException $objExc) {
75: $objExc->IncrementOffset();
76: throw $objExc;
77: }
78: }
79:
80: 81: 82: 83:
84: protected function RenderCaption() {
85: return $this->RenderPaginator();
86: }
87:
88: 89: 90: 91: 92:
93: protected function RenderPaginator () {
94: $objPaginator = $this->objPaginator;
95: if (!$objPaginator) return '';
96:
97: $strHtml = $objPaginator->Render(false);
98: $strHtml = QHtml::RenderTag('span', ['class'=>'paginator-control'], $strHtml);
99: if ($this->strCaption) {
100: $strHtml = '<span>' . QApplication::HtmlEntities($this->strCaption) . '</span>' . $strHtml;
101: }
102:
103: $strHtml = QHtml::RenderTag('caption', null, $strHtml);
104:
105: return $strHtml;
106: }
107:
108: 109: 110: 111:
112: public function AddActions() {
113: $this->AddAction(new QHtmlTableCheckBoxColumn_ClickEvent(), new QAjaxControlAction ($this, 'CheckClick'));
114: $this->AddAction(new QHtmlTableCheckBoxColumn_ClickEvent(), new QStopPropagationAction());
115:
116: $this->AddAction(new QDataGrid_SortEvent(), new QAjaxControlAction ($this, 'SortClick'));
117: }
118:
119: 120: 121: 122: 123: 124: 125:
126: public function AddColumnAt($intColumnIndex, QAbstractHtmlTableColumn $objColumn) {
127: parent::AddColumnAt($intColumnIndex, $objColumn);
128:
129: if (!$objColumn->Id) {
130: $objColumn->Id = $this->ControlId . '_col_' . $this->intLastColumnId++;
131: }
132: }
133:
134: 135: 136: 137: 138: 139: 140:
141: protected function CheckClick($strFormId, $strControlId, $strParameter) {
142: $intColumnIndex = $strParameter['col'];
143: $objColumn = $this->GetColumn ($intColumnIndex, true);
144:
145: if ($objColumn instanceof QDataGrid_CheckboxColumn) {
146: $objColumn->Click($strParameter);
147: }
148: }
149:
150: 151: 152: 153: 154: 155:
156: public function ClearCheckedItems($strColId = null) {
157: foreach ($this->objColumnArray as $objColumn) {
158: if ($objColumn instanceof QDataGrid_CheckboxColumn) {
159: if (is_null($strColId) || $objColumn->Id === $strColId) {
160: $objColumn->ClearCheckedItems();
161: }
162: }
163: }
164: }
165:
166: 167: 168: 169: 170: 171: 172: 173:
174: public function GetCheckedItemIds($strColId = null) {
175: foreach ($this->objColumnArray as $objColumn) {
176: if ($objColumn instanceof QDataGrid_CheckboxColumn) {
177: if (is_null($strColId) ||
178: $objColumn->Id === $strColId) {
179: return $objColumn->GetCheckedItemIds();
180: }
181: }
182: }
183: return null;
184: }
185:
186: 187: 188: 189: 190: 191: 192: 193: 194:
195: protected function SortClick($strFormId, $strControlId, $mixParameter) {
196:
197: $intColumnIndex = QType::Cast($mixParameter, QType::Integer);
198: $objColumn = $this->GetColumn ($intColumnIndex, true);
199:
200: if (!$objColumn) return;
201:
202: $this->blnModified = true;
203:
204: $strId = $objColumn->Id;
205:
206: if (!$objColumn) {
207: return;
208: }
209:
210:
211: if ($this->objPaginator) {
212: $this->PageNumber = 1;
213: }
214:
215:
216: if ($objColumn->OrderByClause) {
217:
218:
219:
220: if ($this->strSortColumnId === $strId) {
221:
222:
223:
224: if ($this->intSortDirection == self::SortDescending) {
225:
226: $this->intSortDirection = self::SortAscending;
227: } else {
228:
229: if ($objColumn->ReverseOrderByClause) {
230: $this->intSortDirection = self::SortDescending;
231: }
232: }
233: } else {
234:
235: $this->strSortColumnId = $strId;
236: $this->intSortDirection = self::SortAscending;
237: }
238: } else {
239:
240: $this->intSortDirection = self::SortAscending;
241: $this->strSortColumnId = null;
242: }
243: }
244:
245: 246: 247: 248: 249:
250: protected function GetHeaderRowHtml() {
251: $strToReturn = '';
252: for ($i = 0; $i < $this->intHeaderRowCount; $i++) {
253: $this->intCurrentHeaderRowIndex = $i;
254:
255: $strCells = '';
256: if ($this->objColumnArray) foreach ($this->objColumnArray as $objColumn) {
257:
258: if ($objColumn->Visible) {
259: $strCellValue = $this->GetHeaderCellContent($objColumn);
260: $aParams = $objColumn->GetHeaderCellParams();
261: $aParams['id'] = $objColumn->Id;
262: if ($objColumn->OrderByClause) {
263: if (isset($aParams['class'])) {
264: $aParams['class'] .= ' ' . 'sortable';
265: } else {
266: $aParams['class'] = 'sortable';
267: }
268: }
269: $strCells .= QHtml::RenderTag('th', $aParams, $strCellValue);
270: }
271: }
272: $strToReturn .= QHtml::RenderTag('tr', $this->GetHeaderRowParams(), $strCells);
273: }
274:
275: return $strToReturn;
276: }
277:
278: 279: 280: 281: 282: 283:
284: protected function GetHeaderCellContent($objColumn) {
285: $blnSortable = false;
286: $strCellValue = $objColumn->FetchHeaderCellValue();
287: if ($objColumn->HtmlEntities) {
288: $strCellValue = QApplication::HtmlEntities($strCellValue);
289: }
290:
291: if ($this->strSortColumnId === $objColumn->Id) {
292: if ($this->intSortDirection == self::SortAscending) {
293: $strCellValue = $strCellValue . ' ' . QHtml::RenderTag('i', ['class'=>'fa fa-sort-desc fa-lg']);
294: } else {
295: $strCellValue = $strCellValue . ' ' . QHtml::RenderTag('i', ['class'=>'fa fa-sort-asc fa-lg']);
296: }
297: $blnSortable = true;
298: }
299: else if ($objColumn->OrderByClause) {
300: $strCellValue = $strCellValue . ' ' . QHtml::RenderTag('i', ['class'=>'fa fa-sort fa-lg', 'style'=>'opacity:0.8']);
301: $blnSortable = true;
302: }
303:
304: if ($blnSortable) {
305:
306: $strCellValue = QHtml::RenderTag('div', null, $strCellValue);
307: $strCellValue = QHtml::RenderTag('a', ['href'=>'javascript:;'], $strCellValue);
308: }
309:
310: return $strCellValue;
311: }
312:
313: 314: 315: 316: 317:
318: public function GetEndScript() {
319: $strJS = parent::GetEndScript();
320: QApplication::ExecuteJsFunction('qcubed.datagrid2', $this->ControlId);
321: return $strJS;
322: }
323:
324:
325: 326: 327: 328:
329: public function GetState() {
330: $state = array();
331: if ($this->strSortColumnId !== null) {
332: $state["c"] = $this->strSortColumnId;
333: $state["d"] = $this->intSortDirection;
334: }
335: if ($this->Paginator || $this->PaginatorAlternate) {
336: $state["p"] = $this->PageNumber;
337: }
338: return $state;
339: }
340:
341: 342: 343: 344:
345: public function PutState($state) {
346:
347: if (isset ($state["c"])) {
348: $this->strSortColumnId = $state["c"];
349: }
350: if (isset ($state["d"])) {
351: $this->intSortDirection = $state["d"];
352: if ($this->intSortDirection != self::SortDescending) {
353: $this->intSortDirection = self::SortAscending;
354: }
355: }
356: if (isset ($state["p"]) &&
357: ($this->Paginator || $this->PaginatorAlternate)) {
358: $this->PageNumber = $state["p"];
359: }
360: }
361:
362: 363: 364: 365: 366: 367:
368: public static function GetCodeGenerator($strClass = 'QDataGrid') {
369: return new QDataGrid_CodeGenerator($strClass);
370: }
371:
372: 373: 374: 375: 376: 377:
378: public function GetSortColumnIndex() {
379: if ($this->objColumnArray && ($count = count($this->objColumnArray))) {
380: for($i = 0; $i < $count; $i++) {
381: if ($this->objColumnArray[$i]->Id == $this->SortColumnId) {
382: return $i;
383: }
384: }
385: }
386: return false;
387: }
388:
389: 390: 391: 392: 393: 394: 395: 396:
397: public function GetOrderByInfo() {
398: if ($this->strSortColumnId !== null) {
399: $objColumn = $this->GetColumnById($this->strSortColumnId);
400: if ($objColumn && $objColumn->OrderByClause) {
401: if ($this->intSortDirection == self::SortAscending) {
402: return $objColumn->OrderByClause;
403: }
404: else {
405: if ($objColumn->ReverseOrderByClause) {
406: return $objColumn->ReverseOrderByClause;
407: }
408: else {
409: return $objColumn->OrderByClause;
410: }
411: }
412: }
413: else {
414: return null;
415: }
416: } else {
417: return null;
418: }
419: }
420:
421: 422: 423: 424: 425:
426: public function __get($strName) {
427: switch ($strName) {
428:
429: case "OrderByClause": return $this->GetOrderByInfo();
430:
431: case "SortColumnId": return $this->strSortColumnId;
432: case "SortDirection": return $this->intSortDirection;
433:
434: case "SortColumnIndex": return $this->GetSortColumnIndex();
435:
436: default:
437: try {
438: return parent::__get($strName);
439: } catch (QCallerException $objExc) {
440: $objExc->IncrementOffset();
441: throw $objExc;
442: }
443: }
444: }
445:
446: 447: 448: 449: 450: 451:
452: public function __set($strName, $mixValue) {
453: switch ($strName) {
454: case "SortColumnId":
455: try {
456: $this->strSortColumnId = QType::Cast($mixValue, QType::String);
457: break;
458: } catch (QInvalidCastException $objExc) {
459: $objExc->IncrementOffset();
460: throw $objExc;
461: }
462:
463: case "SortColumnIndex":
464: try {
465: $intIndex = QType::Cast($mixValue, QType::Integer);
466: if ($intIndex < 0) {
467: $intIndex = 0;
468: }
469: if ($intIndex < count($this->objColumnArray)) {
470: $objColumn = $this->objColumnArray[$intIndex];
471: } elseif (count($this->objColumnArray) > 0) {
472: $objColumn = end($this->objColumnArray);
473: } else {
474:
475: $objColumn = null;
476: }
477: if ($objColumn && $objColumn->OrderByClause) {
478: $this->strSortColumnId = $objColumn->Id;
479: }
480: } catch (QInvalidCastException $objExc) {
481: $objExc->IncrementOffset();
482: throw $objExc;
483: }
484: break;
485:
486: case "SortDirection":
487: try {
488: $this->intSortDirection = QType::Cast($mixValue, QType::Integer);
489: if ($this->intSortDirection != self::SortDescending) {
490: $this->intSortDirection = self::SortAscending;
491: }
492: break;
493: } catch (QInvalidCastException $objExc) {
494: $objExc->IncrementOffset();
495: throw $objExc;
496: }
497:
498: default:
499: try {
500: parent::__set($strName, $mixValue);
501: break;
502: } catch (QCallerException $objExc) {
503: $objExc->IncrementOffset();
504: throw $objExc;
505: }
506: }
507: }
508:
509: }