QDialogBox Error in 2.0
I am having an issue dynamically loading QPanels in a QDialogBox in QCubed version 2.0.1. When I click a control that triggers the QDialogBox the first time it renders properly, however when I close the QDialog and click a control to open it again the Dynamically loaded panel does not appear. After closing the second attempt and then clicking another control that triggers the panel the dynamic panel now appears again. Here is the simplified code. It is basically the same logic as the form drafts, except the edit panel is loaded into a QDialogBox rather than a QPanel. This code works in QCubed Version 1.1.2.
DialogTest.php
<?php
require_once('qcubed.inc.php');
class DialogTest extends QForm {
protected $pnlTopLeft;
protected $pnlTopCenter;
protected $pnlDialog;
protected $pnlEdit;
protected function Form_Create() {
$this->pnlDialog = new QDialogBox($this);
$this->pnlDialog->AutoRenderChildren = true;
$this->pnlTopLeft = new QPanel($this, 'TopLeft');
$this->pnlTopLeft->AutoRenderChildren = true;
$this->pnlTopCenter = new QPanel($this, 'TopCenter');
$this->pnlTopCenter->AutoRenderChildren = true;
$this->pnlEdit = new QPanel($this->pnlDialog, 'pnlEdit');
$this->pnlEdit->Text = 'PnlEdit Rendered';
$this->pnlEdit->AutoRenderChildren = true;
$pnlCompliance = new UserListPanel($this->pnlTopCenter, 'SetEditPane', 'CloseEditPane');
$pnlCBC = new VendorListPanel($this->pnlTopLeft, 'SetEditPane', 'CloseEditPane');
}
public function CloseEditPane($blnUpdatesMade) {
// Close the Edit Pane
$this->pnlEdit->RemoveChildControls(true);
$this->pnlDialog->HideDialogBox();
}
public function SetEditPane(QPanel $objPanel = null) {
$this->pnlEdit->RemoveChildControls(true);
if ($objPanel) {
$objPanel->SetParentControl($this->pnlEdit);
$this->pnlDialog->ShowDialogBox();
} else {
$this->pnlDialog->HideDialogBox();
}
}
}
DialogTest::Run('DialogTest');
?>DialogTest.tpl.php
<?php
include('includes/configuration/header.inc.php');
$this->RenderBegin();
$this->pnlDialog->Render();
$this->pnlTopLeft->Render();
$this->pnlTopCenter->Render();
$this->RenderEnd();
include('includes/configuration/footer.inc.php');
?>
Steven,
Would you mind testing this on trunk? I tried to test it myself, but I don't have your UserListPanel and VendorListPanel classes. If you can either provide these classes, or simplify the example above so it can run without them, I'll try to troubleshoot it.
-Vartan
I will do it off the sample Database when I get to the office. They could be replaced with any of the generated panel drafts.
I just did a fresh install of 2.0.1 and used the sample database to codegen.
I modified the panel_drafts.php code to use a QDialogBox for the edit panel.
To reproduce the error I did the following:
The modified panel_drafts.php code:
<?php
require_once('../qcubed.inc.php');
// Security check for ALLOW_REMOTE_ADMIN
// To allow access REGARDLESS of ALLOW_REMOTE_ADMIN, simply remove the line below
QApplication::CheckRemoteAdmin();
// Let's "magically" determine the list of genereated Class Panel Drafts by
// just traversing through this directory, looking for "*ListPanel.class.php" and "*EditPanel.class.php"
// Obviously, if you are wanting to make your own dashbaord, you should change this and use more
// hard-coded means to determine which classes' paneldrafts you want to include/use in your dashboard.
$objDirectory = opendir(__DOCROOT__ . __PANEL_DRAFTS__);
$strClassNameArray = array();
while ($strFile = readdir($objDirectory)) {
if ($intPosition = strpos($strFile, 'ListPanel.class.php')) {
$strClassName = substr($strFile, 0, $intPosition);
$strClassNameArray[$strClassName] = $strClassName . 'ListPanel';
require(__DOCROOT__ . __PANEL_DRAFTS__ . '/' . $strClassName . 'ListPanel.class.php');
require(__DOCROOT__ . __PANEL_DRAFTS__ . '/' . $strClassName . 'EditPanel.class.php');
}
}
class Dashboard extends QForm {
protected $lstClassNames;
protected $lblTitle;
protected $pnlList;
protected $pnlEdit;
protected function Form_Create() {
$this->lblTitle = new QLabel($this);
$this->lblTitle->Text = 'AJAX Dashboard';
$this->pnlList = new QPanel($this, 'pnlList');
$this->pnlList->AutoRenderChildren = true;
$this->pnlEdit = new QDialogBox($this, 'pnlEdit');
$this->pnlEdit->AutoRenderChildren = true;
$this->pnlEdit->Visible = false;
$this->lstClassNames = new QListBox($this);
$this->lstClassNames->AddItem('- Select One -', null);
// Use the strClassNameArray as magically determined above to aggregate the listbox of classes
// Obviously, this should be modified if you want to make a custom dashboard
global $strClassNameArray;
foreach ($strClassNameArray as $strKey => $strValue)
$this->lstClassNames->AddItem($strKey, $strValue);
$this->lstClassNames->AddAction(new QChangeEvent(), new QAjaxAction('lstClassNames_Change'));
$this->objDefaultWaitIcon = new QWaitIcon($this);
}
/**
* This Form_Validate event handler allows you to specify any custom Form Validation rules.
* It will also Blink() on all invalid controls, as well as Focus() on the top-most invalid control.
*/
protected function Form_Validate() {
// By default, we report that Custom Validations passed
$blnToReturn = true;
// Custom Validation Rules
// TODO: Be sure to set $blnToReturn to false if any custom validation fails!
$blnFocused = false;
foreach ($this->GetErrorControls() as $objControl) {
// Set Focus to the top-most invalid control
if (!$blnFocused) {
$objControl->Focus();
$blnFocused = true;
}
// Blink on ALL invalid controls
$objControl->Blink();
}
return $blnToReturn;
}
protected function lstClassNames_Change($strFormId, $strControlId, $strParameter) {
// Get rid of all child controls for list and edit panels
$this->pnlList->RemoveChildControls(true);
$this->pnlEdit->RemoveChildControls(true);
$this->pnlEdit->Visible = false;
if ($strClassName = $this->lstClassNames->SelectedValue) {
// We've selected a Class Name
$objNewPanel = new $strClassName($this->pnlList, 'SetEditPane', 'CloseEditPane');
$this->lblTitle->Text = $this->lstClassNames->SelectedName;
} else {
$this->lblTitle->Text = 'AJAX Dashboard';
}
}
/* public function SetListPane(QPanel $objPanel) {
$this->pnlList->RemoveChildControls(true);
$objPanel->SetParentControl($this->pnlList);
}*/
public function CloseEditPane($blnUpdatesMade) {
// Close the Edit Pane
$this->pnlEdit->RemoveChildControls(true);
$this->pnlEdit->Visible = false;
$this->pnlEdit->HideDialogBox();
// If updates were made, let's "brute force" the updates to the screen by just refreshing the list pane altogether
if ($blnUpdatesMade)
$this->pnlList->Refresh();
}
public function SetEditPane(QPanel $objPanel = null) {
$this->pnlEdit->RemoveChildControls(true);
if ($objPanel) {
$objPanel->SetParentControl($this->pnlEdit);
$this->pnlEdit->Visible = true;
$this->pnlEdit->ShowDialogBox();
} else {
$this->pnlEdit->Visible = false;
$this->pnlEdit->HideDialogBox();
}
}
}
Dashboard::Run('Dashboard');
?>
I'm having the same problem with 2.0.
I had a similar problem.
Ok, I can reproduce it on trunk as well. If you get a chance please open a ticket (and maybe attach your modified panel_drafts.php).
Created ticket #640.
I added a patch on that ticket, which fixes the main problem, but for some reason results in a dialog box with the wrong height. So after the patch the "height: auto" does not work properly (one has to manually resize the dialog box to see the controls). Can anyone figure out why?
-Vartan
Guys,
I just added a new patch for this ticket, which I think fully fixes the problem. I'd appreciate if you can test it and report any abnormalities you see. It would really help us with the stable release, which has been held back by this ticket for several weeks now.
Thanks.
-Vartan