1: <?php
2: /**
3: * This file contains all basic action classes: QAction, QServerAction, QAjaxAction, etc.
4: *
5: * @package Actions
6: * @filesource
7: */
8:
9: /**
10: * Base class for all other Actions.
11: *
12: * @package Actions
13: * @property QEvent $Event Any QEvent derivated class instance
14: */
15: abstract class QAction extends QBaseClass {
16: /**
17: * Abstract method, implemented in derived classes. Returns the JS needed for the action to work
18: *
19: * @param QControl $objControl
20: *
21: * @return mixed
22: */
23: abstract public function RenderScript(QControl $objControl);
24:
25: /** @var QEvent Event object which will fire this action */
26: protected $objEvent;
27:
28: /**
29: * @param QControl|QControlBase $objControl QControl for which the actions have to be rendered
30: * @param string $strEventName Name of the event for which the actions have to be rendered
31: * @param QAction[] $objActions Array of actionss
32: *
33: * @return null|string
34: * @throws Exception
35: */
36: public static function RenderActions(QControl $objControl, $strEventName, $objActions) {
37: $strToReturn = '';
38: $strJqUiProperty = null;
39:
40: if ($objControl->ActionsMustTerminate) {
41: $strToReturn .= ' event.preventDefault();' . _nl();
42: }
43:
44: if ($objActions && count($objActions)) {
45: foreach ($objActions as $objAction) {
46: if ($objAction->objEvent->EventName != $strEventName) {
47: throw new Exception('Invalid Action Event in this entry in the ActionArray');
48: }
49:
50: if ($objAction->objEvent instanceof QJqUiPropertyEvent) {
51: $strJqUiProperty = $objAction->objEvent->JqProperty;
52: }
53:
54: if ($objAction->objEvent->Delay > 0) {
55: $strCode = sprintf(" qcubed.setTimeout('%s', \$j.proxy(function(){%s},this), %s);",
56: $objControl->ControlId,
57: _nl() . _indent(trim($objAction->RenderScript($objControl))) . _nl(),
58: $objAction->objEvent->Delay);
59: } else {
60: $strCode = ' ' . $objAction->RenderScript($objControl);
61: }
62:
63: // Add Condition (if applicable)
64: if (strlen($objAction->objEvent->Condition)) {
65: $strCode = sprintf(' if (%s) {%s}', $objAction->objEvent->Condition, _nl() . _indent(trim($strCode)) . _nl());
66: }
67:
68: $strCode .= _nl();
69:
70: // Append it to the Return Value
71: $strToReturn .= $strCode;
72: }
73: }
74: $strToReturn = _nl() . _indent($strToReturn);
75:
76: if (strlen($strToReturn)) {
77: if ($strJqUiProperty) {
78: $strOut = sprintf('$j("#%s").%s("option", {%s: function(event, ui){%s}});',
79: $objControl->getJqControlId(),
80: $objControl->getJqSetupFunction(),
81: $strJqUiProperty,
82: $strToReturn);
83: } elseif ($objControl instanceof QControlProxy) {
84: if ($objControl->TargetControlId) {
85: // Deprecated.
86: $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->TargetControlId, $strEventName, $strToReturn);
87: } else {
88: $strOut = sprintf('$j("#%s").on("%s", "[data-qpxy=\'%s\']", function(event, ui){%s});', $objControl->Form->FormId, $strEventName, $objControl->ControlId, $strToReturn);
89: }
90: } else {
91: $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});',
92: $objControl->getJqControlId(),
93: $strEventName, $strToReturn);
94:
95: }
96:
97: if (isset($strOut)) {
98: if (!QApplication::$Minimize) {
99: // Render a comment
100: $strOut = _nl() . _nl() .
101: sprintf ('/*** Event: %s Control Type: %s, Control Name: %s, Control Id: %s ***/', $strEventName, get_class($objControl), $objControl->Name, $objControl->ControlId) .
102: _nl() .
103: _indent($strOut) .
104: _nl() . _nl();
105: }
106: return $strOut;
107: }
108: }
109:
110: return null;
111: }
112:
113: /**
114: * PHP Magic function to set the property values of an object of the class
115: * In this case, we only have 'Event' property to be set
116: *
117: * @param string $strName Name of the property
118: * @param string $mixValue Value of the property
119: *
120: * @throws QCallerException
121: * @return mixed|null|string
122: */
123: public function __set($strName, $mixValue) {
124: switch ($strName) {
125: case 'Event':
126: return ($this->objEvent = QType::Cast($mixValue, 'QEvent'));
127:
128: default:
129: try {
130: return parent::__set($strName, $mixValue);
131: } catch (QCallerException $objExc) {
132: $objExc->IncrementOffset();
133: throw $objExc;
134: }
135: }
136: }
137:
138: /**
139: * PHP Magic function to get the property values of an object of the class
140: * In this case, we only have 'Event' property to be set
141: *
142: * @param string $strName Name of the property
143: *
144: * @return mixed|null|string
145: * @throws QCallerException
146: */
147: public function __get($strName) {
148: switch ($strName) {
149: case 'Event':
150: return $this->objEvent;
151: default:
152: try {
153: return parent::__get($strName);
154: } catch (QCallerException $objExc) {
155: $objExc->IncrementOffset();
156: throw $objExc;
157: }
158: }
159: }
160: }
161:
162: /**
163: * Server actions are handled through a full-page postback.
164: *
165: * @package Actions
166: * @property-read string $MethodName Name of the associated action handling method
167: * @property-read mixed $CausesValidationOverride An override for CausesValidation property (if supplied)
168: * @property-read string $JsReturnParam The parameter to be returned
169: * (overrides the Control's ActionParameter)
170: */
171: class QServerAction extends QAction {
172: /** @var string Name of the method in the form to be called */
173: protected $strMethodName;
174: /**
175: * @var mixed A constant from QCausesValidation enumeration class
176: * It is set in the constructor via the corresponding argument
177: */
178: protected $mixCausesValidationOverride;
179: /** @var string An over-ride for the Control's ActionParameter */
180: protected $strJsReturnParam;
181:
182: /**
183: * @param string $strMethodName The method name which is to be assigned as the event handler
184: * (for the event being created)
185: * @param string $mixCausesValidationOverride A constant from QCausesValidation
186: * (or $this or an array of QControls)
187: * @param string $strJsReturnParam The parameter to be returned when this event occurs
188: * (this is an override for the control's ActionParameter)
189: */
190: public function __construct($strMethodName = null, $mixCausesValidationOverride = null,
191: $strJsReturnParam = '') {
192: $this->strMethodName = $strMethodName;
193: $this->mixCausesValidationOverride = $mixCausesValidationOverride;
194: $this->strJsReturnParam = $strJsReturnParam;
195: }
196:
197: /**
198: * PHP Magic function to get the property values of an object of the class
199: *
200: * @param string $strName Name of the property
201: *
202: * @return mixed|null|string
203: * @throws QCallerException
204: */
205: public function __get($strName) {
206: switch ($strName) {
207: case 'MethodName':
208: return $this->strMethodName;
209: case 'CausesValidationOverride':
210: return $this->mixCausesValidationOverride;
211: case 'JsReturnParam':
212: return $this->strJsReturnParam;
213: default:
214: try {
215: return parent::__get($strName);
216: } catch (QCallerException $objExc) {
217: $objExc->IncrementOffset();
218: throw $objExc;
219: }
220: }
221: }
222:
223: /**
224: * Determines the ActionParameter associated with the action and returns it
225: *
226: * @param QControlBase $objControl
227: *
228: * @return string The action parameter
229: */
230: protected function getActionParameter($objControl) {
231: if ($objActionParameter = $this->strJsReturnParam) {
232: return $objActionParameter;
233: }
234: if ($objActionParameter = $this->objEvent->JsReturnParam) {
235: return $objActionParameter;
236: }
237: $objActionParameter = $objControl->ActionParameter;
238: if ($objActionParameter instanceof QJsClosure) {
239: return '(' . $objActionParameter->toJsObject() . ').call(this)';
240: }
241:
242: return "'" . addslashes($objActionParameter) . "'";
243: }
244:
245: /**
246: * Returns the JS which will be called on the client side
247: * which will result in the event handler being called
248: *
249: * @param QControl $objControl
250: *
251: * @return string
252: */
253: public function RenderScript(QControl $objControl) {
254: return sprintf("qc.pB('%s', '%s', '%s', %s);",
255: $objControl->Form->FormId, $objControl->ControlId, get_class($this->objEvent), $this->getActionParameter($objControl));
256: }
257: }
258:
259: /**
260: * The QAjaxAction responds to events with ajax calls, which refresh a portion of a web page without reloading
261: * the entire page. They generally are faster than server requests and give a better user experience.
262: *
263: * The QAjaxAction will associate a callback (strMethodName) with an event as part of an AddAction call. The callback will be
264: * a method in the current QForm object. To associate a method that is part of a QControl, or any kind of a callback,
265: * use a QAjaxControlAction.
266: *
267: * The wait icon is a spinning gif file that can be overlayed on top of the control to show that the control is in
268: * a "loading" state. TODO: Convert this to a FontAwesome animated icon.
269: *
270: * mixCausesValidationOverride allows you to selectively say whether this action causes a validation, and on what subset of controls.
271: *
272: * strJsReturnParam is a javascript string that specifies what the action parameter will be, if you don't want the default.
273: *
274: * blnAsync lets you respond to the event asynchronously. Use care when setting this to true. Normally, qcubed will
275: * put events in a queue and wait for each event to return a result before executing the next event. Most of the time,
276: * the user experience is fine with this. However, there are times when events might be firing quickly and you do
277: * not want to wait. However, your QFormState handler must be able to handle asynchronous events.
278: * The default QFormStateHandler cannot do this, so you will need to use a different one.
279: *
280: * @property-read $MethodName Name of the (event-handler) method to be called
281: * the event handler - function containing the actual code for the Ajax action
282: * @property-read QWaitIcon $WaitIconControl the waiting icon control for this Ajax Action
283: * @property-read mixed $CausesValidationOverride what kind of validation over-ride is to be implemented
284: * on this action.(See the QCausesValidation class and QFormBase class to understand in greater depth)
285: * @property-read string JsReturnParam The line of javascript which would set the 'strParameter' value on the
286: * client-side when the action occurs!
287: * (see /assets/_core/php/examples/other_controls/js_return_param_example.php for example)
288: * @property-read string Id The Ajax Action ID for this action.
289: * @package Actions
290: */
291: class QAjaxAction extends QAction {
292: /** @var string Ajax Action ID */
293: protected $strId;
294: /** @var string The event handler function name */
295: protected $strMethodName;
296: /** @var QWaitIcon Wait Icon to be used for this particular action */
297: protected $objWaitIconControl;
298:
299: protected $blnAsync = false;
300: /**
301: * @var mixed what kind of validation over-ride is to be implemented
302: * (See the QCausesValidation class and QFormBase class to understand in greater depth)
303: */
304: protected $mixCausesValidationOverride;
305: /**
306: * @var string the line of javascript which would set the 'strParameter' value on the
307: * client-side when the action occurs!
308: */
309: protected $strJsReturnParam;
310:
311: /**
312: * AjaxAction constructor.
313: * @param string $strMethodName Name of the event handler function to be called
314: * @param string|QWaitIcon $objWaitIconControl Wait Icon for the action
315: * @param null|mixed $mixCausesValidationOverride what kind of validation over-ride is to be implemented
316: * @param string $strJsReturnParam the line of javascript which would set the 'strParameter' value on the
317: * client-side when the action occurs!
318: * @param boolean $blnAsync True to have the events for this action fire asynchronously.
319: * Be careful when setting this to true. See class description.
320: */
321: public function __construct($strMethodName = null, $objWaitIconControl = 'default',
322: $mixCausesValidationOverride = null, $strJsReturnParam = "", $blnAsync = false) {
323: $this->strId = null;
324: $this->strMethodName = $strMethodName;
325: $this->objWaitIconControl = $objWaitIconControl;
326: $this->mixCausesValidationOverride = $mixCausesValidationOverride;
327: $this->strJsReturnParam = $strJsReturnParam;
328: $this->blnAsync = $blnAsync;
329: }
330:
331: public function __clone() {
332: $this->strId = null; //we are a fresh clone, lets reset the id and get our own later (in RenderScript)
333: }
334:
335: /**
336: * PHP Magic function to get the property values of a class object
337: *
338: * @param string $strName Name of the property
339: *
340: * @return mixed|null|string
341: * @throws QCallerException
342: */
343: public function __get($strName) {
344: switch ($strName) {
345: case 'MethodName':
346: return $this->strMethodName;
347: case 'WaitIconControl':
348: return $this->objWaitIconControl;
349: case 'CausesValidationOverride':
350: return $this->mixCausesValidationOverride;
351: case 'JsReturnParam':
352: return $this->strJsReturnParam;
353: case 'Id':
354: return $this->strId;
355: default:
356: try {
357: return parent::__get($strName);
358: } catch (QCallerException $objExc) {
359: $objExc->IncrementOffset();
360: throw $objExc;
361: }
362: }
363: }
364:
365: /**
366: * Returns the control's ActionParameter in string format
367: *
368: * @param QControl $objControl
369: *
370: * @return string
371: */
372: protected function getActionParameter($objControl) {
373: if ($objActionParameter = $this->strJsReturnParam) {
374: return $objActionParameter;
375: }
376: if ($objActionParameter = $this->objEvent->JsReturnParam) {
377: return $objActionParameter;
378: }
379: $objActionParameter = $objControl->ActionParameter;
380: if ($objActionParameter instanceof QJsClosure) {
381: return '(' . $objActionParameter->toJsObject() . ').call(this)';
382: }
383:
384: return "'" . addslashes($objActionParameter) . "'";
385: }
386:
387: /**
388: * Returns the RenderScript script for the action.
389: * The returned script is to be executed on the client side when the action is executed
390: * (in this case qc.pA function is executed)
391: *
392: * @param QControl $objControl
393: *
394: * @return string
395: */
396: public function RenderScript(QControl $objControl) {
397: $strWaitIconControlId = null;
398: if ($this->strId == null) {
399: $this->strId = $objControl->Form->GenerateAjaxActionId();
400: }
401:
402: if ((gettype($this->objWaitIconControl) == 'string') && ($this->objWaitIconControl == 'default')) {
403: if ($objControl->Form->DefaultWaitIcon) {
404: $strWaitIconControlId = $objControl->Form->DefaultWaitIcon->ControlId;
405: }
406: } else {
407: if ($this->objWaitIconControl) {
408: $strWaitIconControlId = $this->objWaitIconControl->ControlId;
409: }
410: }
411:
412: return sprintf("qc.pA('%s', '%s', '%s#%s', %s, '%s', %s);",
413: $objControl->Form->FormId, $objControl->ControlId, addslashes(get_class($this->objEvent)), $this->strId,
414: $this->getActionParameter($objControl), $strWaitIconControlId, $this->blnAsync ? 'true' : 'false');
415: }
416: }
417:
418: /**
419: * Server control action is identical to server action, except
420: * the handler for it is defined NOT in the form, but in a control.
421: *
422: * @package Actions
423: */
424: class QServerControlAction extends QServerAction {
425: /**
426: * @param QControl $objControl Control where the action handler is defined
427: * @param string $strMethodName Name of the method which acts as the action handler
428: * @param mixed $mixCausesValidationOverride Override for CausesValidation (if needed)
429: * @param string $strJsReturnParam Override for ActionParameter
430: */
431: public function __construct(QControl $objControl, $strMethodName, $mixCausesValidationOverride = null,
432: $strJsReturnParam = "") {
433: parent::__construct($objControl->ControlId . ':' . $strMethodName, $mixCausesValidationOverride, $strJsReturnParam);
434: }
435: }
436:
437: /**
438: * Ajax control action is identical to Ajax action, except
439: * the handler for it is defined NOT on the form host, but on a QControl.
440: *
441: * @package Actions
442: */
443: class QAjaxControlAction extends QAjaxAction {
444: /**
445: * @param QControl $objControl Control where the action handler is defined
446: * @param string $strMethodName Name of the action handler method
447: * @param string $objWaitIconControl The wait icon to be implemented
448: * @param null $mixCausesValidationOverride Override for CausesValidation (if needed)
449: * @param string $strJsReturnParam Override for ActionParameter
450: * @param boolean $blnAsync True to have the events for this action fire asynchronously
451: */
452: public function __construct(QControl $objControl, $strMethodName, $objWaitIconControl = 'default',
453: $mixCausesValidationOverride = null, $strJsReturnParam = "", $blnAsync = false) {
454: parent::__construct($objControl->ControlId . ':' . $strMethodName, $objWaitIconControl, $mixCausesValidationOverride, $strJsReturnParam, $blnAsync);
455: }
456: }
457:
458: /**
459: * Client-side action - no postbacks of any kind are performed.
460: * All handling activity happens in Javascript.
461: *
462: * @package Actions
463: */
464: class QRedirectAction extends QAction {
465: /** @var string JS to be run on the client side */
466: protected $strJavaScript;
467:
468: /**
469: * possible values:
470: * http://google.com
471: * index.php?page=view
472: * /foo/bar/woot.html
473: *
474: * @param string $strUrl
475: */
476: public function __construct($strUrl) {
477: $this->strJavaScript = sprintf("document.location.href ='%s'", trim($strUrl));
478: }
479:
480: /**
481: * PHP Magic function to get the property values of a class object
482: *
483: * @param string $strName Name of the property
484: *
485: * @return mixed|null|string
486: * @throws QCallerException
487: */
488: public function __get($strName) {
489: switch ($strName) {
490: case 'JavaScript':
491: return $this->strJavaScript;
492: default:
493: try {
494: return parent::__get($strName);
495: } catch (QCallerException $objExc) {
496: $objExc->IncrementOffset();
497: throw $objExc;
498: }
499: }
500: }
501:
502: /**
503: * Returns the JS which runs on the client side
504: * @param QControl $objControl
505: *
506: * @return string
507: */
508: public function RenderScript(QControl $objControl) {
509: return sprintf('%s;', $this->strJavaScript);
510: }
511: }
512:
513: /**
514: * Client-side action - no postbacks of any kind are performed.
515: * All handling activity happens in Javascript.
516: *
517: * @package Actions
518: */
519: class QJavaScriptAction extends QAction {
520: /** @var string JS to be run on the client side */
521: protected $strJavaScript;
522:
523: /**
524: * The constructor
525: * @param string $strJavaScript JS which is to be executed on the client side
526: */
527: public function __construct($strJavaScript) {
528: $this->strJavaScript = trim($strJavaScript);
529: if (QString::LastCharacter($this->strJavaScript) == ';') {
530: $this->strJavaScript = substr($this->strJavaScript, 0, strlen($this->strJavaScript) - 1);
531: }
532: }
533:
534: /**
535: * PHP Magic function to get the property values of a class object
536: *
537: * @param string $strName Name of the property
538: *
539: * @return mixed|null|string
540: * @throws QCallerException
541: */
542: public function __get($strName) {
543: switch ($strName) {
544: case 'JavaScript':
545: return $this->strJavaScript;
546: default:
547: try {
548: return parent::__get($strName);
549: } catch (QCallerException $objExc) {
550: $objExc->IncrementOffset();
551: throw $objExc;
552: }
553: }
554: }
555:
556: /**
557: * Returns the JS which will be executed on the client side
558: * @param QControl $objControl
559: *
560: * @return string
561: */
562: public function RenderScript(QControl $objControl) {
563: return sprintf('%s;', $this->strJavaScript);
564: }
565: }
566:
567: /**
568: * This action works as a if-else stopper for another action.
569: * This action should be added to a control with the same event type before another action of that event type
570: * Doing so brings up a JavaScript Confirmation box in front of the user.
571: * If the user clicks on 'OK', then the next next action is executed (and any actions after that as well)
572: * If the user clicks on 'Cancel', then next/rest of the action(s) are not executed
573: * @package Actions
574: */
575: class QConfirmAction extends QAction {
576: /** @var string Message to be shown to the user on the confirmation prompt */
577: protected $strMessage;
578:
579: /**
580: * Constructor of the function
581: * @param string $strMessage Message which is to be set as the confirmation prompt message
582: */
583: public function __construct($strMessage) {
584: $this->strMessage = $strMessage;
585: }
586:
587: /**
588: * PHP Magic function to get the property values of an object of the class
589: *
590: * @param string $strName Name of the property
591: *
592: * @return mixed|null|string
593: * @throws QCallerException
594: */
595: public function __get($strName) {
596: switch ($strName) {
597: case 'Message':
598: return $this->strMessage;
599: default:
600: try {
601: return parent::__get($strName);
602: } catch (QCallerException $objExc) {
603: $objExc->IncrementOffset();
604: throw $objExc;
605: }
606: }
607: }
608:
609: /**
610: * Returns the JS to be executed on the client side
611: * @param QControl $objControl
612: *
613: * @return string The JS to be executed
614: */
615: public function RenderScript(QControl $objControl) {
616: $strMessage = JavaScriptHelper::toJsObject($this->strMessage);
617:
618: return sprintf("if (!confirm(%s)) return false;", $strMessage);
619: }
620: }
621:
622: /**
623: * Displays an alert to the user
624: *
625: * @package Actions
626: */
627: class QAlertAction extends QAction {
628: /** @var string Message to be shown as the alert */
629: protected $strMessage;
630:
631: /**
632: * Constructor
633: *
634: * @param string $strMessage Message to be shown as the alert
635: */
636: public function __construct($strMessage) {
637: $this->strMessage = $strMessage;
638: }
639:
640: /**
641: * PHP Magic function to get the property values of an object of the class
642: *
643: * @param string $strName Name of the property
644: *
645: * @return mixed|null|string
646: * @throws QCallerException
647: */
648: public function __get($strName) {
649: switch ($strName) {
650: case 'Message':
651: return $this->strMessage;
652: default:
653: try {
654: return parent::__get($strName);
655: } catch (QCallerException $objExc) {
656: $objExc->IncrementOffset();
657: throw $objExc;
658: }
659: }
660: }
661:
662: /**
663: * Returns the JavaScript to be executed on the client side
664: *
665: * @param QControl $objControl
666: *
667: * @return string
668: */
669: public function RenderScript(QControl $objControl) {
670: $strMessage = JavaScriptHelper::toJsObject($this->strMessage);
671:
672: return sprintf("alert(%s);", $strMessage);
673: }
674: }
675:
676: /**
677: * @package Actions
678: */
679: class QResetTimerAction extends QAction {
680: /**
681: * Returns the JavaScript to be executed on the client side (to clear the timeout on the control)
682: *
683: * @param QControl $objControl Control on which the timeout has to be cleared
684: *
685: * @return string JavaScript to be executed on the client side
686: */
687: public function RenderScript(QControl $objControl) {
688: return sprintf("qcubed.clearTimeout('%s');", $objControl->ControlId);
689: }
690: }
691:
692: /**
693: * Prevents the default action on an event.
694: *
695: * E.g. If you have a click action added to a label whose text is a link, clicking it will take the action
696: * but also take you to the link pointed by the label. You can add a QTerminateAction after all QClickEvent
697: * handlers and that will make sure that action handlers are triggered but the browser does not navigate
698: * the user to the link pointed by the label
699: *
700: * @package Actions
701: */
702: class QTerminateAction extends QAction {
703: /**
704: * Returns the JS for the browser
705: *
706: * @param QControl $objControl
707: *
708: * @return string JS to prevent the default action
709: */
710: public function RenderScript(QControl $objControl) {
711: return 'event.preventDefault();';
712: }
713: }
714:
715: /**
716: * Prevents the event from bubbling up the DOM tree, preventing any parent
717: * handlers from being notified of the event.
718: *
719: * @package Actions
720: */
721: class QStopPropagationAction extends QAction {
722: /**
723: * Returns the JavaScript to be executed on the client side
724: *
725: * @param QControl $objControl
726: *
727: * @return string Client side JS
728: */
729: public function RenderScript(QControl $objControl) {
730: return 'event.stopPropagation();';
731: }
732: }
733:
734: /**
735: * Toggle the Disaply of a control
736: *
737: * @package Actions
738: */
739: class QToggleDisplayAction extends QAction {
740: /** @var string Control ID of the control */
741: protected $strControlId = null;
742: /** @var boolean|null Enforce 'show' or 'hide' action */
743: protected $blnDisplay = null;
744:
745: /**
746: * @param QControl|QControlBase $objControl
747: * @param bool $blnDisplay
748: *
749: * @throws Exception|QCallerException|QInvalidCastException
750: */
751: public function __construct($objControl, $blnDisplay = null) {
752: if (!($objControl instanceof QControl)) {
753: throw new QCallerException('First parameter of constructor is expecting an object of type QControl');
754: }
755:
756: $this->strControlId = $objControl->ControlId;
757:
758: if (!is_null($blnDisplay)) {
759: $this->blnDisplay = QType::Cast($blnDisplay, QType::Boolean);
760: }
761: }
762:
763: /**
764: * Returns the JavaScript to be executed on the client side
765: *
766: * @param QControl $objControl
767: *
768: * @return string Returns the JavaScript to be executed on the client side
769: */
770: public function RenderScript(QControl $objControl) {
771: if ($this->blnDisplay === true) {
772: $strShowOrHide = 'show';
773: } else {
774: if ($this->blnDisplay === false) {
775: $strShowOrHide = 'hide';
776: } else {
777: $strShowOrHide = '';
778: }
779: }
780:
781: return sprintf("qc.getW('%s').toggleDisplay('%s');",
782: $this->strControlId, $strShowOrHide);
783: }
784: }
785:
786: /**
787: * Toggle the 'enabled' status of a control
788: * NOTE: It does not change the Enabled property on the server side
789: *
790: * @package Actions
791: */
792: class QToggleEnableAction extends QAction {
793: /** @var null|string Control ID of the control to be Enabled/Disabled */
794: protected $strControlId = null;
795: /** @var boolean|null Enforce the Enabling or Disabling action */
796: protected $blnEnabled = null;
797:
798: /**
799: * @param QControl|QControlBase $objControl
800: * @param boolean $blnEnabled
801: *
802: * @throws Exception|QCallerException|QInvalidCastException
803: */
804: public function __construct($objControl, $blnEnabled = null) {
805: if (!($objControl instanceof QControl)) {
806: throw new QCallerException('First parameter of constructor is expecting an object of type QControl');
807: }
808:
809: $this->strControlId = $objControl->ControlId;
810:
811: if (!is_null($blnEnabled)) {
812: $this->blnEnabled = QType::Cast($blnEnabled, QType::Boolean);
813: }
814: }
815:
816: /**
817: * Returns the JavaScript to be executed on the client side
818: *
819: * @param QControl $objControl
820: *
821: * @return string Client side JS
822: */
823: public function RenderScript(QControl $objControl) {
824: if ($this->blnEnabled === true) {
825: $strEnableOrDisable = 'enable';
826: } else {
827: if ($this->blnEnabled === false) {
828: $strEnableOrDisable = 'disable';
829: } else {
830: $strEnableOrDisable = '';
831: }
832: }
833:
834: return sprintf("qc.getW('%s').toggleEnabled('%s');", $this->strControlId, $strEnableOrDisable);
835: }
836: }
837:
838: /**
839: * Registers the click position on a control
840: *
841: * @package Actions
842: */
843: class QRegisterClickPositionAction extends QAction {
844: /** @var null|string Control ID of the control on which the click position has to be registered */
845: protected $strControlId = null;
846:
847: /**
848: * Returns the JavaScript to be executed on the client side
849: *
850: * @param QControl $objControl
851: *
852: * @return string
853: */
854: public function RenderScript(QControl $objControl) {
855: return sprintf("qc.getW('%s').registerClickPosition(event);", $objControl->ControlId);
856: }
857: }
858:
859: /**
860: * Shows a dialog box (QDialogBox)
861: *
862: * @package Actions
863: */
864: class QShowDialogBox extends QAction {
865: /** @var null|string Control ID of the dialog box (QDialogBox) */
866: protected $strControlId = null;
867: /**
868: * @var null|string The Javascript that executes on the client side
869: * For this action, this string contains the JS to show the dialog box
870: */
871: protected $strJavaScript = null;
872:
873: /**
874: * Constructor method
875: *
876: * @param QDialogBox $objControl
877: *
878: * @throws QCallerException
879: */
880: public function __construct($objControl) {
881: if (!($objControl instanceof QDialogBox)) {
882: throw new QCallerException('First parameter of constructor is expecting an object of type QDialogBox');
883: }
884:
885: $this->strControlId = $objControl->ControlId;
886: $this->strJavaScript = $objControl->GetShowDialogJavaScript();
887: }
888:
889: /**
890: * Returns the JavaScript to be executed on the client side
891: *
892: * @param QControl $objControl
893: *
894: * @return string JS to be executed on the client side
895: */
896: public function RenderScript(QControl $objControl) {
897: return (sprintf('%s; qcubed.recordControlModification("%s", "Display", "1");', $this->strJavaScript, $this->strControlId));
898: }
899: }
900:
901: /**
902: * Hides a dialog box (QDialogBox)
903: *
904: * @package Actions
905: */
906: class QHideDialogBox extends QAction {
907: /** @var null|string The JS for hiding the dialog box */
908: protected $strJavaScript = null;
909:
910: /**
911: * Constructor
912: *
913: * @param QDialogBox $objControl
914: *
915: * @throws QCallerException
916: */
917: public function __construct($objControl) {
918: if (!($objControl instanceof QDialogBox)) {
919: throw new QCallerException('First parameter of constructor is expecting an object of type QDialogBox');
920: }
921:
922: $this->strJavaScript = $objControl->GetHideDialogJavaScript();
923: }
924:
925: /**
926: * Returns the JavaScript to be executed on the client side
927: *
928: * @param QControl $objControl
929: *
930: * @return null|string JS to be executed on the client side
931: */
932: public function RenderScript(QControl $objControl) {
933: return $this->strJavaScript;
934: }
935: }
936:
937: /**
938: * Shows a QDialog
939: * This is the JQuery UI alternative to show dialog
940: *
941: * @package Actions
942: */
943: class QShowDialog extends QAction {
944: /** @var null|string The JS to show the dialog */
945: protected $strJavaScript = null;
946:
947: /**
948: * Constructor
949: *
950: * @param QDialog $objControl
951: *
952: * @throws QCallerException
953: */
954: public function __construct($objControl) {
955: if (!($objControl instanceof QDialog)) {
956: throw new QCallerException('First parameter of constructor is expecting an object of type QDialog');
957: }
958:
959: $strControlId = $objControl->getJqControlId();
960: $this->strJavaScript = sprintf('jQuery("#%s").dialog("open");', $strControlId);
961: }
962:
963: /**
964: * Returns the JavaScript to be executed on the client side for opening/showing the dialog
965: *
966: * @param QControl $objControl
967: *
968: * @return null|string JS that will be run on the client side
969: */
970: public function RenderScript(QControl $objControl) {
971: return $this->strJavaScript;
972: }
973: }
974:
975: /**
976: * Hiding a JQuery UI Dialog (QDialog)
977: *
978: * @package Actions
979: */
980: class QHideDialog extends QAction {
981: /** @var null|string JS to be executed on the client side for closing the dialog */
982: protected $strJavaScript = null;
983:
984: /**
985: * Constructor
986: *
987: * @param QDialog $objControl
988: *
989: * @throws QCallerException
990: */
991: public function __construct($objControl) {
992: if (!($objControl instanceof QDialog)) {
993: throw new QCallerException('First parameter of constructor is expecting an object of type QDialog');
994: }
995:
996: $strControlId = $objControl->getJqControlId();
997: $this->strJavaScript = sprintf('jQuery("#%s").dialog("close");', $strControlId);
998: }
999:
1000: /**
1001: * Returns the JavaScript to be executed on the client side
1002: *
1003: * @param QControl $objControl
1004: *
1005: * @return null|string JavaScript to be executed on the client side
1006: */
1007: public function RenderScript(QControl $objControl) {
1008: return $this->strJavaScript;
1009: }
1010: }
1011:
1012: /**
1013: * Puts focus on a Control (on the client side/browser)
1014: * @package Actions
1015: */
1016: class QFocusControlAction extends QAction {
1017: /** @var null|string Control ID of the control on which focus is to be put */
1018: protected $strControlId = null;
1019:
1020: /**
1021: * Constructor
1022: *
1023: * @param QControl $objControl
1024: *
1025: * @throws QCallerException
1026: */
1027: public function __construct($objControl) {
1028: if (!($objControl instanceof QControl)) {
1029: throw new QCallerException('First parameter of constructor is expecting an object of type QControl');
1030: }
1031:
1032: $this->strControlId = $objControl->ControlId;
1033: }
1034:
1035: /**
1036: * Returns the JavaScript to be executed on the client side
1037: *
1038: * @param QControl $objControl
1039: *
1040: * @return string JavaScript to be executed on the client side
1041: */
1042: public function RenderScript(QControl $objControl) {
1043: // for firefox focus is special when in a blur or in a focusout event
1044: // http://stackoverflow.com/questions/7046798/jquery-focus-fails-on-firefox/7046837#7046837
1045: return sprintf("setTimeout(function(){qc.getW('%s').focus();},0);", $this->strControlId);
1046: }
1047: }
1048:
1049: /**
1050: * Blurs (JS blur, not visual blur) a control on server side (i.e. removes focus from that control)
1051: *
1052: * @package Actions
1053: */
1054: class QBlurControlAction extends QAction {
1055: /** @var null|string Control ID of the control from which focus has to be removed */
1056: protected $strControlId = null;
1057:
1058: /**
1059: * Constructor
1060: *
1061: * @param QControl $objControl
1062: *
1063: * @throws QCallerException
1064: */
1065: public function __construct($objControl) {
1066: if (!($objControl instanceof QControl)) {
1067: throw new QCallerException('First parameter of constructor is expecting an object of type QControl');
1068: }
1069:
1070: $this->strControlId = $objControl->ControlId;
1071: }
1072:
1073: /**
1074: * Returns the JavaScript to be executed on the client side
1075: *
1076: * @param QControl $objControl
1077: *
1078: * @return string JavaScript to be executed on the client side
1079: */
1080: public function RenderScript(QControl $objControl) {
1081: return sprintf("qc.getW('%s').blur();", $this->strControlId);
1082: }
1083: }
1084:
1085: /**
1086: * Selects contents inside a QTextBox on the client-side/browser
1087: * @package Actions
1088: */
1089: class QSelectControlAction extends QAction {
1090: /** @var null|string Control ID of the QTextBox which is to be selected */
1091: protected $strControlId = null;
1092:
1093: /**
1094: * Constructor
1095: *
1096: * @param QTextBox $objControl
1097: *
1098: * @throws QCallerException
1099: */
1100: public function __construct($objControl) {
1101: if (!($objControl instanceof QTextBox)) {
1102: throw new QCallerException('First parameter of constructor is expecting an object of type QTextBox');
1103: }
1104:
1105: $this->strControlId = $objControl->ControlId;
1106: }
1107:
1108: /**
1109: * Returns the JavaScript to be executed on the client side
1110: *
1111: * @param QControl $objControl
1112: *
1113: * @return string JavaScript to be executed on the client side
1114: */
1115: public function RenderScript(QControl $objControl) {
1116: return sprintf("qc.getW('%s').select();", $this->strControlId);
1117: }
1118: }
1119:
1120: /**
1121: * Can add or remove an extra CSS class from a control.
1122: * Should be used mostly for temporary purposes such as 'hovering' over a control
1123: *
1124: * @package Actions
1125: */
1126: class QCssClassAction extends QAction {
1127: /** @var null|string The CSS class to be added to the control */
1128: protected $strTemporaryCssClass = null;
1129: /** @var bool Should the CSS class be applied by removing the previous one? */
1130: protected $blnOverride = false;
1131:
1132: /**
1133: * Constructor
1134: *
1135: * @param null|string $strTemporaryCssClass The temporary class to be added to the control
1136: * If null, it will reset the CSS classes to the previous set
1137: * @param bool $blnOverride Should the previously set classes be removed (true) or not (false)
1138: * This will not reset the CSS class on the server side
1139: */
1140: public function __construct($strTemporaryCssClass = null, $blnOverride = false) {
1141: $this->strTemporaryCssClass = $strTemporaryCssClass;
1142: $this->blnOverride = $blnOverride;
1143: }
1144:
1145: /**
1146: * Returns the JavaScript to be executed on the client side
1147: *
1148: * @param QControl $objControl
1149: *
1150: * @return string The JavaScript to be executed on the client side
1151: */
1152: public function RenderScript(QControl $objControl) {
1153: // Specified a Temporary Css Class to use?
1154: if (is_null($this->strTemporaryCssClass)) {
1155: // No Temporary CSS Class -- use the Control's already-defined one
1156: return sprintf("qc.getC('%s').className = '%s';", $objControl->ControlId, $objControl->CssClass);
1157: } else {
1158: // Are we overriding or are we displaying this temporary css class outright?
1159: if ($this->blnOverride) {
1160: // Overriding
1161: return sprintf("qc.getC('%s').className = '%s %s';", $objControl->ControlId, $objControl->CssClass, $this->strTemporaryCssClass);
1162: } else {
1163: // Use Temp Css Class Outright
1164: return sprintf("qc.getC('%s').className = '%s';", $objControl->ControlId, $this->strTemporaryCssClass);
1165: }
1166: }
1167: }
1168: }
1169:
1170:
1171: /**
1172: * Toggles the given class on the objects identified by the given jQuery selector. If no selector given, then
1173: * the trigger control is toggled.
1174: *
1175: * @package Actions
1176: */
1177: class QToggleCssClassAction extends QAction {
1178: protected $strCssClass;
1179: protected $strTargetSelector;
1180:
1181: public function __construct($strCssClass, $strTargetSelector = null) {
1182: $this->strCssClass = $strCssClass;
1183: $this->strTargetSelector = $strTargetSelector;
1184: }
1185:
1186: public function RenderScript(QControl $objControl) {
1187: // Specified a Temporary Css Class to use?
1188: if ($this->strTargetSelector) {
1189: $strSelector = $this->strTargetSelector;
1190: } else {
1191: $strSelector = '#' . $objControl->ControlId;
1192: }
1193: return sprintf("jQuery('%s').toggleClass('%s');", $strSelector, $this->strCssClass);
1194: }
1195: }
1196:
1197:
1198: /**
1199: * Sets the CSS class of a control on the client side (does not update the server side)
1200: *
1201: * @package Actions
1202: */
1203: class QCssAction extends QAction {
1204: /** @var string CSS property to be set */
1205: protected $strCssProperty = null;
1206: /** @var string Value to which the CSS property should be set */
1207: protected $strCssValue = null;
1208: /**
1209: * @var null|string The control ID for which the action should be done.
1210: * By default, it is applied to the QControl to which the action is added.
1211: */
1212: protected $strControlId = null;
1213:
1214: /**
1215: * Constructor
1216: *
1217: * @param string $strCssProperty
1218: * @param string $strCssValue
1219: * @param null|QControl $objControl
1220: */
1221: public function __construct($strCssProperty, $strCssValue, $objControl = null) {
1222: $this->strCssProperty = $strCssProperty;
1223: $this->strCssValue = $strCssValue;
1224: if ($objControl) {
1225: $this->strControlId = $objControl->ControlId;
1226: }
1227: }
1228:
1229: /**
1230: * Returns the JavaScript to be executed on the client side
1231: *
1232: * @param QControl $objControl
1233: *
1234: * @return string JavaScript to be executed on the client side for setting the CSS
1235: */
1236: public function RenderScript(QControl $objControl) {
1237: if ($this->strControlId == null) {
1238: $this->strControlId = $objControl->ControlId;
1239: }
1240:
1241: // Specified a Temporary Css Class to use?
1242: return sprintf('$j("#%s").css("%s", "%s"); ', $this->strControlId, $this->strCssProperty, $this->strCssValue);
1243: }
1244: }
1245:
1246: /**
1247: * Shows a Calendar Control
1248: *
1249: * @package Actions
1250: */
1251: class QShowCalendarAction extends QAction {
1252: /** @var null|string Control ID of the calendar */
1253: protected $strControlId = null;
1254:
1255: /**
1256: * @param QCalendar $calControl
1257: *
1258: * @throws QCallerException
1259: */
1260: public function __construct($calControl) {
1261: if (!($calControl instanceof QCalendar)) {
1262: throw new QCallerException('First parameter of constructor is expecting an object of type QCalendar');
1263: }
1264: $this->strControlId = $calControl->ControlId;
1265: }
1266:
1267: /**
1268: * Returns the JavaScript to be executed on the client side
1269: * @param QControl $objControl
1270: *
1271: * @return string JavaScript to be executed on the client side
1272: */
1273: public function RenderScript(QControl $objControl) {
1274: return sprintf("qc.getC('%s').showCalendar();", $this->strControlId);
1275: }
1276: }
1277:
1278: /**
1279: * Hides a calendar control
1280: *
1281: * @package Actions
1282: */
1283: class QHideCalendarAction extends QAction {
1284: /** @var null|string Control ID of the calendar control */
1285: protected $strControlId = null;
1286:
1287: /**
1288: * Constructor
1289: * @param QCalendar $calControl
1290: *
1291: * @throws QCallerException
1292: */
1293: public function __construct($calControl) {
1294: if (!($calControl instanceof QCalendar)) {
1295: throw new QCallerException('First parameter of constructor is expecting an object of type QCalendar');
1296: }
1297: $this->strControlId = $calControl->ControlId;
1298: }
1299:
1300: /**
1301: * Returns the JavaScript to be executed on the client side
1302: * @param QControl $objControl
1303: *
1304: * @return string JavaScript to be executed on the client side
1305: */
1306: public function RenderScript(QControl $objControl) {
1307: return sprintf("qc.getC('%s').hideCalendar();", $this->strControlId);
1308: }
1309: }
1310:
1311: /**
1312: * Sets the javascript value of a control in the form. The value has to be known ahead of time. Useful for
1313: * automatically clearing a text field when it receives focus, for example.
1314: */
1315: class QSetValueAction extends QAction {
1316: protected $strControlId = null;
1317: protected $strValue = "";
1318:
1319: public function __construct($objControl, $strValue = "") {
1320: $this->strControlId = $objControl->ControlId;
1321: $this->strValue = $strValue;
1322: }
1323:
1324: /**
1325: * @param QControl $objControl
1326: * @return mixed|string
1327: */
1328: public function RenderScript(QControl $objControl) {
1329: return sprintf("jQuery('#%s').val('%s');", $this->strControlId, $this->strValue);
1330: }
1331: }
1332:
1333: