Overview

Packages

  • Actions
  • Codegen
  • Controls
    • Base
  • DatabaseAdapters
  • Events
  • None
  • Sessions
  • Tests

Classes

  • AbstractControl_CodeGenerator
  • AjaxTimingForm
  • BasicForm
  • BasicOrmTests
  • BBCodeParser
  • CacheTests
  • CalculatorForm
  • CalculatorWidget
  • ComplexColumn
  • DataRepeaterExample
  • Event
  • ExampleCheckColumn1
  • ExampleCheckColumn2
  • ExampleForm
  • Examples
  • ExampleService
  • ExamplesForm
  • ExampleSingleForm
  • ExpandAsArrayTests
  • HtmlJqDoc
  • InjectForm
  • JavaScriptHelper
  • JqAttributes
  • JqControlGen
  • JqDoc
  • JqIcon
  • Method
  • ModelConnectorTests
  • MyControl
  • MyQSlider_ChangeEvent
  • NavPanel
  • NestedTabForm
  • Option
  • Order
  • PaginatorForm
  • ParamsForm
  • PersistentExampleForm
  • PersonEditPanel
  • PluginEditForm
  • PluginManagerForm
  • Project
  • ProjectEditPanel
  • ProjectListForm
  • ProjectPickerListBox
  • ProjectViewPanel
  • QAbstractCacheProvider
  • QAbstractHtmlTableColumn
  • QAbstractHtmlTableDataColumn
  • QAccordion
  • QAccordion_ActivateEvent
  • QAccordion_BeforeActivateEvent
  • QAccordion_CreateEvent
  • QAccordionBase
  • QAccordionGen
  • QAction
  • QActionControl
  • QAjaxAction
  • QAjaxControlAction
  • QAjaxResponse
  • QAlertAction
  • QApplication
  • QApplicationBase
  • QArchive
  • QAutocomplete
  • QAutocomplete_ChangeEvent
  • QAutocomplete_CloseEvent
  • QAutocomplete_CodeGenerator
  • QAutocomplete_CreateEvent
  • QAutocomplete_FocusEvent
  • QAutocomplete_OpenEvent
  • QAutocomplete_ResponseEvent
  • QAutocomplete_SearchEvent
  • QAutocomplete_SelectEvent
  • QAutocomplete_SourceEvent
  • QAutocompleteBase
  • QAutocompleteBase_CodeGenerator
  • QAutocompleteGen
  • QAutocompleteListItem
  • QBackspaceKeyEvent
  • QBaseClass
  • QBlockControl
  • QBlurControlAction
  • QBlurEvent
  • QBorderCollapse
  • QBorderStyle
  • QBrowserType
  • QButton
  • QButtonBase
  • QCache
  • QCacheDeleteAction
  • QCacheDeleteAllAction
  • QCacheProviderAPC
  • QCacheProviderLocalMemory
  • QCacheProviderLocalMemoryTest
  • QCacheProviderMemcache
  • QCacheProviderNoCache
  • QCacheProviderProxy
  • QCacheSetAction
  • QCalendar
  • QCalendarType
  • QCallType
  • QCausesValidation
  • QCellClickEvent
  • QChangeEvent
  • QCheckBox
  • QCheckBox_CodeGenerator
  • QCheckBoxBase_CodeGenerator
  • QCheckBoxLegacyColumn
  • QCheckBoxList
  • QCheckBoxList_CodeGenerator
  • QCheckBoxListBase_CodeGenerator
  • QClickEvent
  • QCodeGen
  • QCodeGenBase
  • QConfirmAction
  • QContextMenuEvent
  • QControl
  • QControl_CodeGenerator
  • QControlBase
  • QControlBase_CodeGenerator
  • QControlBaseTests
  • QControlCategoryType
  • QControlGrouping
  • QControlLabel
  • QControlProxy
  • QConvertNotation
  • QConvertNotationBase
  • QCrossScripting
  • QCryptography
  • QCss
  • QCssAction
  • QCssClassAction
  • QCssTests
  • QCsvTextBox
  • QCursor
  • QDatabaseBase
  • QDatabaseCodeGen
  • QDatabaseFieldBase
  • QDatabaseFieldType
  • QDatabaseForeignKey
  • QDatabaseIndex
  • QDatabaseResultBase
  • QDatabaseRowBase
  • QDatabaseTests
  • QDataGrid
  • QDataGrid_CheckBoxColumn
  • QDataGrid_CodeGenerator
  • QDataGrid_SortEvent
  • QDataGridBase
  • QDataGridBase_CodeGenerator
  • QDataGridLegacy
  • QDataGridLegacyBase
  • QDataGridLegacyColumn
  • QDataGridLegacyRow
  • QDataGridLegacyRowStyle
  • QDataRepeater
  • QDatepicker
  • QDatepicker_BeforeShowDayEvent
  • QDatepicker_BeforeShowEvent
  • QDatepicker_CalculateWeekEvent
  • QDatepicker_ChangeMonthYearEvent
  • QDatepicker_CloseEvent
  • QDatepicker_SelectEvent
  • QDatepicker_SelectEvent2
  • QDatepickerBase
  • QDatepickerBox
  • QDatepickerBox_BeforeShowDayEvent
  • QDatepickerBox_BeforeShowEvent
  • QDatepickerBox_CalculateWeekEvent
  • QDatepickerBox_ChangeMonthYearEvent
  • QDatepickerBox_CloseEvent
  • QDatepickerBox_CodeGenerator
  • QDatepickerBox_SelectEvent
  • QDatepickerBoxBase
  • QDatepickerBoxBase_CodeGenerator
  • QDatepickerBoxGen
  • QDatepickerGen
  • QDateTime
  • QDateTimePicker
  • QDateTimePicker_CodeGenerator
  • QDateTimePickerBase_CodeGenerator
  • QDateTimePickerFormat
  • QDateTimePickerType
  • QDateTimeSpan
  • QDateTimeTests
  • QDateTimeTextBox
  • QDbBackedFormStateHandler
  • QDbBackedSessionHandler
  • QDialog
  • QDialog_BeforeCloseEvent
  • QDialog_ButtonEvent
  • QDialog_CloseEvent
  • QDialog_CreateEvent
  • QDialog_DragEvent
  • QDialog_DragStartEvent
  • QDialog_DragStopEvent
  • QDialog_FocusEvent
  • QDialog_OpenEvent
  • QDialog_ResizeEvent
  • QDialog_ResizeStartEvent
  • QDialog_ResizeStopEvent
  • QDialogBase
  • QDialogBox
  • QDialogGen
  • QDisplayStyle
  • QDoubleClickEvent
  • QDownArrowKeyEvent
  • QDragDropEvent
  • QDraggable
  • QDraggable_CreateEvent
  • QDraggable_DragEvent
  • QDraggable_StartEvent
  • QDraggable_StopEvent
  • QDraggableBase
  • QDraggableGen
  • QDroppable
  • QDroppable_ActivateEvent
  • QDroppable_CreateEvent
  • QDroppable_DeactivateEvent
  • QDroppable_DropEvent
  • QDroppable_OutEvent
  • QDroppable_OverEvent
  • QDroppableBase
  • QDroppableGen
  • QDropZoneGrouping
  • QEmailAttachment
  • QEmailMessage
  • QEmailServer
  • QEmailStringAttachment
  • QEmailTextBox
  • QEnterKeyEvent
  • QErrorAttribute
  • QEscapeKeyEvent
  • QEvent
  • QFieldset
  • QFile
  • QFileAsset
  • QFileAssetBase
  • QFileAssetDialog
  • QFileAssetType
  • QFileControl
  • QFileFormStateHandler
  • QFilterType
  • QFloatTextBox
  • QFloatTextBox_CodeGenerator
  • QFloatTextBoxBase_CodeGenerator
  • QFocusControlAction
  • QFocusEvent
  • QFocusInEvent
  • QFocusOutEvent
  • QFolder
  • QFontFamily
  • QForm
  • QFormBase
  • QFormGen
  • QFormStateHandler
  • QGridLines
  • QHideCalendarAction
  • QHideDialog
  • QHideDialogBox
  • QHListControl
  • QHListItem
  • QHorizontalAlign
  • QHtml
  • QHtmlAttributeManager
  • QHtmlAttributeManagerBase
  • QHtmlReporter
  • QHtmlTable
  • QHtmlTable_CodeGenerator
  • QHtmlTableBase
  • QHtmlTableCallableColumn
  • QHtmlTableCheckBoxColumn
  • QHtmlTableCheckBoxColumn_ClickEvent
  • QHtmlTableIndexedColumn
  • QHtmlTableLinkColumn
  • QHtmlTableNodeColumn
  • QHtmlTablePropertyColumn
  • QI18n
  • QI18nTests
  • QImageBase
  • QImageBrowser
  • QImageBrowserBase
  • QImageBrowserNav
  • QImageBrowserThumbnails
  • QImageButton
  • QImageControl
  • QImageControlBase
  • QImageFileAsset
  • QImageLabel
  • QImageLabelBase
  • QImageRollover
  • QImageType
  • QIndex
  • QInformixPdoDatabase
  • QInformixPdoDatabaseField
  • QInformixPdoDatabaseResult
  • QInformixPdoDatabaseRow
  • QInputEvent
  • QInstallationValidationResult
  • QInstallationValidator
  • QIntegerTextBox
  • QIntegerTextBox_CodeGenerator
  • QIntegerTextBoxBase_CodeGenerator
  • QJavaScriptAction
  • QJQAction
  • QJQBounceAction
  • QJqButton
  • QJqButton_CreateEvent
  • QJqButtonBase
  • QJqButtonGen
  • QJqCheckBox
  • QJqCheckBox_CreateEvent
  • QJqCheckBoxBase
  • QJqCheckBoxGen
  • QJQHideAction
  • QJQHideEffectAction
  • QJQHighlightAction
  • QJQPulsateAction
  • QJqRadioButton
  • QJqRadioButton_CreateEvent
  • QJqRadioButtonBase
  • QJqRadioButtonGen
  • QJQShakeAction
  • QJQShowAction
  • QJQShowEffectAction
  • QJQSizeAction
  • QJQToggleAction
  • QJQToggleEffectAction
  • QJQTransferAction
  • QJqUiEvent
  • QJqUiPropertyEvent
  • QJsClosure
  • QJsFunction
  • QJsNoQuoteKey
  • QJsParameterList
  • QJsPriority
  • QJsTimer
  • QJsTimerBase
  • QJsVarName
  • QKeyDownEvent
  • QKeyPressEvent
  • QKeyUpEvent
  • QLabel
  • QLabel_CodeGenerator
  • QLabelBase_CodeGenerator
  • QLexer
  • QLinkButton
  • QListBox
  • QListBox_CodeGenerator
  • QListBoxBase
  • QListBoxBase_CodeGenerator
  • QListControl
  • QListControl_CodeGenerator
  • QListControlBase_CodeGenerator
  • QListItem
  • QListItemBase
  • QListItemStyle
  • QManyToManyReference
  • QMenu
  • QMenu_BlurEvent
  • QMenu_CreateEvent
  • QMenu_FocusEvent
  • QMenu_SelectEvent
  • QMenuBase
  • QMenuGen
  • QMimeType
  • QModelConnectorArgumentType
  • QModelConnectorCreateType
  • QModelConnectorEditDlg
  • QModelConnectorOptions
  • QModelConnectorParam
  • QMouseDownEvent
  • QMouseEnterEvent
  • QMouseLeaveEvent
  • QMouseMoveEvent
  • QMouseOutEvent
  • QMouseOverEvent
  • QMouseUpEvent
  • QMultiLevelCacheProvider
  • QMySqlDatabase
  • QMySqlDatabaseField
  • QMySqlDatabaseResult
  • QMySqli5ClusterDatabase
  • QMySqli5Database
  • QMySqli5DatabaseField
  • QMySqli5DatabaseResult
  • QMySqliDatabase
  • QMySqliDatabaseField
  • QMySqliDatabaseResult
  • QMySqliDatabaseRow
  • QNoScriptAjaxAction
  • QNumericTextBox
  • QOnEvent
  • QOracleDatabase
  • QOracleDatabaseField
  • QOracleDatabaseResult
  • QOracleDatabaseRow
  • QOrderedListType
  • QOverflow
  • QPaginatedControl
  • QPaginator
  • QPaginatorBase
  • QPanel
  • QPartialQueryBuilder
  • QPdoDatabase
  • QPdoDatabaseResult
  • QPgConditionILike
  • QPgConditionJsonContains
  • QPgQ
  • QPosition
  • QPostgreSqlDatabase
  • QPostgreSqlDatabaseField
  • QPostgreSqlDatabaseResult
  • QPostgreSqlDatabaseRow
  • QPostgreSqlPdoDatabase
  • QPostgreSqlPdoDatabaseField
  • QPostgreSqlPdoDatabaseResult
  • QPostgreSqlPdoDatabaseRow
  • QProgressbar
  • QProgressbar_ChangeEvent
  • QProgressbar_CompleteEvent
  • QProgressbar_CreateEvent
  • QProgressbarBase
  • QProgressbarGen
  • QQ
  • QQAggregationClause
  • QQAliasTests
  • QQAssociationNode
  • QQAverage
  • QQClause
  • QQColumnNode
  • QQCondition
  • QQConditionAll
  • QQConditionAnd
  • QQConditionBetween
  • QQConditionComparison
  • QQConditionEqual
  • QQConditionExists
  • QQConditionGreaterOrEqual
  • QQConditionGreaterThan
  • QQConditionIn
  • QQConditionIsNotNull
  • QQConditionIsNull
  • QQConditionLessOrEqual
  • QQConditionLessThan
  • QQConditionLike
  • QQConditionLogical
  • QQConditionNone
  • QQConditionNot
  • QQConditionNotBetween
  • QQConditionNotEqual
  • QQConditionNotExists
  • QQConditionNotIn
  • QQConditionNotLike
  • QQConditionOr
  • QQCount
  • QQDistinct
  • QQExpand
  • QQExpandAsArray
  • QQExpandVirtualNode
  • QQFuncTests
  • QQFunctionNode
  • QQGroupBy
  • QQHavingClause
  • QQLimitInfo
  • QQMathNode
  • QQMathOpTests
  • QQMaximum
  • QQMinimum
  • QQNamedValue
  • QQNode
  • QQNoParentNode
  • QQOrderBy
  • QQReverseReferenceNode
  • QQSelect
  • QQSubQueryCountNode
  • QQSubQueryNode
  • QQSubQuerySqlNode
  • QQSum
  • QQTableNode
  • QQuery
  • QQueryBuilder
  • QQueryExpansion
  • QQVirtualNode
  • QRadioButton
  • QRadioButtonList
  • QRadioButtonList_CodeGenerator
  • QRadioButtonListBase_CodeGenerator
  • QRedirectAction
  • QReference
  • QRegex
  • QRegisterClickPositionAction
  • QRepeatDirection
  • QRequestMode
  • QResetTimerAction
  • QResizable
  • QResizable_CreateEvent
  • QResizable_ResizeEvent
  • QResizable_StartEvent
  • QResizable_StopEvent
  • QResizableBase
  • QResizableGen
  • QResizeHandleDirection
  • QRestServiceCodeGen
  • QReverseReference
  • QRssCategory
  • QRssFeed
  • QRssImage
  • QRssItem
  • QSampleControl
  • QSampleTranslation
  • QSelectable
  • QSelectable_CreateEvent
  • QSelectable_SelectedEvent
  • QSelectable_SelectingEvent
  • QSelectable_StartEvent
  • QSelectable_StopEvent
  • QSelectable_UnselectedEvent
  • QSelectable_UnselectingEvent
  • QSelectableBase
  • QSelectableGen
  • QSelectControlAction
  • QSelectEvent
  • QSelectionMode
  • QSelectMenu
  • QSelectMenu_ChangeEvent
  • QSelectMenu_CloseEvent
  • QSelectMenu_CreateEvent
  • QSelectMenu_FocusEvent
  • QSelectMenu_OpenEvent
  • QSelectMenu_SelectEvent
  • QSelectMenuBase
  • QSelectMenuGen
  • QServerAction
  • QServerControlAction
  • QSessionFormStateHandler
  • QSetValueAction
  • QShowCalendarAction
  • QShowDialog
  • QShowDialogBox
  • QSlider
  • QSlider_ChangeEvent
  • QSlider_CodeGenerator
  • QSlider_CreateEvent
  • QSlider_SlideEvent
  • QSlider_StartEvent
  • QSlider_StopEvent
  • QSliderBase
  • QSliderBase_CodeGenerator
  • QSliderGen
  • QSoapMethod
  • QSoapParameter
  • QSoapService
  • QSortable
  • QSortable_ActivateEvent
  • QSortable_BeforeStopEvent
  • QSortable_ChangeEvent
  • QSortable_CreateEvent
  • QSortable_DeactivateEvent
  • QSortable_OutEvent
  • QSortable_OverEvent
  • QSortable_ReceiveEvent
  • QSortable_RemoveEvent
  • QSortable_SortEvent
  • QSortable_StartEvent
  • QSortable_StopEvent
  • QSortable_UpdateEvent
  • QSortableBase
  • QSortableGen
  • QSpinner
  • QSpinner_ChangeEvent
  • QSpinner_CreateEvent
  • QSpinner_SpinEvent
  • QSpinner_StartEvent
  • QSpinner_StopEvent
  • QSpinnerBase
  • QSpinnerGen
  • QSqlColumn
  • QSqLite3PdoDatabase
  • QSqLite3PdoDatabaseField
  • QSqLite3PdoDatabaseResult
  • QSqLite3PdoDatabaseRow
  • QSqlServer2005Database
  • QSqlServer2005DatabaseField
  • QSqlServer2005DatabaseResult
  • QSqlServer2005DatabaseRow
  • QSqlServerDatabase
  • QSqlServerDatabaseField
  • QSqlServerDatabaseResult
  • QSqlServerDatabaseRow
  • QSqlTable
  • QStack
  • QStopPropagationAction
  • QString
  • QStringTest
  • QTabKeyEvent
  • QTabs
  • QTabs_ActivateEvent
  • QTabs_BeforeActivateEvent
  • QTabs_BeforeLoadEvent
  • QTabs_CreateEvent
  • QTabs_LoadEvent
  • QTabsBase
  • QTabsGen
  • QTag
  • QTagStyler
  • QTerminateAction
  • QTestControl
  • QTestForm
  • QTextAlign
  • QTextBox
  • QTextBox_CodeGenerator
  • QTextBoxBase
  • QTextBoxBase_CodeGenerator
  • QTextMode
  • QTimer
  • QTimerExpiredEvent
  • QTimerTests
  • QToggleCssClassAction
  • QToggleDisplayAction
  • QToggleEnableAction
  • QTranslationPoParser
  • QTreeNav
  • QTreeNavItem
  • QType
  • QTypeTable
  • QTypeTests
  • QUnitTestCaseBase
  • QUnorderedListStyle
  • QUpArrowKeyEvent
  • QUrlTextBox
  • QVerticalAlign
  • QVirtualAttributeColumn
  • QWaitIcon
  • QWatcher
  • QWatcherBase
  • QWatcherCache
  • QWatcherDB
  • QWatcherNone
  • QWriteBox
  • RecordsSummary
  • RefreshForm
  • SampleComposite
  • SampleForm
  • SelectableLabel
  • SelectForm
  • SpeedForm
  • TestImageBrowser
  • UrlForm

