/** * @param QControl|QControlBase $objControl QControl for which the actions have to be rendered * @param string $strEventName Name of the event for which the actions have to be rendered * @param QAction[] $objActions Array of actionss * * @return null|string * @throws Exception */ public static function RenderActions(QControl $objControl, $strEventName, $objActions) { $strToReturn = ''; $strJqUiProperty = null; if ($objControl->ActionsMustTerminate) { $strToReturn .= ' event.preventDefault();' . _nl(); } if ($objActions && count($objActions)) { foreach ($objActions as $objAction) { if ($objAction->objEvent->EventName != $strEventName) { throw new Exception('Invalid Action Event in this entry in the ActionArray'); } if ($objAction->objEvent instanceof QJqUiPropertyEvent) { $strJqUiProperty = $objAction->objEvent->JqProperty; } if ($objAction->objEvent->Delay > 0) { $strCode = sprintf(" qcubed.setTimeout('%s', \$j.proxy(function(){%s},this), %s);", $objControl->ControlId, _nl() . _indent(trim($objAction->RenderScript($objControl))) . _nl(), $objAction->objEvent->Delay); } else { $strCode = ' ' . $objAction->RenderScript($objControl); } // Add Condition (if applicable) if (strlen($objAction->objEvent->Condition)) { $strCode = sprintf(' if (%s) {%s}', $objAction->objEvent->Condition, _nl() . _indent(trim($strCode)) . _nl()); } $strCode .= _nl(); // Append it to the Return Value $strToReturn .= $strCode; } } $strToReturn = _nl() . _indent($strToReturn); if (strlen($strToReturn)) { if ($strJqUiProperty) { $strOut = sprintf('$j("#%s").%s("option", {%s: function(event, ui){%s}});', $objControl->getJqControlId(), $objControl->getJqSetupFunction(), $strJqUiProperty, $strToReturn); } elseif ($objControl instanceof QControlProxy) { if ($objControl->TargetControlId) { // Deprecated. $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->TargetControlId, $strEventName, $strToReturn); } else { $strOut = sprintf('$j("#%s").on("%s", "[data-qpxy=\'%s\']", function(event, ui){%s});', $objControl->Form->FormId, $strEventName, $objControl->ControlId, $strToReturn); } } else { $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->getJqControlId(), $strEventName, $strToReturn); } if (isset($strOut)) { if (!QApplication::$Minimize) { // Render a comment $strOut = _nl() . _nl() . sprintf('/*** Event: %s Control Type: %s, Control Name: %s, Control Id: %s ***/', $strEventName, get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strOut) . _nl() . _nl(); } return $strOut; } } return null; }
/** * Renders an html tag with the given attributes and inner html. * * If the innerHtml is detected as being wrapped in an html tag of some sort, it will attempt to format the code so that * it has a structured view in a browser, with the inner html indented and on a new line in between the tags. You * can turn this off by setting __MINIMIZE__, or by passing in true to $blnNoSpace. * * There area a few special cases to consider: * - Void elements will not be formatted to avoid adding unnecessary white space since these are generally * inline elements * - Non-void elements always use internal newlines, even in __MINIMIZE__ mode. This is to prevent different behavior * from appearing in __MINIMIZE__ mode on inline elements, because inline elements with internal space will render with space to separate * from surrounding elements. Usually, this is not an issue, but in the special situations where you really need inline * elements to be right up against its siblings, set $blnNoSpace to true. * * * @param string $strTag The tag name * @param null|mixed $mixAttributes String of attribute values or array of attribute values. * @param null|string $strInnerHtml The html to print between the opening and closing tags. This will NOT be escaped. * @param boolean $blnIsVoidElement True to print as a tag with no closing tag. * @param boolean $blnNoSpace Renders with no white-space. Useful in special inline situations. * @return string The rendered html tag */ public static function RenderTag($strTag, $mixAttributes, $strInnerHtml = null, $blnIsVoidElement = false, $blnNoSpace = false) { assert('!empty($strTag)'); $strToReturn = '<' . $strTag; if ($mixAttributes) { if (is_string($mixAttributes)) { $strToReturn .= ' ' . trim($mixAttributes); } else { // assume array $strToReturn .= QHtml::RenderHtmlAttributes($mixAttributes); } } if ($blnIsVoidElement) { $strToReturn .= ' />'; // conforms to both XHTML and HTML5 for both normal and foreign elements } elseif ($blnNoSpace || substr(trim($strInnerHtml), 0, 1) !== '<') { $strToReturn .= '>' . $strInnerHtml . '</' . $strTag . '>'; } else { // the hardcoded newlines below are important to prevent different drawing behavior in MINIMIZE mode $strToReturn .= '>' . "\n" . _indent(trim($strInnerHtml)) . "\n" . '</' . $strTag . '>' . _nl(); } return $strToReturn; }
/** * Returns code to refresh the control from the saved object. * * @param QCodeGenBase $objCodeGen * @param QSqlTable $objTable * @param QSqlColumn $objColumn * @param bool $blnInit * @return string */ public function ConnectorRefresh(QCodeGenBase $objCodeGen, QSqlTable $objTable, $objColumn, $blnInit = false) { $strPropName = QCodeGen::ModelConnectorPropertyName($objColumn); $strControlVarName = $this->VarName($strPropName); $strObjectName = $objCodeGen->ModelVariableName($objTable->Name); $strRet = ''; if ($blnInit) { $strRet .= <<<TMPL if (!\$this->str{$strPropName}NullLabel) { \tif (!\$this->{$strControlVarName}->Required) { \t\t\$this->str{$strPropName}NullLabel = '- None -'; \t} \telseif (!\$this->blnEditMode) { \t\t\$this->str{$strPropName}NullLabel = '- Select One -'; \t} } TMPL; } else { $strRet .= "\$this->{$strControlVarName}->RemoveAllItems();\n"; } $strRet .= <<<TMPL \$this->{$strControlVarName}->AddItem(QApplication::Translate(\$this->str{$strPropName}NullLabel), null); TMPL; $options = $objColumn->Options; if (!$options || !isset($options['NoAutoLoad'])) { $strRet .= "\$this->{$strControlVarName}->AddItems(\$this->{$strControlVarName}_GetItems());\n"; } if ($objColumn instanceof QSqlColumn) { $strRet .= "\$this->{$strControlVarName}->SelectedValue = \$this->{$strObjectName}->{$objColumn->PropertyName};\n"; } elseif ($objColumn instanceof QReverseReference && $objColumn->Unique) { $strRet .= "if (\$this->{$strObjectName}->{$objColumn->ObjectPropertyName})\n"; $strRet .= _indent("\$this->{$strControlVarName}->SelectedValue = \$this->{$strObjectName}->{$objColumn->ObjectPropertyName}->{$objCodeGen->GetTable($objColumn->Table)->PrimaryKeyColumnArray[0]->PropertyName};\n"); } elseif ($objColumn instanceof QManyToManyReference) { if ($objColumn->IsTypeAssociation) { $strRet .= "\$this->{$strControlVarName}->SelectedValues = array_keys(\$this->{$strObjectName}->Get{$objColumn->ObjectDescription}Array());\n"; } else { //$strRet .= $strTabs . "\$this->{$strControlVarName}->SelectedValues = \$this->{$strObjectName}->Get{$objColumn->ObjectDescription}Keys();\n"; } } if (!$blnInit) { // wrap it with a test as to whether the control has been created. $strRet = _indent($strRet); $strRet = <<<TMPL if (\$this->{$strControlVarName}) { {$strRet} } TMPL; } $strRet = _indent($strRet, 3); return $strRet; }
/** * Renders the end of the form, including the closing form and body tags. * Renders the html for hidden controls. * @param bool $blnDisplayOutput should the output be returned or directly printed to screen. * * @return null|string * @throws QCallerException */ public function RenderEnd($blnDisplayOutput = true) { // Ensure that RenderEnd() has not yet been called switch ($this->intFormStatus) { case QFormBase::FormStatusUnrendered: throw new QCallerException('$this->RenderBegin() was never called'); case QFormBase::FormStatusRenderBegun: break; case QFormBase::FormStatusRenderEnded: throw new QCallerException('$this->RenderEnd() has already been called'); break; default: throw new QCallerException('FormStatus is in an unknown status'); } $strHtml = ''; // This will be the final output /**** Render any controls that get automatically rendered ****/ foreach ($this->GetAllControls() as $objControl) { if ($objControl->AutoRender && !$objControl->Rendered) { $strRenderMethod = $objControl->PreferredRenderMethod; $strHtml .= $objControl->{$strRenderMethod}(false) . _nl(); } } /**** Prepare Javascripts ****/ // Clear included javascript array since we are completely redrawing the page $this->strIncludedJavaScriptFileArray = array(); $strControlIdToRegister = array(); $strEventScripts = ''; // Add form level javascripts and libraries $strJavaScriptArray = $this->ProcessJavaScriptList($this->GetFormJavaScripts()); QApplication::AddJavaScriptFiles($strJavaScriptArray); $strFormJsFiles = QApplication::RenderFiles(); // Render the form-level javascript files separately // Go through all controls and gather up any JS or CSS to run or Form Attributes to modify foreach ($this->GetAllControls() as $objControl) { if ($objControl->Rendered || $objControl->ScriptsOnly) { $strControlIdToRegister[] = $objControl->ControlId; /* Note: GetEndScript may cause the control to register additional commands, or even add javascripts, so those should be handled after this. */ if ($strControlScript = $objControl->GetEndScript()) { $strControlScript = JavaScriptHelper::TerminateScript($strControlScript); // Add comments for developer version of output if (!QApplication::$Minimize) { // Render a comment $strControlScript = _nl() . _nl() . sprintf('/*** EndScript -- Control Type: %s, Control Name: %s, Control Id: %s ***/', get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strControlScript); } $strEventScripts .= $strControlScript; } } // Include the javascripts specified by each control. if ($strScriptArray = $this->ProcessJavaScriptList($objControl->JavaScripts)) { QApplication::AddJavaScriptFiles($strScriptArray); } // Include any StyleSheets? The control would have a // comma-delimited list of stylesheet files to include (if applicable) if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) { QApplication::AddStyleSheets(array_keys($strScriptArray)); } // Form Attributes? if ($objControl->FormAttributes) { QApplication::ExecuteControlCommand($this->strFormId, 'attr', $objControl->FormAttributes); foreach ($objControl->FormAttributes as $strKey => $strValue) { if (!array_key_exists($strKey, $this->strFormAttributeArray)) { $this->strFormAttributeArray[$strKey] = $strValue; } else { if ($this->strFormAttributeArray[$strKey] != $strValue) { $this->strFormAttributeArray[$strKey] = $strValue; } } } } } // Add grouping commands to events (Used for deprecated drag and drop, but not removed yet) foreach ($this->objGroupingArray as $objGrouping) { $strGroupingScript = $objGrouping->Render(); if (strlen($strGroupingScript) > 0) { $strGroupingScript = JavaScriptHelper::TerminateScript($strGroupingScript); $strEventScripts .= $strGroupingScript; } } /*** Build the javascript block ****/ // Start with variable settings and initForm $strEndScript = sprintf('qc.initForm("%s"); ', $this->strFormId); // Register controls if ($strControlIdToRegister) { $strEndScript .= sprintf("qc.regCA(%s); \n", JavaScriptHelper::toJsObject($strControlIdToRegister)); } // Design mode event if (defined('__DESIGN_MODE__') && __DESIGN_MODE__ == 1) { // attach an event listener to the form to send context menu selections to the designer dialog for processing $strEndScript .= sprintf('$j("#%s").on("contextmenu", "[id]", function(event) { $j("#qconnectoreditdlg").trigger("qdesignerclick", [{id: event.target.id ? event.target.id : $j(event.target).parents("[id]").attr("id"), for: $j(event.target).attr("for")}] ); return false; } );', $this->FormId); } // Add any application level js commands. // This will include high and medimum level commands $strEndScript .= QApplication::RenderJavascript(true); // Add the javascript coming from controls and events just after the medium level commands $strEndScript .= ';' . $strEventScripts; // Add low level commands and other things that need to execute at the end $strEndScript .= ';' . QApplication::RenderJavascript(false); // Create Final EndScript Script $strEndScript = sprintf('<script type="text/javascript">$j(document).ready(function() { %s; });</script>', $strEndScript); /**** Render the HTML itself, appending the javascript we generated above ****/ foreach ($this->GetAllControls() as $objControl) { if ($objControl->Rendered) { $strHtml .= $objControl->GetEndHtml(); } $objControl->ResetFlags(); // Make sure controls are serialized in a reset state } $strHtml .= $strFormJsFiles . _nl(); // Add form level javascript files // put javascript environment defines up early for use by other js files. $strHtml .= '<script type="text/javascript">' . sprintf('qc.baseDir = "%s"; ', __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__) . sprintf('qc.jsAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __JS_ASSETS__) . sprintf('qc.phpAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __PHP_ASSETS__) . sprintf('qc.cssAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __CSS_ASSETS__) . sprintf('qc.imageAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __IMAGE_ASSETS__) . '</script>' . _nl(); $strHtml .= QApplication::RenderFiles() . _nl(); // add plugin and control js files // Render hidden controls related to the form $strHtml .= sprintf('<input type="hidden" name="Qform__FormId" id="Qform__FormId" value="%s" />', $this->strFormId) . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormControl" id="Qform__FormControl" value="" />') . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormEvent" id="Qform__FormEvent" value="" />') . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormParameter" id="Qform__FormParameter" value="" />') . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormCallType" id="Qform__FormCallType" value="" />') . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormUpdates" id="Qform__FormUpdates" value="" />') . _nl(); $strHtml .= sprintf('<input type="hidden" name="Qform__FormCheckableControls" id="Qform__FormCheckableControls" value="" />') . _nl(); // Serialize and write out the formstate $strHtml .= sprintf('<input type="hidden" name="Qform__FormState" id="Qform__FormState" value="%s" />', QForm::Serialize(clone $this)) . _nl(); // close the form tag $strHtml .= "</form>"; // Add the JavaScripts rendered above $strHtml .= $strEndScript; // close the body tag if ($this->blnRenderedBodyTag) { $strHtml .= '</body>'; } /**** Cleanup ****/ // Update Form Status $this->intFormStatus = QFormBase::FormStatusRenderEnded; // Display or Return if ($blnDisplayOutput) { if (!QApplication::$CliMode) { print $strHtml; } return null; } else { if (!QApplication::$CliMode) { return $strHtml; } else { return ''; } } }
/** * RenderOutput should be the last call in your custom RenderMethod. It is responsible for the following: * - Creating the wrapper if you are using a wrapper, or * - Possibly creating a dummy control if not using a wrapper and the control is hidden. * - Generating the control's output in one of 3 ways: * - Generate straight html if drawing the control as part of a complete page refresh * - Generate straight html if in an ajax call, but a parent is getting redrawn, which requires this * whole control to get drawn * - If in an ajax call and we are the top level control getting drawn, then generate special code that * out javascript will read and put into the control's spot on the page. Requires coordination with * the code in qcubed.js. * * @param string $strOutput * Your html-code which should be printed out * @param boolean $blnDisplayOutput * should it be printed, or just be returned? * * @return string */ protected function RenderOutput($strOutput, $blnDisplayOutput, $blnForceAsBlockElement = false) { if ($blnForceAsBlockElement) { $this->blnIsBlockElement = true; // must be remembered for ajax drawing } if ($this->blnUseWrapper) { if (!$this->blnVisible) { $strOutput = ''; } } else { if (!$this->blnVisible) { /* No wrapper is used and the control is not visible. We must enter a span with the control id and * display:none in order to be able change blnVisible to true in an Ajax call later and redraw the control. */ $strOutput = sprintf('<span id="%s" style="display:none;"></span>', $this->strControlId); } } switch ($this->objForm->CallType) { case QCallType::Ajax: if ($this->objParentControl) { if ($this->objParentControl->Rendered || $this->objParentControl->Rendering) { // If we have a ParentControl and the ParentControl has NOT been rendered, then output // as standard HTML if ($this->blnUseWrapper) { $strOutput = $this->RenderWrappedOutput($strOutput, $blnForceAsBlockElement) . $this->GetNonWrappedHtml(); } else { $strOutput = $strOutput . $this->GetNonWrappedHtml(); } } else { // Do nothing. RenderAjax will handle it. } } else { // if this is an injected top-level control, then we need to render the whole thing if (!$this->blnOnPage) { if ($this->blnUseWrapper) { $strOutput = $this->RenderWrappedOutput($strOutput, $blnForceAsBlockElement) . $this->GetNonWrappedHtml(); } else { $strOutput = $strOutput . $this->GetNonWrappedHtml(); } } } break; default: if ($this->blnUseWrapper) { $strOutput = $this->RenderWrappedOutput($strOutput) . $this->GetNonWrappedHtml(); } else { $strOutput = $strOutput . $this->GetNonWrappedHtml(); } $strOutput = $this->RenderComment(self::CommentStart) . _indent($strOutput) . $this->RenderComment(self::CommentEnd); break; } // Update watcher if ($this->objWatcher) { $this->objWatcher->MakeCurrent(); } $this->blnRendering = false; $this->blnRendered = true; $this->blnOnPage = true; // Output or Return if ($blnDisplayOutput) { print $strOutput; } else { return $strOutput; } }
/** * Display the help message * @return void */ public function showHelp() { $options = $this->getOptions(); if (count($options)) { _writeln('Usage:'); $usage = _indent() . $this->name . ' [options]'; if (count($this->arguments)) { $usage .= ' [<' . implode('>] [<', $this->argumentNames) . '>]'; } _writeln($usage); # Arguments if (count($this->arguments)) { _writeln(); _writeln('Arguments:'); $table = new ConsoleTable(); $table->hideBorder()->setPadding(2); foreach ($this->arguments as $arg) { $table->addRow(); $table->addColumn($arg['name']); $desc = $arg['description']; if ($arg['default']) { $desc .= ' [default: "' . $arg['default'] . '"]'; } $table->addColumn($desc); } $table->display(); } # Options if (count($options)) { _writeln(); _writeln('Options:'); $table = new ConsoleTable(); $table->hideBorder()->setPadding(2); foreach ($this->options as $name => $opt) { $table->addRow(); $table->addColumn($opt['key']); $desc = $opt['description']; if ($opt['default']) { $desc .= ' [default: "' . $opt['default'] . '"]'; } $table->addColumn($desc); } $table->display(); } if ($this->description) { _writeln(); _writeln('Help:'); _writeln(_indent() . $this->description); } } }