Interfaces

  • ICacheAction
  • QDataList_CodeGenerator_Interface
  • QTranslationBase

Traits

  • QDataBinder
  • QListItemManager
  • QModelTrait

Exceptions

  • QCallerException
  • QCrossScriptingException
  • QCryptographyException
  • QDatabaseExceptionBase
  • QDataBindException
  • QDateTimeNullException
  • QEmailException
  • QIndexOutOfRangeException
  • QInformixPdoDatabaseException
  • QInvalidCastException
  • QInvalidFormStateException
  • QMySqliDatabaseException
  • QOptimisticLockingException
  • QOracleDatabaseException
  • QPdoDatabaseException
  • QPoParserException
  • QPostgreSqlDatabaseException
  • QPostgreSqlPdoDatabaseException
  • QRemoteAdminDeniedException
  • QSqLite3PdoDatabaseException
  • QSqlServer2005DatabaseException
  • QSqlServerDatabaseException
  • QUndefinedMethodException
  • QUndefinedPrimaryKeyException
  • QUndefinedPropertyException

Functions

  • __database_check_error
  • __QForm_EvaluateTemplate_ObHandler
  • _b
  • _indent
  • _nl
  • _p
  • _r
  • _t
  • _tp
  • _tr
  • array_trim
  • beginsWith
  • CamelCaseFromDash
  • CastToInt
  • DataGridEvalHandleError
  • DisplayMonospacedText
  • endsWith
  • GO_BACK
  • jq_anytime_gen
  • jq_control_gen
  • jq_inc_gen
  • jq_indent
  • PrintExplainStatement
  • PrintInstructions
  • QcubedHandleCodeGenParseError
  • QcubedHandleError
  • QcubedHandleException
  • QCubedShutdown
  • QDateTimeErrorHandler
  • trimOffEnd
  • trimOffFront
  • Overview
  • Package
  • Class
   1: <?php
   2:     /**
   3:      * This file contains the QFormBase class.
   4:      *
   5:      * @package Controls
   6:      * @filesource
   7:      */
   8: 
   9:     /**
  10:      * @package Controls
  11:      * @property-read string     $FormId              Form ID of the QForm
  12:      * @property-read string     $CallType            Type of call (useful when the QForm submits due to user action)
  13:      * @property-read QWaitIcon  $DefaultWaitIcon     Default Ajax wait icon control
  14:      * @property-read integer    $FormStatus          Status of form (pre-render stage, rendering stage of already rendered stage)
  15:      * @property string          $HtmlIncludeFilePath (Alternate) path to the template file to be used
  16:      * @property string          $CssClass            Form CSS class.
  17:      */
  18:     abstract class QFormBase extends QBaseClass {
  19:         ///////////////////////////
  20:         // Static Members
  21:         ///////////////////////////
  22:         /** @var bool True when css scripts get rendered on page. Lets user call RenderStyles in header. */
  23:         protected static $blnStylesRendered = false;
  24: 
  25:         ///////////////////////////
  26:         // Protected Member Variables
  27:         ///////////////////////////
  28:         /** @var string Form ID (usually passed as the first argument to the 'Run' method call) */
  29:         protected $strFormId;
  30:         /** @var integer representational integer value of what state the form currently is in */
  31:         protected $intFormStatus;
  32:         /** @var QControl[] Array of QControls with this form as the parent */
  33:         protected $objControlArray;
  34:         /**
  35:          * @var QControlGrouping List of Groupings in the form (for old drag and drop)
  36:          * Use of this is deprecated in favor of jQueryUI drag and drop, but code remains in case we need it again.
  37:          * @deprecated
  38:          */
  39:         protected $objGroupingArray;
  40:         /** @var bool Has the body tag already been rendered? */
  41:         protected $blnRenderedBodyTag = false;
  42:         protected $checkableControlValues = array();
  43:         /** @var string The type of call made to the QForm (Ajax, Server or Fresh GET request) */
  44:         protected $strCallType;
  45:         /** @var null|QWaitIcon Default wait icon for the page/QForm  */
  46:         protected $objDefaultWaitIcon = null;
  47: 
  48:         protected $strFormAttributeArray = array();
  49: 
  50:         /** @var array List of included JavaScript files for this QForm */
  51:         protected $strIncludedJavaScriptFileArray = array();
  52:         /** @var array List of ignored JavaScript files for this QForm */
  53:         protected $strIgnoreJavaScriptFileArray = array();
  54: 
  55:         /** @var array List of included CSS files for this QForm */
  56:         protected $strIncludedStyleSheetFileArray = array();
  57:         /** @var array List of ignored CSS files for this QForm */
  58:         protected $strIgnoreStyleSheetFileArray = array();
  59: 
  60:         protected $strPreviousRequestMode = false;
  61:         /**
  62:          * @var string The QForm's template file path.
  63:          * When this value is not supplied, the 'Run' function will try to find and use the
  64:          * .tpl.php file with the same filename as the QForm in the same same directory as the QForm file.
  65:          */
  66:         protected $strHtmlIncludeFilePath;
  67:         /** @var string CSS class to be set for the 'form' tag when QCubed Renders the QForm */
  68:         protected $strCssClass;
  69: 
  70:         protected $strCustomAttributeArray = null;
  71: 
  72:         ///////////////////////////
  73:         // Form Status Constants
  74:         ///////////////////////////
  75:         /** Form has not started rendering */
  76:         const FormStatusUnrendered = 1;
  77:         /** Form has started rendering but has not finished */
  78:         const FormStatusRenderBegun = 2;
  79:         /** Form rendering has already been started and finished */
  80:         const FormStatusRenderEnded = 3;
  81: 
  82:         ///////////////////////////
  83:         // Form Preferences
  84:         ///////////////////////////
  85:         /**
  86:          * @var null|string The key to encrypt the formstate
  87:          *              when saving and retrieving from the chosen FormState handler
  88:          */
  89:         public static $EncryptionKey = null;
  90:         /**
  91:          * @var string Chosen FormStateHandler
  92:          *              default is QFormStateHandler as shown here,
  93:          *              however it is read from the configuration.inc.php (in the QForm class)
  94:          *              In case something goes wrong with QForm, the default FormStateHandler here will
  95:          *              try to take care of the situation.
  96:          */
  97:         public static $FormStateHandler = 'QFormStateHandler';
  98: 
  99:         /////////////////////////
 100:         // Public Properties: GET
 101:         /////////////////////////
 102:         /**
 103:          * PHP magic method for getting property values of object
 104:          * @param string $strName Name of the propery
 105:          *
 106:          * @return int|mixed|null|string
 107:          * @throws QCallerException
 108:          */
 109:         public function __get($strName) {
 110:             switch ($strName) {
 111:                 case "FormId": return $this->strFormId;
 112:                 case "CallType": return $this->strCallType;
 113:                 case "DefaultWaitIcon": return $this->objDefaultWaitIcon;
 114:                 case "FormStatus": return $this->intFormStatus;
 115:                 case "HtmlIncludeFilePath": return $this->strHtmlIncludeFilePath;
 116:                 case "CssClass": return $this->strCssClass;
 117: 
 118:                 default:
 119:                     try {
 120:                         return parent::__get($strName);
 121:                     } catch (QCallerException $objExc) {
 122:                         $objExc->IncrementOffset();
 123:                         throw $objExc;
 124:                     }
 125:             }
 126:         }
 127: 
 128:         /////////////////////////
 129:         // Public Properties: SET
 130:         /////////////////////////
 131:         /**
 132:          * PHP magic function to set the value of properties of class object
 133:          * @param string $strName Name of the property
 134:          * @param string $mixValue Value of the property
 135:          *
 136:          * @return mixed|string
 137:          * @throws QCallerException
 138:          */
 139:         public function __set($strName, $mixValue) {
 140:             switch ($strName) {
 141:                 case "HtmlIncludeFilePath":
 142:                     // Passed-in value is null -- use the "default" path name of file".tpl.php"
 143:                     if (!$mixValue) {
 144:                         $strPath = realpath(substr(QApplication::$ScriptFilename, 0, strrpos(QApplication::$ScriptFilename, '.php')) . '.tpl.php');
 145:                         if ($strPath === false) {
 146:                             // Look again based on the object name
 147:                             $strPath = realpath(get_class($this) . '.tpl.php');
 148:                         }
 149:                     }
 150: 
 151:                     // Use passed-in value
 152:                     else
 153:                         $strPath = realpath($mixValue);
 154: 
 155:                     // Verify File Exists, and if not, throw exception
 156:                     if (is_file($strPath)) {
 157:                         $this->strHtmlIncludeFilePath = $strPath;
 158:                         return $strPath;
 159:                     } else
 160:                         throw new QCallerException('Accompanying HTML Include File does not exist: "' . $mixValue . '"');
 161:                     break;
 162: 
 163:                 case "CssClass":
 164:                     try {
 165:                         return ($this->strCssClass = QType::Cast($mixValue, QType::String));
 166:                     } catch (QCallerException $objExc) {
 167:                         $objExc->IncrementOffset();
 168:                         throw $objExc;
 169:                     }
 170: 
 171:                 default:
 172:                     try {
 173:                         return parent::__set($strName, $mixValue);
 174:                     } catch (QCallerException $objExc) {
 175:                         $objExc->IncrementOffset();
 176:                         throw $objExc;
 177:                     }
 178:             }
 179:         }
 180: 
 181: 
 182:         /////////////////////////
 183:         // Helpers for ControlId Generation
 184:         /////////////////////////
 185: 
 186:         /**
 187:          * Generates Control ID used to keep track of those QControls whose ID was not explicitly set.
 188:          * It uses the counter variable to maintain uniqueness for Control IDs during the life of the page
 189:          * Life of the page is untill the time when the formstate expired and is removed by the
 190:          * garbage collection of the formstate handler
 191:          * @return string the Ajax Action ID
 192:          */
 193:         public function GenerateControlId() {
 194: //          $strToReturn = sprintf('control%s', $this->intNextControlId);
 195:             $strToReturn = sprintf('c%s', $this->intNextControlId);
 196:             $this->intNextControlId++;
 197:             return $strToReturn;
 198:         }
 199:         /**
 200:          * @var int Counter variable to contain the numerical part of the Control ID value.
 201:          *      it is automatically incremented everytime the GenerateControlId() runs
 202:          */
 203:         protected $intNextControlId = 1;
 204: 
 205:         /////////////////////////
 206:         // Helpers for AjaxActionId Generation
 207:         /////////////////////////
 208:         /**
 209:          * Generates Ajax Action ID used to keep track of Ajax Actions
 210:          * It uses the counter variable to maintain uniqueness for Ajax Action IDs during the life of the page
 211:          * Life of the page is untill the time when the formstate expired and is removed by the
 212:          * garbage collection of the formstate handler
 213:          * @return string the Ajax Action ID
 214:          */
 215:         public function GenerateAjaxActionId() {
 216:             $strToReturn = sprintf('a%s', $this->intNextAjaxActionId);
 217:             $this->intNextAjaxActionId++;
 218:             return $strToReturn;
 219:         }
 220: 
 221:         /**
 222:          * @var int Counter variable to contain the numerical part of the AJAX ID value.
 223:          *      it is automatically incremented everytime the GenerateAjaxActionId() runs
 224:          */
 225:         protected $intNextAjaxActionId = 1;
 226: 
 227:         /////////////////////////
 228:         // Event Handlers
 229:         /////////////////////////
 230:         /**
 231:          * Custom Form Run code.
 232:          * To contain code which should be run 'AFTER' QCubed's QForm run has been completed
 233:          * but 'BEFORE' the custom event handlers are called
 234:          * (In case it is to be used, it should be overriden by a child class)
 235:          */
 236:         protected function Form_Run() {}
 237: 
 238:         /**
 239:          * To contain the code which should be executed after the Form Run and
 240:          * before the custom handlers are called (In case it is to be used, it should be overridden by a child class)
 241:          * In this situation, we are about to process an event, or the user has reloaded the page. Do whatever you
 242:          * need to do before any event processing.
 243:          */
 244:         protected function Form_Load() {}
 245: 
 246:         /**
 247:          * To contain the code to initialize the QForm on the first call.
 248:          * Once the QForm is created, the state is saved and is reused by the Run method.
 249:          * In short - this function will run only once (the first time the QForm is to be created)
 250:          * (In case it is to be used, it should be overriden by a child class)
 251:          */
 252:         protected function Form_Create() {}
 253: 
 254:         /**
 255:          * To contain the code to be executed after Form_Run, Form_Create, Form_Load has been called
 256:          * and the custom defined event handlers have been executed but actual rendering process has not begun.
 257:          * This is a good place to put data into a session variable that you need to send to
 258:          * other forms.
 259:          */
 260:         protected function Form_PreRender() {}
 261: 
 262:         /**
 263:          * Override this method to set data in your form controls. Appropriate things to do would be to:
 264:          * - Respond to options sent by _GET or _POST variables.
 265:          * - Load data into the control from the database
 266:          * - Initialize controls whose data depends on the state or data in other controls.
 267:          *
 268:          * When this is called, the controls will have been created by Form_Create, and will have already read their saved state.
 269:          *
 270:          */
 271:         protected function Form_Initialize() {}
 272: 
 273:         /**
 274:          * The Form_Validate method.
 275:          *
 276:          * Before we get here, all the controls will first be validated. Override this method to do
 277:          * additional form level validation, and any form level actions needed as part of the validation process,
 278:          * like displaying an error message.
 279:          *
 280:          * This is the last thing called in the validation process, and will always be called if
 281:          * validation is requested, even if prior controls caused a validation error. Return false to prevent
 282:          * validation and cancel the current action.
 283:          *
 284:          * $blnValid will contain the result of control validation. If it is false, you know that validation will
 285:          * fail, regardless of what you return from the function.
 286:          *
 287:          * @return bool     Return false to prevent validation.
 288:          */
 289:         protected function Form_Validate() {return true;}
 290: 
 291:         /**
 292:          * If you want to respond in some way to an invalid form that you have not already been able to handle,
 293:          * override this function. For example, you could display a message that an error occurred with some of the
 294:          * controls.
 295:          */
 296:         protected function Form_Invalid() {}
 297: 
 298:         /**
 299:          * This function is meant to be overriden by child class and is called when the Form exits
 300:          * (After the form render is complete and just before the Run function completes execution)
 301:          */
 302:         protected function Form_Exit() {}
 303: 
 304: 
 305:         /**
 306:          * VarExport the Controls or var_export the current QForm
 307:          * (well, be ready for huge amount of text)
 308:          * @param bool $blnReturn
 309:          *
 310:          * @return mixed
 311:          */
 312:         public function VarExport($blnReturn = true) {
 313:             if ($this->objControlArray) foreach ($this->objControlArray as $objControl)
 314:                 $objControl->VarExport(false);
 315:             if ($blnReturn) {
 316:                 return var_export($this, true);
 317:             }
 318:             else {
 319:                 return null;
 320:             }
 321:         }
 322: 
 323:         /**
 324:          * Returns the value of a checkable control. Checkable controls are special, in that the browser only tells us
 325:          * when a control is checked, not when it is unchecked. So, unless we keep track of them specially, we will
 326:          * not know if they are unchecked, or just not there.
 327:          * @param $strControlId
 328:          * @return mixed|null
 329:          */
 330:         public function CheckableControlValue($strControlId) {
 331:             if (array_key_exists($strControlId, $this->checkableControlValues)) {
 332:                 return $this->checkableControlValues[$strControlId];
 333:             }
 334:             return null;
 335:         }
 336: 
 337: 
 338:         /**
 339:          * Helper function for below GetModifiedControls
 340:          * @param QControl $objControl
 341:          * @return boolean
 342:          */
 343:         protected static function IsControlModified ($objControl) {
 344:             return $objControl->IsModified();
 345:         }
 346:         /**
 347:          * Return only the controls that have been modified
 348:          */
 349:         public function GetModifiedControls() {
 350:             $ret = array_filter ($this->objControlArray, 'QForm::IsControlModified');
 351:             return $ret;
 352:         }
 353: 
 354:         /**
 355:          * This method initializes the actual layout of the form
 356:          * It runs in all cases including initial form (the time when Form_Create is run) as well as on
 357:          * trigger actions (QServerAction, QAjaxAction, QServerControlAction and QAjaxControlAction)
 358:          *
 359:          * It is responsible for implementing the logic and sequence in which page wide checks are done
 360:          * such as running Form_Validate and Control validations for every control of the page and their
 361:          * child controls. Checking for an existing FormState and loading them before trigerring any action
 362:          * is also a responsibility of this method.
 363:          * @param string $strFormClass The class of the form to create when creating a new form.
 364:          * @param string|null $strAlternateHtmlFile location of the alternate HTML template file.
 365:          * @param string|null $strFormId The html id to use for the form. If null, $strFormClass will be used.
 366:          *
 367:          * @throws QCallerException
 368:          * @throws QInvalidFormStateException
 369:          * @throws Exception
 370:          */
 371:         public static function Run($strFormClass, $strAlternateHtmlFile = null, $strFormId = null) {
 372:             // See if we can get a Form Class out of PostData
 373:             $objClass = null;
 374:             if ($strFormId === null) {
 375:                 $strFormId = $strFormClass;
 376:             }
 377:             if (array_key_exists('Qform__FormId', $_POST) && ($_POST['Qform__FormId'] == $strFormId) && array_key_exists('Qform__FormState', $_POST)) {
 378:                 $strPostDataState = $_POST['Qform__FormState'];
 379: 
 380:                 if ($strPostDataState)
 381:                     // We might have a valid form state -- let's see by unserializing this object
 382:                     $objClass = QForm::Unserialize($strPostDataState);
 383: 
 384:                 // If there is no QForm Class, then we have an Invalid Form State
 385:                 if (!$objClass) {
 386:                     self::InvalidFormState();
 387:                 }
 388:             }
 389:             
 390:             if ($objClass) {
 391:                 // Globalize
 392:                 global $_FORM;
 393:                 $_FORM = $objClass;
 394: 
 395:                 $objClass->strCallType = $_POST['Qform__FormCallType'];
 396:                 $objClass->intFormStatus = QFormBase::FormStatusUnrendered;
 397: 
 398:                 if ($objClass->strCallType == QCallType::Ajax) {
 399:                     QApplication::$RequestMode = QRequestMode::Ajax;
 400:                 }
 401: 
 402:                 // Cleanup ajax post data if the encoding does not match, since ajax data is always utf-8
 403:                 if ($objClass->strCallType == QCallType::Ajax && QApplication::$EncodingType != 'UTF-8') {
 404:                     foreach ($_POST as $key=>$val) {
 405:                         if (substr($key, 0, 6) != 'Qform_') {
 406:                             $_POST[$key] = iconv('UTF-8', QApplication::$EncodingType, $val);
 407:                         }
 408:                     }
 409:                 }
 410: 
 411:                 if (!empty($_POST['Qform__FormParameter'])) {
 412:                     $_POST['Qform__FormParameter'] = self::UnpackPostVar($_POST['Qform__FormParameter']);
 413:                 }
 414: 
 415:                 // Decode custom post variables from server calls
 416:                 if (!empty($_POST['Qform__AdditionalPostVars'])) {
 417:                     $val = self::UnpackPostVar($_POST['Qform__AdditionalPostVars']);
 418:                     $_POST = array_merge($_POST, $val);
 419:                 }
 420: 
 421:                 // Iterate through all the control modifications
 422:                 if (!empty($_POST['Qform__FormUpdates'])) {
 423:                     $controlUpdates = $_POST['Qform__FormUpdates'];
 424:                     if (is_string($controlUpdates)) {    // Server post is encoded, ajax not encoded
 425:                         $controlUpdates = self::UnpackPostVar($controlUpdates);
 426:                     }
 427:                     if (!empty($controlUpdates)) {
 428:                         foreach ($controlUpdates as $strControlId=>$params) {
 429:                             foreach ($params as $strProperty=>$strValue) {
 430:                                 switch ($strProperty) {
 431:                                     case 'Parent':
 432:                                         if ($strValue) {
 433:                                             if ($strValue == $objClass->FormId) {
 434:                                                 $objClass->objControlArray[$strControlId]->SetParentControl(null);
 435:                                             } else {
 436:                                                 $objClass->objControlArray[$strControlId]->SetParentControl($objClass->objControlArray[$strValue]);
 437:                                             }
 438:                                         } else {
 439:                                             // Remove all parents
 440:                                             $objClass->objControlArray[$strControlId]->SetParentControl(null);
 441:                                             $objClass->objControlArray[$strControlId]->SetForm(null);
 442:                                             $objClass->objControlArray[$strControlId] = null;
 443:                                             unset($objClass->objControlArray[$strControlId]);
 444:                                         }
 445:                                         break;
 446:                                     default:
 447:                                         if (array_key_exists($strControlId, $objClass->objControlArray))
 448:                                             $objClass->objControlArray[$strControlId]->__set($strProperty, $strValue);
 449:                                         break;
 450: 
 451:                                 }
 452:                             }
 453:                         }
 454:                     }
 455:                 }
 456: 
 457: 
 458:                 // Set the RenderedCheckableControlArray
 459:                 if (!empty($_POST['Qform__FormCheckableControls'])) {
 460:                     $vals = $_POST['Qform__FormCheckableControls'];
 461:                     if (is_string($vals)) { // Server post is encoded, ajax not encoded
 462:                         $vals = self::UnpackPostVar($vals);
 463:                     }
 464:                     $objClass->checkableControlValues = $vals;
 465:                 } else {
 466:                     $objClass->checkableControlValues = [];
 467:                 }
 468: 
 469:                 // This is original code. In an effort to minimize changes,
 470:                 // we aren't going to touch the server calls for now
 471:                 if ($objClass->strCallType != QCallType::Ajax) {
 472:                     foreach ($objClass->objControlArray as $objControl) {
 473:                         // If they were rendered last time and are visible 
 474:                         // (and if ServerAction, enabled), then Parse its post data
 475:                         if (($objControl->Visible) &&
 476:                             ($objControl->Enabled) &&
 477:                             ($objControl->RenderMethod)) {
 478:                             // Call each control's ParsePostData()
 479:                             $objControl->ParsePostData();
 480:                         }
 481: 
 482:                         // Reset the modified/rendered flags and the validation
 483:                         // in ALL controls
 484:                         $objControl->ResetFlags();
 485:                     }
 486:                 }
 487:                 else {
 488:                     // Ajax post. Only send data to controls specified in the post to save time.
 489: 
 490:                     $previouslyFoundArray = array();
 491:                     $controls = $_POST;
 492:                     $controls = array_merge($controls, $objClass->checkableControlValues);
 493:                     foreach ($controls as $key=>$val) {
 494:                         if ($key == 'Qform__FormControl') {
 495:                             $strControlId = $val;
 496:                         } elseif (substr($key, 0, 6) == 'Qform_') {
 497:                             continue;   // ignore this form data
 498:                         } else {
 499:                             $strControlId = $key;
 500:                         }
 501:                         if (($intOffset = strpos ($strControlId, '_')) !== false) { // the first break is the control id
 502:                             $strControlId = substr ($strControlId, 0, $intOffset);
 503:                         }
 504:                         if (($objControl = $objClass->GetControl($strControlId)) &&
 505:                                 !isset($previouslyFoundArray[$strControlId])) {
 506:                             if (($objControl->Visible) &&
 507:                                 ($objControl->RenderMethod)) {
 508:                                 // Call each control's ParsePostData()
 509:                                 $objControl->ParsePostData();
 510:                             }
 511: 
 512:                             $previouslyFoundArray[$strControlId] = true;
 513:                         }
 514:                     }
 515:                 }
 516: 
 517:                 // Only if our action is validating, we are going to reset the validation state of all the controls
 518:                 if (isset($_POST['Qform__FormControl']) && isset($objClass->objControlArray[$_POST['Qform__FormControl']])) {
 519:                     $objControl = $objClass->objControlArray[$_POST['Qform__FormControl']];
 520:                     if ($objControl->CausesValidation) {
 521:                         $objClass->ResetValidationStates();
 522:                     }
 523:                 }
 524: 
 525:                 // Trigger Run Event (if applicable)
 526:                 $objClass->Form_Run();
 527: 
 528:                 // Trigger Load Event (if applicable)
 529:                 $objClass->Form_Load();
 530: 
 531:                 // Trigger a triggered control's Server- or Ajax- action (e.g. PHP method) here (if applicable)
 532:                 $objClass->TriggerActions();
 533: 
 534:             } else {
 535:                 // We have no form state -- Create Brand New One
 536:                 $objClass = new $strFormClass();
 537: 
 538:                 // Globalize
 539:                 global $_FORM;
 540:                 $_FORM = $objClass;
 541: 
 542:                 // Setup HTML Include File Path, based on passed-in strAlternateHtmlFile (if any)
 543:                 try {
 544:                     $objClass->HtmlIncludeFilePath = $strAlternateHtmlFile;
 545:                 } catch (QCallerException $objExc) {
 546:                     $objExc->IncrementOffset();
 547:                     throw $objExc;
 548:                 }
 549: 
 550:                 // By default, this form is being created NOT via a PostBack
 551:                 // So there is no CallType
 552:                 $objClass->strCallType = QCallType::None;
 553: 
 554:                 $objClass->strFormId = $strFormId;
 555:                 $objClass->intFormStatus = QFormBase::FormStatusUnrendered;
 556:                 $objClass->objControlArray = array();
 557:                 $objClass->objGroupingArray = array();
 558: 
 559:                 // Trigger Run Event (if applicable)
 560:                 $objClass->Form_Run();
 561: 
 562:                 // Trigger Create Event (if applicable)
 563:                 $objClass->Form_Create();
 564: 
 565:                 $objClass->Form_Initialize();
 566: 
 567:                 if (defined ('__DESIGN_MODE__') && __DESIGN_MODE__ == 1) {
 568:                     // Attach custom event to dialog to handle right click menu items sent by form
 569: 
 570:                     $dlg = new QModelConnectorEditDlg ($objClass, 'qconnectoreditdlg');
 571: 
 572:                     $dlg->AddAction (
 573:                         new QOnEvent('qdesignerclick'),
 574:                         new QAjaxAction ('ctlDesigner_Click', null, null, 'ui')
 575:                     );
 576:                 }
 577: 
 578:             }
 579: 
 580:             // Trigger PreRender Event (if applicable)
 581:             $objClass->Form_PreRender();
 582: 
 583:             // Render the Page
 584:             switch ($objClass->strCallType) {
 585:                 case QCallType::Ajax:
 586:                     // Must use AJAX-based renderer
 587:                     $objClass->RenderAjax();
 588:                     break;
 589: 
 590:                 case QCallType::Server:
 591:                 case QCallType::None:
 592:                 case '':
 593:                     // Server/Postback or New Page
 594:                     // Make sure all controls are marked as not being on the page yet
 595:                     foreach ($objClass->objControlArray as $objControl)
 596:                         $objControl->ResetOnPageStatus();
 597: 
 598:                     // Use Standard Rendering
 599:                     $objClass->Render();
 600: 
 601:                     // Ensure that RenderEnd() was called during the Render process
 602:                     switch ($objClass->intFormStatus) {
 603:                         case QFormBase::FormStatusUnrendered:
 604:                             throw new QCallerException('$this->RenderBegin() is never called in the HTML Include file');
 605:                         case QFormBase::FormStatusRenderBegun:
 606:                             throw new QCallerException('$this->RenderEnd() is never called in the HTML Include file');
 607:                         case QFormBase::FormStatusRenderEnded:
 608:                             break;
 609:                         default:
 610:                             throw new QCallerException('FormStatus is in an unknown status');
 611:                     }
 612:                 break;
 613: 
 614:                 default:
 615:                     throw new Exception('Unknown Form CallType: ' . $objClass->strCallType);
 616:             }
 617: 
 618:             // Once all the controls have been set up, and initialized, remember them.
 619:             $objClass->SaveControlState();
 620: 
 621:             // Tigger Exit Event (if applicable)
 622:             $objClass->Form_Exit();
 623:         }
 624: 
 625:         /**
 626:          * Unpacks a post variable that has been encoded with JSON.stringify.
 627:          *
 628:          * @param $val
 629:          * @return mixed|string
 630:          */
 631:         protected static function UnpackPostVar($val) {
 632:             if (QApplication::$EncodingType != 'UTF-8' && QApplication::$RequestMode != QRequestMode::Ajax) {
 633:                 // json_decode only accepts utf-8 encoded text. Ajax calls are already UTF-8 encoded.
 634:                 $val = iconv(QApplication::$EncodingType, 'UTF-8', $val);
 635:             }
 636:             $val = json_decode($val, true);
 637:             if (QApplication::$EncodingType != 'UTF-8') {
 638:                 // Must convert back from utf-8 to whatever our application encoding is
 639:                 if (is_string($val)) {
 640:                     $val = iconv('UTF-8', QApplication::$EncodingType, $val);
 641:                 }
 642:                 elseif (is_array($val)) {
 643:                     array_walk_recursive($val, function(&$v, $key) {
 644:                         if (is_string($v)) {
 645:                             $v = iconv('UTF-8', QApplication::$EncodingType, $v);
 646:                         }
 647:                     });
 648:                 }
 649:                 else {
 650:                     throw new Exception ('Unknown Post Var Type');
 651:                 }
 652:             }
 653:             return $val;
 654:         }
 655: 
 656:         /**
 657:          * Reset all validation states.
 658:          */
 659:         public function ResetValidationStates() {
 660:             foreach ($this->objControlArray as $objControl) {
 661:                 $objControl->ValidationReset();
 662:             }
 663:         }
 664: 
 665:         /**
 666:          * Private function to respond to a designer click.
 667:          *
 668:          * @param $strFormId
 669:          * @param $strControlId
 670:          * @param $mixParam
 671:          */
 672:         private function ctlDesigner_Click ($strFormId, $strControlId, $mixParam) {
 673:             if (isset($mixParam['id'])) {
 674:                 $controlId = $mixParam['id'];
 675:                 if (strpos($controlId, '_')) {  // extra the real control id from a sub id
 676:                     $controlId = substr($controlId, 0, strpos($controlId, '_'));
 677:                 }
 678:             }
 679:             elseif (isset($mixParam['for'])) {
 680:                 $controlId = $mixParam['for'];
 681:             }
 682:             if (!empty($controlId)) {
 683:                 $objControl = $this->GetControl($controlId);
 684:                 if ($objControl) {
 685:                     $dlg = $this->GetControl ('qconnectoreditdlg');
 686:                     $dlg->EditControl ($objControl);
 687:                 }
 688:             }
 689:         }
 690: 
 691:         /**
 692:          * An invalid form state was found. 
 693:          * We were handed a formstate, but the formstate could not be interpreted. This could be for
 694:          * a variety of reasons, and is dependent on the formstate handler. Most likely, the user hit
 695:          * the back button past the back button limit of what we remember, or the user lost the session.
 696:          * Or, you simply have not set up the form state handler correctly.
 697:          * In the past, we threw an exception, but that was not a very user friendly response. 
 698:          * The response below resubmits the url without a formstate so that a new one will be created. 
 699:          * Override if you want a different response.
 700:          */
 701:         public static function InvalidFormState() {
 702:             //ob_clean();
 703:             if (isset($_POST['Qform__FormCallType']) &&  $_POST['Qform__FormCallType'] == QCallType::Ajax) {
 704:                 QApplication::$ProcessOutput = false;
 705:                 QApplication::SendAjaxResponse(['loc' => 'reload']);
 706:             } else {
 707:                 header('Location: '. QApplication::$RequestUri);
 708:             }
 709: 
 710:             // End the Response Script
 711:             exit(); 
 712:         }
 713: 
 714:         /**
 715:          * Calls a data binder associated with the form. Does this so data binder can be protected. Mostly for legacy code.
 716:          * @param callable $callable
 717:          * @param  QControl $objPaginatedControl
 718:          * @throws QDataBindException
 719:          */
 720:         public function CallDataBinder($callable, $objPaginatedControl) {
 721:             try {
 722:                 call_user_func($callable, $objPaginatedControl);
 723:             } catch (QCallerException $objExc) {
 724:                 throw new QDataBindException($objExc);
 725:             }
 726:         }
 727: 
 728:         /**
 729:          * Renders the AjaxHelper for the QForm
 730:          * @param QControlBase $objControl
 731:          *
 732:          * @return string The Ajax helper string (should be JS commands)
 733:          */
 734:         protected function RenderAjaxHelper($objControl) {
 735:             $controls = [];
 736: 
 737:             if ($objControl) {
 738:                 $controls = array_merge($controls, $objControl->RenderAjax());  // will return an array of controls to be merged with current controls
 739:                 foreach ($objControl->GetChildControls() as $objChildControl) {
 740:                     $controls = array_merge($controls, $this->RenderAjaxHelper($objChildControl));
 741:                 }
 742:             }
 743: 
 744:             return $controls;
 745:         }
 746: 
 747:         /**
 748:          * Renders the actual ajax return value as a json object. Since json must be UTF-8 encoded, will convert to
 749:          * UTF-8 if needed. Response is parsed in the "success" function in qcubed.js, and handled there.
 750:          */
 751:         protected function RenderAjax() {
 752:             $aResponse = array();
 753: 
 754:             if (QApplication::$JavascriptExclusiveCommand) {
 755:                 /**
 756:                  * Processing of the actions has resulted in a very high priority exclusive response. This would typically
 757:                  * happen when a javascript widget is requesting data from us. We want to respond as quickly as possible,
 758:                  * and also prevent possibly redrawing the widget while its already in the middle of its own drawing.
 759:                  * We short-circuit the drawing process here.
 760:                  */
 761: 
 762:                 $aResponse = QApplication::GetJavascriptCommandArray();
 763:                 $strFormState = QForm::Serialize($this);
 764:                 $aResponse[QAjaxResponse::Controls][] = [QAjaxResponse::Id=>"Qform__FormState", QAjaxResponse::Value=>$strFormState];   // bring it back next time
 765:                 ob_clean();
 766:                 QApplication::SendAjaxResponse($aResponse);
 767:                 return;
 768:             }
 769: 
 770:             // Update the Status
 771:             $this->intFormStatus = QFormBase::FormStatusRenderBegun;
 772: 
 773:             // Broadcast the watcher change to other windows listening
 774:             if (QWatcher::WatchersChanged()) {
 775:                 $aResponse[QAjaxResponse::Watcher] = true;
 776:             }
 777: 
 778:             // Recursively render changed controls, starting with all top-level controls
 779:             $controls = array();
 780:             foreach ($this->GetAllControls() as $objControl) {
 781:                 if (!$objControl->ParentControl) {
 782:                     $controls = array_merge($controls, $this->RenderAjaxHelper($objControl));
 783:                 }
 784:             }
 785:             $aResponse[QAjaxResponse::Controls] = $controls;
 786: 
 787:             // Go through all controls and gather up any JS or CSS to run or Form Attributes to modify
 788:             foreach ($this->GetAllControls() as $objControl) {
 789:                 // Include any javascript files that were added by the control
 790:                 // Note: current implementation does not handle removal of javascript files
 791:                 if ($strScriptArray = $this->ProcessJavaScriptList($objControl->JavaScripts)) {
 792:                     QApplication::AddJavaScriptFiles($strScriptArray);
 793:                 }
 794: 
 795:                 // Include any new stylesheets
 796:                 if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) {
 797:                     QApplication::AddStyleSheets(array_keys($strScriptArray));
 798:                 }
 799: 
 800:                 // Form Attributes?
 801:                 if ($objControl->FormAttributes) {
 802:                     QApplication::ExecuteControlCommand($this->strFormId, 'attr', $objControl->FormAttributes);
 803:                     foreach ($objControl->FormAttributes as $strKey=>$strValue) {
 804:                         if (!array_key_exists($strKey, $this->strFormAttributeArray)) {
 805:                             $this->strFormAttributeArray[$strKey] = $strValue;
 806:                         } else if ($this->strFormAttributeArray[$strKey] != $strValue) {
 807:                             $this->strFormAttributeArray[$strKey] = $strValue;
 808:                         }
 809:                     }
 810:                 }
 811:             }
 812: 
 813:             $strControlIdToRegister = array();
 814:             foreach ($this->GetAllControls() as $objControl) {
 815:                 $strScript = '';
 816:                 if ($objControl->Rendered) { // whole control was rendered during this event
 817:                     $strScript = trim ($objControl->GetEndScript());
 818:                     $strControlIdToRegister[] = $objControl->ControlId;
 819:                 } else {
 820:                     $objControl->RenderAttributeScripts(); // render one-time attribute commands only
 821:                 }
 822:                 if ($strScript) {
 823:                     QApplication::ExecuteJavaScript($strScript, QJsPriority::High); // put these last in the high priority queue, just before getting the commands below
 824:                 }
 825:                 $objControl->ResetFlags();
 826:             }
 827: 
 828:             if ($strControlIdToRegister) {
 829:                 $aResponse[QAjaxResponse::RegC] = $strControlIdToRegister;
 830:             }
 831: 
 832: 
 833:             foreach ($this->objGroupingArray as $objGrouping) {
 834:                 $strRender = $objGrouping->Render();
 835:                 if (trim($strRender))
 836:                     QApplication::ExecuteJavaScript($strRender, QJsPriority::High);
 837:             }
 838: 
 839: 
 840:             $aResponse = array_merge($aResponse, QApplication::GetJavascriptCommandArray());
 841: 
 842:             // Add in the form state
 843:             $strFormState = QForm::Serialize($this);
 844:             $aResponse[QAjaxResponse::Controls][] = [QAjaxResponse::Id=>"Qform__FormState", QAjaxResponse::Value=>$strFormState];
 845: 
 846:             $strContents = trim(ob_get_contents());
 847: 
 848:             if (strtolower(substr($strContents, 0, 5)) == 'debug') {
 849:                 // TODO: Output debugging information.
 850:             } else {
 851:                 ob_clean();
 852: 
 853:                 QApplication::SendAjaxResponse($aResponse);
 854:             }
 855: 
 856:             // Update Render State
 857:             $this->intFormStatus = QFormBase::FormStatusRenderEnded;
 858:         }
 859: 
 860:         /**
 861:          * Saves the formstate using the 'Save' method of FormStateHandler set in configuration.inc.php
 862:          * @param QForm $objForm
 863:          *
 864:          * @return string the Serialized QForm
 865:          */
 866:         public static function Serialize(QForm $objForm) {
 867:             // Get and then Update PreviousRequestMode
 868:             $strPreviousRequestMode = $objForm->strPreviousRequestMode;
 869:             $objForm->strPreviousRequestMode = QApplication::$RequestMode;
 870: 
 871:             // Figure Out if we need to store state for back-button purposes
 872:             $blnBackButtonFlag = true;
 873:             if ($strPreviousRequestMode == QRequestMode::Ajax)
 874:                 $blnBackButtonFlag = false;
 875: 
 876:             // Create a Clone of the Form to Serialize
 877:             $objForm = clone($objForm);
 878: 
 879:             // Cleanup internal links between controls and the form
 880:             if ($objForm->objControlArray) foreach ($objForm->objControlArray as $objControl) {
 881:                 $objControl->Sleep();
 882:             }
 883: 
 884:             // Use PHP "serialize" to serialize the form
 885:             $strSerializedForm = serialize($objForm);
 886: 
 887:             // Setup and Call the FormStateHandler to retrieve the PostDataState to return
 888:             $strFormStateHandler = QForm::$FormStateHandler;
 889:             $strPostDataState = $strFormStateHandler::Save ($strSerializedForm, $blnBackButtonFlag);
 890: 
 891:             // Return the PostDataState
 892:             return $strPostDataState;
 893:         }
 894: 
 895:         /**
 896:          * Unserializes (extracts) the FormState using the 'Load' method of FormStateHandler set in configuration.inc.php
 897:          * @param string $strPostDataState The string identifying the FormState to the loaded for Unserialization
 898:          *
 899:          * @internal param string $strSerializedForm
 900:          * @return QForm the Form object
 901:          */
 902:         public static function Unserialize($strPostDataState) {
 903:             // Setup and Call the FormStateHandler to retrieve the Serialized Form
 904:             $strFormStateHandler = QForm::$FormStateHandler;
 905:             $strSerializedForm = $strFormStateHandler::Load ($strPostDataState);
 906: 
 907:             if ($strSerializedForm) {
 908:                 // Unserialize and Cast the Form
 909:                 // For the QSessionFormStateHandler the __PHP_Incomplete_Class occurs sometimes
 910:                 // for the result of the unserialize call.
 911:                 $objForm = unserialize($strSerializedForm);
 912:                 $objForm = QType::Cast($objForm, 'QForm');
 913: 
 914:                 // Reset the links from Control->Form
 915:                 if ($objForm->objControlArray) foreach ($objForm->objControlArray as $objControl) {
 916:                     // If you are having trouble with a __PHP_Incomplete_Class here, it means you are not including the definitions
 917:                     // of your own controls in the form.
 918:                     $objControl->Wakeup($objForm);
 919:                 }
 920: 
 921:                 // Return the Form
 922:                 return $objForm;
 923:             } else
 924:                 return null;
 925:         }
 926: 
 927:         /**
 928:          * Add a QControl to the current QForm.
 929:          * @param QControl|QControlBase $objControl
 930:          *
 931:          * @throws QCallerException
 932:          */
 933:         public function AddControl(QControl $objControl) {
 934:             $strControlId = $objControl->ControlId;
 935:             $objControl->MarkAsModified(); // make sure new controls get drawn
 936:             if (array_key_exists($strControlId, $this->objControlArray))
 937:                 throw new QCallerException(sprintf('A control already exists in the form with the ID: %s', $strControlId));
 938:             if (array_key_exists($strControlId, $this->objGroupingArray))
 939:                 throw new QCallerException(sprintf('A Grouping already exists in the form with the ID: %s', $strControlId));
 940:             $this->objControlArray[$strControlId] = $objControl;
 941:         }
 942: 
 943:         /**
 944:          * Returns a control from the current QForm
 945:          * @param string $strControlId The Control ID of the control which is needed to be fetched
 946:          *               from the current QForm (should be the child of the current QForm).
 947:          *
 948:          * @return null|QControl
 949:          */
 950:         public function GetControl($strControlId) {
 951:             if (isset($this->objControlArray[$strControlId])) {
 952:                 return $this->objControlArray[$strControlId];
 953:             }
 954:             else {
 955:                 return null;
 956:             }
 957:         }
 958: 
 959:         /**
 960:          * Removes a QControl (and its children) from the current QForm
 961:          * @param string $strControlId
 962:          */
 963:         public function RemoveControl($strControlId) {
 964:             if (isset($this->objControlArray[$strControlId])) {
 965:                 // Get the Control in Question
 966:                 $objControl = $this->objControlArray[$strControlId];
 967: 
 968:                 // Remove all Child Controls as well
 969:                 $objControl->RemoveChildControls(true);
 970: 
 971:                 // Remove this control from the parent
 972:                 if ($objControl->ParentControl)
 973:                     $objControl->ParentControl->RemoveChildControl($strControlId, false);
 974: 
 975:                 // Remove this control
 976:                 unset($this->objControlArray[$strControlId]);
 977: 
 978:                 // Remove this control from any groups
 979:                 foreach ($this->objGroupingArray as $strKey => $objGrouping)
 980:                     $this->objGroupingArray[$strKey]->RemoveControl($strControlId);
 981:             }
 982:         }
 983: 
 984:         /**
 985:          * Returns all controls belonging to the Form as an array.
 986:          * @return mixed|QControl[]
 987:          */
 988:         public function GetAllControls() {
 989:             return $this->objControlArray;
 990:         }
 991: 
 992:         /**
 993:          * Tell all the controls to save their state.
 994:          */
 995:         public function SaveControlState() {
 996:             // tell the controls to save their state
 997:             $a = $this->GetAllControls();
 998:             foreach ($a as $control) {
 999:                 $control->_WriteState();
1000:             }
1001:         }
1002: 
1003:         /**
1004:          * Tell all the controls to read their state.
1005:          */
1006:         protected function RestoreControlState() {
1007:             // tell the controls to restore their state
1008:             $a = $this->GetAllControls();
1009:             foreach ($a as $control) {
1010:                 $control->_ReadState();
1011:             }
1012:         }
1013: 
1014: 
1015:         /**
1016:          * Custom Attributes are other html name-value pairs that can be rendered within the form using this method.
1017:          * For example, you can now render the autocomplete tag on the QForm
1018:          * additional javascript actions, etc.
1019:          *      $this->SetCustomAttribute("autocomplete", "off");
1020:          * Will render:
1021:          *          [form ...... autocomplete="off"] (replace sqare brackets with angle brackets)
1022:          * @param string $strName Name of the attribute
1023:          * @param string $strValue Value of the attribute
1024:          *
1025:          * @throws QCallerException
1026:          */
1027:         public function SetCustomAttribute($strName, $strValue) {
1028:             if ($strName == "method" || $strName == "action")
1029:                 throw new QCallerException(sprintf("Custom Attribute not supported through SetCustomAttribute(): %s", $strName));
1030: 
1031:             if (!is_null($strValue))
1032:                 $this->strCustomAttributeArray[$strName] = $strValue;
1033:             else {
1034:                 $this->strCustomAttributeArray[$strName] = null;
1035:                 unset($this->strCustomAttributeArray[$strName]);
1036:             }
1037:         }
1038: 
1039:         /**
1040:          * Returns the requested custom attribute from the form.
1041:          * This attribute must have already been set.
1042:          * @param string $strName Name of the Custom Attribute
1043:          *
1044:          * @return mixed
1045:          * @throws QCallerException
1046:          */
1047:         public function GetCustomAttribute($strName) {
1048:             if ((is_array($this->strCustomAttributeArray)) && (array_key_exists($strName, $this->strCustomAttributeArray)))
1049:                 return $this->strCustomAttributeArray[$strName];
1050:             else
1051:                 throw new QCallerException(sprintf("Custom Attribute does not exist in Form: %s", $strName));
1052:         }
1053: 
1054:         public function RemoveCustomAttribute($strName) {
1055:             if ((is_array($this->strCustomAttributeArray)) && (array_key_exists($strName, $this->strCustomAttributeArray))) {
1056:                 $this->strCustomAttributeArray[$strName] = null;
1057:                 unset($this->strCustomAttributeArray[$strName]);
1058:             } else
1059:                 throw new QCallerException(sprintf("Custom Attribute does not exist in Form: %s", $strName));
1060:         }
1061: 
1062: 
1063:         public function AddGrouping(QControlGrouping $objGrouping) {
1064:             $strGroupingId = $objGrouping->GroupingId;
1065:             if (array_key_exists($strGroupingId, $this->objGroupingArray))
1066:                 throw new QCallerException(sprintf('A Grouping already exists in the form with the ID: %s', $strGroupingId));
1067:             if (array_key_exists($strGroupingId, $this->objControlArray))
1068:                 throw new QCallerException(sprintf('A Control already exists in the form with the ID: %s', $strGroupingId));
1069:             $this->objGroupingArray[$strGroupingId] = $objGrouping;
1070:         }
1071: 
1072:         public function GetGrouping($strGroupingId) {
1073:             if (array_key_exists($strGroupingId, $this->objGroupingArray))
1074:                 return $this->objGroupingArray[$strGroupingId];
1075:             else
1076:                 return null;
1077:         }
1078: 
1079:         public function RemoveGrouping($strGroupingId) {
1080:             if (array_key_exists($strGroupingId, $this->objGroupingArray)) {
1081:                 // Remove this Grouping
1082:                 unset($this->objGroupingArray[$strGroupingId]);
1083:             }
1084:         }
1085: 
1086:         /**
1087:          * Retruns the Groupings
1088:          * @return mixed
1089:          */
1090:         public function GetAllGroupings() {
1091:             return $this->objGroupingArray;
1092:         }
1093: 
1094:         /**
1095:          * Returns the child controls of the current QForm or a QControl object
1096:          *
1097:          * @param QForm|QControl|QFormBase $objParentObject The object whose child controls are to be searched for
1098:          *
1099:          * @throws QCallerException
1100:          * @return QControl[]
1101:          */
1102:         public function GetChildControls($objParentObject) {
1103:             $objControlArrayToReturn = array();
1104: 
1105:             if ($objParentObject instanceof QForm) {
1106:                 // They want all the ChildControls for this Form
1107:                 // Basically, return all objControlArray QControls where the Qcontrol's parent is NULL
1108:                 foreach ($this->objControlArray as $objChildControl) {
1109:                     if (!($objChildControl->ParentControl))
1110:                         array_push($objControlArrayToReturn, $objChildControl);
1111:                 }
1112:                 return $objControlArrayToReturn;
1113: 
1114:             } else if ($objParentObject instanceof QControl) {
1115:                 return $objParentObject->GetChildControls();
1116:                 // THey want all the ChildControls for a specific Control
1117:                 // Basically, return all objControlArray QControls where the Qcontrol's parent is the passed in parentobject
1118:                 /*              $strControlId = $objParentObject->ControlId;
1119:                                 foreach ($this->objControlArray as $objChildControl) {
1120:                                     $objParentControl = $objChildControl->ParentControl;
1121:                                     if (($objParentControl) && ($objParentControl->ControlId == $strControlId)) {
1122:                                         array_push($objControlArrayToReturn, $objChildControl);
1123:                                     }
1124:                                 }*/
1125: 
1126:             } else
1127:                 throw new QCallerException('ParentObject must be either a QForm or QControl object');
1128:         }
1129: 
1130:         /**
1131:          * This function evaluates the QForm Template.
1132:          * It will try to open the Template file specified in the call to 'Run' method for the QForm
1133:          * and then execute it.
1134:          * @param string $strTemplate Path to the HTML template file
1135:          *
1136:          * @return string The evaluated HTML string
1137:          */
1138:         public function EvaluateTemplate($strTemplate) {
1139:             global $_ITEM;
1140:             global $_CONTROL;
1141:             global $_FORM;
1142: 
1143:             if ($strTemplate) {
1144:                 QApplication::$ProcessOutput = false;
1145:                 // Store the Output Buffer locally
1146:                 $strAlreadyRendered = ob_get_contents();
1147:                 if ($strAlreadyRendered) {
1148:                     ob_clean();
1149:                 }
1150: 
1151:                 // Evaluate the new template
1152:                 ob_start('__QForm_EvaluateTemplate_ObHandler');
1153:                 require($strTemplate);
1154:                 $strTemplateEvaluated = ob_get_contents();
1155:                 ob_end_clean();
1156: 
1157:                 // Restore the output buffer and return evaluated template
1158:                 if ($strAlreadyRendered) {
1159:                     print($strAlreadyRendered);
1160:                 }
1161:                 QApplication::$ProcessOutput = true;
1162: 
1163:                 return $strTemplateEvaluated;
1164:             } else
1165:                 return null;
1166:         }
1167: 
1168:         /**
1169:          * Triggers an event handler method for a given control ID
1170:          * NOTE: Parameters must be already validated and are guaranteed to exist.
1171:          *
1172:          * @param string $strControlId  Control ID triggering the method
1173:          * @param string $strMethodName Method name which has to be fired. Includes a control id if a control action.
1174:          * @param QAction $objAction The action object which caused the event
1175:          */
1176:         protected function TriggerMethod($strControlId, $strMethodName, QAction $objAction) {
1177:             $mixParameter = $_POST['Qform__FormParameter'];
1178:             $objSourceControl = $this->objControlArray[$strControlId];
1179:             $params = QControl::_ProcessActionParams($objSourceControl, $objAction, $mixParameter);
1180: 
1181:             if (strpos($strMethodName, '::')) {
1182:                 // Calling a static method in a class
1183:                 $f = explode('::', $strMethodName);
1184:                 if (is_callable($f)) {
1185:                     $f($this->strFormId, $params['controlId'], $params['param'], $params);
1186:                 }
1187:             }
1188:             elseif (($intPosition = strpos($strMethodName, ':')) !== false) {
1189:                 $strDestControlId = substr($strMethodName, 0, $intPosition);
1190:                 $strMethodName = substr($strMethodName, $intPosition + 1);
1191: 
1192:                 $objDestControl = $this->objControlArray[$strDestControlId];
1193:                 QControl::_CallActionMethod ($objDestControl, $strMethodName, $this->strFormId, $params);
1194:             } else {
1195:                 $this->$strMethodName($this->strFormId, $params['controlId'], $params['param'], $params);
1196:             }
1197:         }
1198: 
1199:         /**
1200:          * Calles 'Validate' method on a QControl recursively
1201:          * @param QControl $objControl
1202:          *
1203:          * @return bool
1204:          */
1205:         protected function ValidateControlAndChildren(QControl $objControl) {
1206:             return $objControl->ValidateControlAndChildren();
1207:         }
1208: 
1209:         /**
1210:          * Runs/Triggers any and all event handling functions for the control on which an event took place
1211:          * Depending on the control's CausesValidation value, it also calls for validation of the control or
1212:          * control and children or entire QForm.
1213:          *
1214:          * @param null|string $strControlIdOverride If supplied, the control with the supplied ID is selected
1215:          *
1216:          * @throws Exception|QCallerException
1217:          */
1218:         protected function TriggerActions($strControlIdOverride = null) {
1219:             if (array_key_exists('Qform__FormControl', $_POST)) {
1220:                 if ($strControlIdOverride) {
1221:                     $strControlId = $strControlIdOverride;
1222:                 } else {
1223:                     $strControlId = $_POST['Qform__FormControl'];
1224:                 }
1225: 
1226:                 // Control ID determined
1227:                 if ($strControlId != '') {
1228:                     $strEvent = $_POST['Qform__FormEvent'];
1229:                     $strAjaxActionId = NULL;
1230: 
1231:                     // Does this Control which performed the action exist?
1232:                     if (array_key_exists($strControlId, $this->objControlArray)) {
1233:                         // Get the ActionControl as well as the Actions to Perform
1234:                         $objActionControl = $this->objControlArray[$strControlId];
1235: 
1236:                         switch ($this->strCallType) {
1237:                             case QCallType::Ajax:
1238:                                 // split up event class name and ajax action id: i.e.: QClickEvent#a3 => [QClickEvent, a3]
1239:                                 $arrTemp = explode('#',$strEvent);
1240:                                 $strEvent = $arrTemp[0];
1241:                                 if(count($arrTemp) == 2)
1242:                                     $strAjaxActionId = $arrTemp[1];
1243:                                 $objActions = $objActionControl->GetAllActions($strEvent, 'QAjaxAction');
1244:                                 break;
1245:                             case QCallType::Server:
1246:                                 $objActions = $objActionControl->GetAllActions($strEvent, 'QServerAction');
1247:                                 break;
1248:                             default:
1249:                                 throw new Exception('Unknown Form CallType: ' . $this->strCallType);
1250:                         }
1251: 
1252:                         // Validation Check
1253:                         $blnValid = true;
1254:                         $mixCausesValidation = null;
1255: 
1256:                         // Figure out what the CausesValidation directive is
1257:                         // Set $mixCausesValidation to the default one (e.g. the one defined on the control)
1258:                         $mixCausesValidation = $objActionControl->CausesValidation;
1259: 
1260:                         // Next, go through the linked ajax/server actions to see if a causesvalidation override is set on any of them
1261:                         if ($objActions) foreach ($objActions as $objAction) {
1262:                             if (!is_null($objAction->CausesValidationOverride)) {
1263:                                 $mixCausesValidation = $objAction->CausesValidationOverride;
1264:                             }
1265:                         }
1266: 
1267:                         // Now, Do Something with mixCauseValidation...
1268: 
1269:                         // Starting Point is a QControl
1270:                         if ($mixCausesValidation instanceof QControl) {
1271:                             if (!$this->ValidateControlAndChildren($mixCausesValidation)) {
1272:                                 $blnValid = false;
1273:                             }
1274: 
1275:                             // Starting Point is an Array of QControls
1276:                         } else if (is_array($mixCausesValidation)) {
1277:                             foreach (((array) $mixCausesValidation) as $objControlToValidate) {
1278:                                 if (!$this->ValidateControlAndChildren($objControlToValidate)) {
1279:                                     $blnValid = false;
1280:                                 }
1281:                             }
1282: 
1283:                             // Validate All the Controls on the Form
1284:                         } else if ($mixCausesValidation === QCausesValidation::AllControls) {
1285:                             foreach ($this->GetChildControls($this) as $objControl) {
1286:                                 // Only Enabled and Visible and Rendered controls that are children of this form should be validated
1287:                                 if (($objControl->Visible) && ($objControl->Enabled) && ($objControl->RenderMethod) && ($objControl->OnPage)) {
1288:                                     if (!$this->ValidateControlAndChildren($objControl)) {
1289:                                         $blnValid = false;
1290:                                     }
1291:                                 }
1292:                             }
1293: 
1294:                             // CausesValidation specifed by QCausesValidation directive
1295:                         } else if ($mixCausesValidation == QCausesValidation::SiblingsAndChildren) {
1296:                             // Get only the Siblings of the ActionControl's ParentControl
1297:                             // If not ParentControl, then the parent is the form itself
1298:                             if (!($objParentObject = $objActionControl->ParentControl)) {
1299:                                 $objParentObject = $this;
1300:                             }
1301: 
1302:                             // Get all the children of ParentObject
1303:                             foreach ($this->GetChildControls($objParentObject) as $objControl) {
1304:                                 // Only Enabled and Visible and Rendered controls that are children of ParentObject should be validated
1305:                                 if (($objControl->Visible) && ($objControl->Enabled) && ($objControl->RenderMethod) && ($objControl->OnPage)) {
1306:                                     if (!$this->ValidateControlAndChildren($objControl)) {
1307:                                         $blnValid = false;
1308:                                     }
1309:                                 }
1310:                             }
1311: 
1312:                             // CausesValidation specifed by QCausesValidation directive
1313:                         } else if ($mixCausesValidation == QCausesValidation::SiblingsOnly) {
1314:                             // Get only the Siblings of the ActionControl's ParentControl
1315:                             // If not ParentControl, tyhen the parent is the form itself
1316:                             if (!($objParentObject = $objActionControl->ParentControl)) {
1317:                                 $objParentObject = $this;
1318:                             }
1319: 
1320:                             // Get all the children of ParentObject
1321:                             foreach ($this->GetChildControls($objParentObject) as $objControl)
1322:                                 // Only Enabled and Visible and Rendered controls that are children of ParentObject should be validated
1323:                                 if (($objControl->Visible) && ($objControl->Enabled) && ($objControl->RenderMethod) && ($objControl->OnPage)) {
1324:                                     if (!$objControl->Validate()) {
1325:                                         $objControl->MarkAsModified();
1326:                                         $blnValid = false;
1327:                                     }
1328:                                 }
1329: 
1330:                             // No Validation Requested
1331:                         } else {}
1332: 
1333: 
1334:                         // Run Form-Specific Validation (if any)
1335:                         if ($mixCausesValidation && !($mixCausesValidation instanceof QDialog)) {
1336:                             if (!$this->Form_Validate()) {
1337:                                 $blnValid = false;
1338:                             }
1339:                         }
1340: 
1341: 
1342:                         // Go ahead and run the ServerActions or AjaxActions if Validation Passed and if there are Server/Ajax-Actions defined
1343:                         if ($blnValid) {
1344:                             if ($objActions) foreach ($objActions as $objAction) {
1345:                                 if ($strMethodName = $objAction->MethodName) {
1346:                                     if (($strAjaxActionId == NULL)          //if this call was not an ajax call
1347:                                         || ($objAction->Id == NULL)         // or the QAjaxAction derived action has no id set
1348:                                         //(a possible way to add a callback that gets executed on every ajax call for this control)
1349:                                         || ($strAjaxActionId == $objAction->Id)) //or the ajax action id passed from client side equals the id of the current ajax action
1350:                                         $this->TriggerMethod($strControlId, $strMethodName, $objAction);
1351:                                 }
1352:                             }
1353:                         }
1354:                         else {
1355:                             $this->Form_Invalid();  // notify form that something went wrong
1356:                         }
1357:                     } else {
1358:                         // Nope -- Throw an exception
1359:                         throw new Exception(sprintf('Control passed by Qform__FormControl does not exist: %s', $strControlId));
1360:                     }
1361:                 }
1362:                 /* else {
1363:                     // TODO: Code to automatically execute any PrimaryButton's onclick action, if applicable
1364:                     // Difficult b/c of all the QCubed hidden parameters that need to be set to get the action to work properly
1365:                     // Javascript interaction of PrimaryButton works fine in Firefox... currently doens't work in IE 6.
1366:                 }*/
1367:             }
1368:         }
1369: 
1370:         /**
1371:          * Begins rendering the page
1372:          */
1373:         protected function Render() {
1374:             if (QWatcher::WatchersChanged()) {
1375:                 QApplication::ExecuteJsFunction('qc.broadcastChange');
1376:             }
1377: 
1378:             require($this->HtmlIncludeFilePath);
1379:         }
1380: 
1381:         /**
1382:          * Render the children of this QForm
1383:          * @param bool $blnDisplayOutput
1384:          *
1385:          * @return null|string Null when blnDisplayOutput is true
1386:          */
1387:         protected function RenderChildren($blnDisplayOutput = true) {
1388:             $strToReturn = "";
1389: 
1390:             foreach ($this->GetChildControls($this) as $objControl)
1391:                 if (!$objControl->Rendered)
1392:                     $strToReturn .= $objControl->Render($blnDisplayOutput);
1393: 
1394:             if ($blnDisplayOutput) {
1395:                 print($strToReturn);
1396:                 return null;
1397:             } else
1398:                 return $strToReturn;
1399:         }
1400: 
1401:         /**
1402:          * This exists to prevent inadverant "New"
1403:          */
1404:         protected function __construct() {}
1405: 
1406:         /**
1407:          * Renders the tags to include the css style sheets. Call this in your head tag if you want to
1408:          * put these there. Otherwise, the styles will automatically be included just after the form.
1409:          *
1410:          * @param bool $blnDisplayOutput
1411:          * @return null|string
1412:          */
1413:         public function RenderStyles($blnDisplayOutput = true, $blnInHead = true) {
1414:             $strToReturn = '';
1415:             $this->strIncludedStyleSheetFileArray = array();
1416: 
1417:             // Figure out initial list of StyleSheet includes
1418:             $strStyleSheetArray = array();
1419: 
1420:             foreach ($this->GetAllControls() as $objControl) {
1421:                 // Include any StyleSheets?  The control would have a
1422:                 // comma-delimited list of stylesheet files to include (if applicable)
1423:                 if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) {
1424:                     $strStyleSheetArray = array_merge($strStyleSheetArray, $strScriptArray);
1425:                 }
1426:             }
1427: 
1428:             // In order to make ui-themes workable, move the jquery.css to the end of list.
1429:             // It should override any rules that it can override.
1430:             foreach ($strStyleSheetArray as $strScript) {
1431:                 if (__JQUERY_CSS__ == $strScript) {
1432:                     unset($strStyleSheetArray[$strScript]);
1433:                     $strStyleSheetArray[$strScript] = $strScript;
1434:                     break;
1435:                 }
1436:             }
1437: 
1438:             // Include styles that need to be included
1439:             foreach ($strStyleSheetArray as $strScript) {
1440:                 if ($blnInHead) {
1441:                     $strToReturn  .= '<link href="' . $this->GetCssFileUri($strScript) . '" rel="stylesheet" />';
1442:                 } else {
1443:                     $strToReturn  .= '<style type="text/css" media="all">@import "' . $this->GetCssFileUri($strScript) . '"</style>';
1444:                 }
1445:                 $strToReturn .= "\r\n";
1446:             }
1447: 
1448:             self::$blnStylesRendered = true;
1449: 
1450:             // Return or Display
1451:             if ($blnDisplayOutput) {
1452:                 if(!QApplication::$CliMode) {
1453:                     print($strToReturn);
1454:                 }
1455:                 return null;
1456:             } else {
1457:                 if(!QApplication::$CliMode) {
1458:                     return $strToReturn;
1459:                 } else {
1460:                     return '';
1461:                 }
1462:             }
1463:         }
1464: 
1465:         /**
1466:          * Initializes the QForm rendering process
1467:          * @param bool $blnDisplayOutput Whether the output is to be printed (true) or simply returned (false)
1468:          *
1469:          * @return null|string
1470:          * @throws QCallerException
1471:          */
1472:         public function RenderBegin($blnDisplayOutput = true) {
1473:             // Ensure that RenderBegin() has not yet been called
1474:             switch ($this->intFormStatus) {
1475:                 case QFormBase::FormStatusUnrendered:
1476:                     break;
1477:                 case QFormBase::FormStatusRenderBegun:
1478:                 case QFormBase::FormStatusRenderEnded:
1479:                     throw new QCallerException('$this->RenderBegin() has already been called');
1480:                     break;
1481:                 default:
1482:                     throw new QCallerException('FormStatus is in an unknown status');
1483:             }
1484: 
1485:             // Update FormStatus and Clear Included JS/CSS list
1486:             $this->intFormStatus = QFormBase::FormStatusRenderBegun;
1487: 
1488:             // Prepare for rendering
1489: 
1490:             QApplicationBase::$ProcessOutput = false;
1491:             $strOutputtedText = trim(ob_get_contents());
1492:             if (strpos(strtolower($strOutputtedText), '<body') === false) {
1493:                 $strToReturn = '<body>';
1494:                 $this->blnRenderedBodyTag = true;
1495:             } else
1496:                 $strToReturn = '';
1497:             QApplicationBase::$ProcessOutput = true;
1498: 
1499: 
1500:             // Iterate through the form's ControlArray to Define FormAttributes and additional JavaScriptIncludes
1501:             $this->strFormAttributeArray = array();
1502:             foreach ($this->GetAllControls() as $objControl) {
1503:                 // Form Attributes?
1504:                 if ($objControl->FormAttributes) {
1505:                     $this->strFormAttributeArray = array_merge($this->strFormAttributeArray, $objControl->FormAttributes);
1506:                 }
1507:             }
1508: 
1509:             if (is_array($this->strCustomAttributeArray))
1510:                 $this->strFormAttributeArray = array_merge($this->strFormAttributeArray, $this->strCustomAttributeArray);
1511: 
1512:             // Create $strFormAttributes
1513:             $strFormAttributes = '';
1514:             foreach ($this->strFormAttributeArray as $strKey=>$strValue) {
1515:                 $strFormAttributes .= sprintf(' %s="%s"', $strKey, $strValue);
1516:             }
1517: 
1518:             if ($this->strCssClass)
1519:                 $strFormAttributes .= ' class="' . $this->strCssClass . '"';
1520: 
1521:             // Setup Rendered HTML
1522:             $strToReturn .= sprintf('<form method="post" id="%s" action="%s"%s>', $this->strFormId, htmlentities(QApplication::$RequestUri), $strFormAttributes);
1523:             $strToReturn .= "\r\n";
1524:             
1525:             if (!self::$blnStylesRendered) {
1526:                 $strToReturn .= $this->RenderStyles(false, false);
1527:             }
1528: 
1529:             // Perhaps a strFormModifiers as an array to
1530:             // allow controls to update other parts of the form, like enctype, onsubmit, etc.
1531: 
1532:             // Return or Display
1533:             if ($blnDisplayOutput) {
1534:                 if(!QApplication::$CliMode) {
1535:                     print($strToReturn);
1536:                 }
1537:                 return null;
1538:             } else {
1539:                 if(!QApplication::$CliMode) {
1540:                     return $strToReturn;
1541:                 } else {
1542:                     return '';
1543:                 }
1544:             }
1545:         }
1546: 
1547:         /**
1548:          * Internal helper function used by RenderBegin and by RenderAjax
1549:          * Given a comma-delimited list of javascript files, this will return an array of files that NEED to still
1550:          * be included because (1) it hasn't yet been included and (2) it hasn't been specified to be "ignored".
1551:          *
1552:          * This WILL update the internal $strIncludedJavaScriptFileArray array.
1553:          *
1554:          * @param string | array $strJavaScriptFileList
1555:          * @return string[] array of script files to include or NULL if none
1556:          */
1557:         protected function ProcessJavaScriptList($strJavaScriptFileList)  {
1558: 
1559:             if (empty($strJavaScriptFileList)) return null;
1560: 
1561:             $strArrayToReturn = array();
1562: 
1563:             if (!is_array($strJavaScriptFileList)) {
1564:                 $strJavaScriptFileList = explode(',', $strJavaScriptFileList);
1565:             }
1566: 
1567:             // Iterate through the list of JavaScriptFiles to Include...
1568:             foreach ($strJavaScriptFileList as $strScript) {
1569:                 if ($strScript = trim($strScript)) {
1570: 
1571:                     // Include it if we're NOT ignoring it and it has NOT already been included
1572:                     if ((array_search($strScript, $this->strIgnoreJavaScriptFileArray) === false) &&
1573:                         !array_key_exists($strScript, $this->strIncludedJavaScriptFileArray)) {
1574:                         $strArrayToReturn[$strScript] = $strScript;
1575:                         $this->strIncludedJavaScriptFileArray[$strScript] = true;
1576:                     }
1577:                 }
1578:             }
1579: 
1580:             if (count($strArrayToReturn))
1581:                 return $strArrayToReturn;
1582: 
1583:             return null;
1584:         }
1585: 
1586:         /**
1587:          * Primarily used by RenderBegin and by RenderAjax
1588:          * Given a comma-delimited list of stylesheet files, this will return an array of file that NEED to still
1589:          * be included because (1) it hasn't yet been included and (2) it hasn't been specified to be "ignored".
1590:          *
1591:          * This WILL update the internal $strIncludedStyleSheetFileArray array.
1592:          *
1593:          * @param string $strStyleSheetFileList
1594:          * @return string[] array of stylesheet files to include or NULL if none
1595:          */
1596:         protected function ProcessStyleSheetList($strStyleSheetFileList) {
1597:             $strArrayToReturn = array();
1598: 
1599:             // Is there a comma-delimited list of StyleSheet files to include?
1600:             if ($strStyleSheetFileList = trim($strStyleSheetFileList)) {
1601:                 $strScriptArray = explode(',', $strStyleSheetFileList);
1602: 
1603:                 // Iterate through the list of StyleSheetFiles to Include...
1604:                 foreach ($strScriptArray as $strScript)
1605:                     if ($strScript = trim($strScript))
1606: 
1607:                         // Include it if we're NOT ignoring it and it has NOT already been included
1608:                         if ((array_search($strScript, $this->strIgnoreStyleSheetFileArray) === false) &&
1609:                             !array_key_exists($strScript, $this->strIncludedStyleSheetFileArray)) {
1610:                             $strArrayToReturn[$strScript] = $strScript;
1611:                             $this->strIncludedStyleSheetFileArray[$strScript] = true;
1612:                         }
1613:             }
1614: 
1615:             if (count($strArrayToReturn))
1616:                 return $strArrayToReturn;
1617: 
1618:             return null;
1619:         }
1620: 
1621:         /**
1622:          * Returns whether or not this Form is being run due to a PostBack event (e.g. a ServerAction or AjaxAction)
1623:          * @return bool
1624:          */
1625:         public function IsPostBack() {
1626:             return ($this->strCallType != QCallType::None);
1627:         }
1628: 
1629:         /**
1630:          * Will return an array of Strings which will show all the error and warning messages
1631:          * in all the controls in the form.
1632:          *
1633:          * @param bool $blnErrorsOnly Show only the errors (otherwise, show both warnings and errors)
1634:          * @return string[] an array of strings representing the (multiple) errors and warnings
1635:          */
1636:         public function GetErrorMessages($blnErrorsOnly = false) {
1637:             $strToReturn = array();
1638:             foreach ($this->GetAllControls() as $objControl) {
1639:                 if ($objControl->ValidationError)
1640:                     array_push($strToReturn, $objControl->ValidationError);
1641:                 if (!$blnErrorsOnly)
1642:                     if ($objControl->Warning)
1643:                         array_push($strToReturn, $objControl->Warning);
1644:             }
1645: 
1646:             return $strToReturn;
1647:         }
1648: 
1649:         /**
1650:          * Will return an array of QControls from the form which have either an error or warning message.
1651:          *
1652:          * @param bool $blnErrorsOnly Return controls that have just errors (otherwise, show both warnings and errors)
1653:          * @return QControl[] an array of controls representing the (multiple) errors and warnings
1654:          */
1655:         public function GetErrorControls($blnErrorsOnly = false) {
1656:             $objToReturn = array();
1657:             foreach ($this->GetAllControls() as $objControl) {
1658:                 if ($objControl->ValidationError)
1659:                     array_push($objToReturn, $objControl);
1660:                 else if (!$blnErrorsOnly)
1661:                     if ($objControl->Warning)
1662:                         array_push($objToReturn, $objControl);
1663:             }
1664: 
1665:             return $objToReturn;
1666:         }
1667: 
1668:         /**
1669:          * Gets the JS file URI, given a string input
1670:          * @param string $strFile File name to be tested
1671:          *
1672:          * @return string the final JS file URI
1673:          */
1674:         public function GetJsFileUri($strFile) {
1675:             return QApplication::GetJsFileUri($strFile);
1676:         }
1677: 
1678:         /**
1679:          * Gets the CSS file URI, given a string input
1680:          * @param string $strFile File name to be tested
1681:          *
1682:          * @return string the final CSS URI
1683:          */
1684:         public function GetCssFileUri($strFile) {
1685:             return QApplication::GetCssFileUri($strFile);
1686:         }
1687: 
1688:         /**
1689:          * Get high level form javascript files to be included. Default here includes all
1690:          * javascripts needed to run qcubed.
1691:          * Override and add to this list and include
1692:          * javascript and jQuery files and libraries needed for your application.
1693:          * Javascript files included before __QCUBED_JS_CORE__ can refer to jQuery as $.
1694:          * After qcubed.js, $ becomes $j, so add other libraries that need
1695:          * $ in a different context after qcubed.js, and insert jQuery libraries and  plugins that
1696:          * refer to $ before qcubed.js file.
1697:          *
1698:          * @return array
1699:          */
1700:         protected function GetFormJavaScripts() {
1701:             return array (__JQUERY_BASE__,
1702:                 __JQUERY_EFFECTS__,
1703:                 'jquery/jquery.ajaxq-0.0.1.js',
1704:                 __QCUBED_JS_CORE__);
1705:         }
1706: 
1707:         /**
1708:          * Renders the end of the form, including the closing form and body tags.
1709:          * Renders the html for hidden controls.
1710:          * @param bool $blnDisplayOutput should the output be returned or directly printed to screen.
1711:          *
1712:          * @return null|string
1713:          * @throws QCallerException
1714:          */
1715:         public function RenderEnd($blnDisplayOutput = true) {
1716:             // Ensure that RenderEnd() has not yet been called
1717:             switch ($this->intFormStatus) {
1718:                 case QFormBase::FormStatusUnrendered:
1719:                     throw new QCallerException('$this->RenderBegin() was never called');
1720:                 case QFormBase::FormStatusRenderBegun:
1721:                     break;
1722:                 case QFormBase::FormStatusRenderEnded:
1723:                     throw new QCallerException('$this->RenderEnd() has already been called');
1724:                     break;
1725:                 default:
1726:                     throw new QCallerException('FormStatus is in an unknown status');
1727:             }
1728: 
1729:             $strHtml = '';  // This will be the final output
1730: 
1731:             /**** Render any controls that get automatically rendered ****/
1732:             foreach ($this->GetAllControls() as $objControl) {
1733:                 if ($objControl->AutoRender &&
1734:                     !$objControl->Rendered) {
1735:                     $strRenderMethod = $objControl->PreferredRenderMethod;
1736:                     $strHtml .= $objControl->$strRenderMethod(false) . _nl();
1737:                 }
1738:             }
1739: 
1740:             /**** Prepare Javascripts ****/
1741: 
1742:             // Clear included javascript array since we are completely redrawing the page
1743:             $this->strIncludedJavaScriptFileArray = array();
1744:             $strControlIdToRegister = array();
1745:             $strEventScripts = '';
1746: 
1747:             // Add form level javascripts and libraries
1748:             $strJavaScriptArray = $this->ProcessJavaScriptList($this->GetFormJavaScripts());
1749:             QApplication::AddJavaScriptFiles($strJavaScriptArray);
1750:             $strFormJsFiles = QApplication::RenderFiles();  // Render the form-level javascript files separately
1751: 
1752:             // Go through all controls and gather up any JS or CSS to run or Form Attributes to modify
1753:             foreach ($this->GetAllControls() as $objControl) {
1754:                 if ($objControl->Rendered || $objControl->ScriptsOnly) {
1755:                     $strControlIdToRegister[] = $objControl->ControlId;
1756: 
1757:                     /* Note: GetEndScript may cause the control to register additional commands, or even add javascripts, so those should be handled after this. */
1758:                     if ($strControlScript = $objControl->GetEndScript()) {
1759:                         $strControlScript = JavaScriptHelper::TerminateScript($strControlScript);
1760: 
1761:                         // Add comments for developer version of output
1762:                         if (!QApplication::$Minimize) {
1763:                             // Render a comment
1764:                             $strControlScript = _nl() .  _nl() .
1765:                                 sprintf ('/*** EndScript -- Control Type: %s, Control Name: %s, Control Id: %s  ***/',
1766:                                     get_class($objControl), $objControl->Name, $objControl->ControlId) .
1767:                                 _nl() .
1768:                                 _indent($strControlScript);
1769:                         }
1770:                         $strEventScripts .= $strControlScript;
1771:                     }
1772:                 }
1773: 
1774:                 // Include the javascripts specified by each control.
1775:                 if ($strScriptArray = $this->ProcessJavaScriptList($objControl->JavaScripts)) {
1776:                     QApplication::AddJavaScriptFiles($strScriptArray);
1777:                 }
1778: 
1779:                 // Include any StyleSheets?  The control would have a
1780:                 // comma-delimited list of stylesheet files to include (if applicable)
1781:                 if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) {
1782:                     QApplication::AddStyleSheets(array_keys($strScriptArray));
1783:                 }
1784: 
1785:                 // Form Attributes?
1786:                 if ($objControl->FormAttributes) {
1787:                     QApplication::ExecuteControlCommand($this->strFormId, 'attr', $objControl->FormAttributes);
1788:                     foreach ($objControl->FormAttributes as $strKey=>$strValue) {
1789:                         if (!array_key_exists($strKey, $this->strFormAttributeArray)) {
1790:                             $this->strFormAttributeArray[$strKey] = $strValue;
1791:                         } else if ($this->strFormAttributeArray[$strKey] != $strValue) {
1792:                             $this->strFormAttributeArray[$strKey] = $strValue;
1793:                         }
1794:                     }
1795:                 }
1796:             }
1797: 
1798:             // Add grouping commands to events (Used for deprecated drag and drop, but not removed yet)
1799:             foreach ($this->objGroupingArray as $objGrouping) {
1800:                 $strGroupingScript = $objGrouping->Render();
1801:                 if (strlen($strGroupingScript) > 0) {
1802:                     $strGroupingScript = JavaScriptHelper::TerminateScript($strGroupingScript);
1803:                     $strEventScripts .= $strGroupingScript;
1804:                 }
1805:             }
1806: 
1807:             /*** Build the javascript block ****/
1808: 
1809:             // Start with variable settings and initForm
1810:             $strEndScript = sprintf('qc.initForm("%s"); ', $this->strFormId);
1811: 
1812:             // Register controls
1813:             if ($strControlIdToRegister) {
1814:                 $strEndScript .= sprintf("qc.regCA(%s); \n", JavaScriptHelper::toJsObject($strControlIdToRegister));
1815:             }
1816: 
1817:             // Design mode event
1818:             if (defined('__DESIGN_MODE__') && __DESIGN_MODE__ == 1) {
1819:                 // attach an event listener to the form to send context menu selections to the designer dialog for processing
1820:                 $strEndScript .= sprintf(
1821:                     '$j("#%s").on("contextmenu", "[id]", 
1822:                         function(event) {
1823:                             $j("#qconnectoreditdlg").trigger("qdesignerclick", 
1824:                                 [{id: event.target.id ? event.target.id : $j(event.target).parents("[id]").attr("id"), for: $j(event.target).attr("for")}]
1825:                             );
1826:                             return false;
1827:                         }
1828:                     );', $this->FormId);
1829:             }
1830: 
1831:             // Add any application level js commands.
1832:             // This will include high and medimum level commands
1833:             $strEndScript .= QApplication::RenderJavascript(true);
1834: 
1835:             // Add the javascript coming from controls and events just after the medium level commands
1836:             $strEndScript .=  ';'  . $strEventScripts;
1837: 
1838:             // Add low level commands and other things that need to execute at the end
1839:             $strEndScript .= ';' . QApplication::RenderJavascript(false);
1840: 
1841: 
1842: 
1843: 
1844:             // Create Final EndScript Script
1845:             $strEndScript = sprintf('<script type="text/javascript">$j(document).ready(function() { %s; });</script>', $strEndScript);
1846: 
1847: 
1848:             /**** Render the HTML itself, appending the javascript we generated above ****/
1849: 
1850:             foreach ($this->GetAllControls() as $objControl) {
1851:                 if ($objControl->Rendered) {
1852:                     $strHtml .= $objControl->GetEndHtml();
1853:                 }
1854:                 $objControl->ResetFlags(); // Make sure controls are serialized in a reset state
1855:             }
1856: 
1857:             $strHtml .= $strFormJsFiles . _nl();    // Add form level javascript files
1858: 
1859:             // put javascript environment defines up early for use by other js files.
1860:             $strHtml .= '<script type="text/javascript">' .
1861:                 sprintf('qc.baseDir = "%s"; ', __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__) .
1862:                 sprintf('qc.jsAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __JS_ASSETS__) .
1863:                 sprintf('qc.phpAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __PHP_ASSETS__) .
1864:                 sprintf('qc.cssAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __CSS_ASSETS__) .
1865:                 sprintf('qc.imageAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __IMAGE_ASSETS__) .
1866:                 '</script>' .
1867:                 _nl();
1868: 
1869:             $strHtml .= QApplication::RenderFiles() . _nl();    // add plugin and control js files
1870: 
1871:             // Render hidden controls related to the form
1872:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormId" id="Qform__FormId" value="%s" />', $this->strFormId) . _nl();
1873:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormControl" id="Qform__FormControl" value="" />') . _nl();
1874:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormEvent" id="Qform__FormEvent" value="" />') . _nl();
1875:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormParameter" id="Qform__FormParameter" value="" />') . _nl();
1876:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormCallType" id="Qform__FormCallType" value="" />') . _nl();
1877:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormUpdates" id="Qform__FormUpdates" value="" />') . _nl();
1878:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormCheckableControls" id="Qform__FormCheckableControls" value="" />') . _nl();
1879: 
1880:             // Serialize and write out the formstate
1881:             $strHtml .= sprintf('<input type="hidden" name="Qform__FormState" id="Qform__FormState" value="%s" />', QForm::Serialize(clone($this))) . _nl();
1882: 
1883:             // close the form tag
1884:             $strHtml .= "</form>";
1885: 
1886:             // Add the JavaScripts rendered above
1887:             $strHtml .= $strEndScript;
1888: 
1889:             // close the body tag
1890:             if ($this->blnRenderedBodyTag) {
1891:                 $strHtml .= '</body>';
1892:             }
1893: 
1894:             /**** Cleanup ****/
1895: 
1896:             // Update Form Status
1897:             $this->intFormStatus = QFormBase::FormStatusRenderEnded;
1898: 
1899:             // Display or Return
1900:             if ($blnDisplayOutput) {
1901:                 if(!QApplication::$CliMode) {
1902:                     print($strHtml);
1903:                 }
1904:                 return null;
1905:             } else {
1906:                 if(!QApplication::$CliMode) {
1907:                     return $strHtml;
1908:                 } else {
1909:                     return '';
1910:                 }
1911:             }
1912:         }
1913:     }
1914: 
1915:     function __QForm_EvaluateTemplate_ObHandler($strBuffer) {
1916:         return $strBuffer;
1917:     }
1918: 
API documentation generated by ApiGen