How to properly save children panels from the parent panel?

thread: 6 messages  |  last: a year ago  |  started: monday, march 1, 2010, 11:19 am pst


#1  |  comradwt (Santa Monica, CA) United States of America
Monday, March 1, 2010, 11:19 AM PST

I have a parent QPanel which has 2 children QPanels.  Furthermore, the parent QPanel has a save button.  Thus, parent panel looks as follows:


class MyPanel extends QPanel 
{
    public $panel1;
    public $panel2;
    public $btnSave;

    public function __construct( $objParentObject, 
                                     $strPanelRightControlId = null, 
                                     $strControlId = null )
    {
        //call the parent's constructor first
        try {
            parent::__construct($objParentObject, $strControlId );
        } catch (QCallerException $objExc) {
            $objExc->IncrementOffset();
            throw $objExc;
        }
        
        $strDraftsPath = sprintf(__DRAFTS__, 'default');
        $this->strTemplate = $strDraftsPath . '/my_panel.tpl.php';
        
    $objFc = Zend_Controller_Front::getInstance();
    $intId = User::AutoloadId();
    
    $this->panel1 = new Panel1( $this, $intId, 'panel1');
    $this->panel2 = new Panel2( $this, $intId, 'panel2');
    $this->btnSave_Create();
}
    
public function btnSave_Create() 
{
  $this->btnSave = new QButton($this);
  $this->btnSave->Text = 'Save These Changes';
  $this->btnSave->AddAction( new QClickEvent(), 
                             new QServerControlAction( $this, 'btnSave_Click' ) );
  $this->btnSave->CausesValidation = $this;            
}

public function btnSave_Click()
{
  $this->panel1->btnSave_Click();
  $this->panel2->btnSave_Click();
}

Next, each child panel has its own validation and initialization methods but when I click the save button, the information in panel1 doesn't get properly saved.  If anyone has any ideas as to how to resolve this, please feel free to post.

Thanks in advance,

-Conrad

#2  |  kentpachi (France, EU) France
Tuesday, March 2, 2010, 4:35 AM PST

Try to change the causes validation to

1.

$this->btnSave->CausesValidation =  QCausesValidation::SiblingsAndChildren;

2.
What do you have in btn_saveClick of the children panel1 and 2 ?

3. check if your function btnsave_click in “mypanel” is called

plus if panel1 and 2 has the same method as “mypanel” make sure they have as child another panel1 and panel2

show us the class Panel1 and Panel2


kent

#3  |  comradwt (Santa Monica, CA) United States of America
Tuesday, March 2, 2010, 4:47 AM PST

Panel1.php:


class Panel1 extends QPanel
{
  const MsgPasswordNotMatch = "The passwords do not match";
  const ScreenNameExist = "Screen Name already exist";
  const DEBUG = false;

  protected $strTemplate = '';
  protected $objUser;

  public $lblError;
  public $txtFirstName;
  public $txtLastName;
  public $lblEmail;
  public $txtPword;
  public $txtConPword;
  public $txtScreenName;
  public $btnSave;

  public function __construct($objParentObject, $intUserId, $strControlId = null) 
  {
    try {
      parent::__construct($objParentObject, $strControlId);
    } catch (QCallerException $objExc) {
      $objExc->IncrementOffset();
      throw $objExc;
    }
    
    $this->objUser = User::Load( $intUserId );

    $drafts = sprintf( __DRAFTS__, 'default' );
    $this->strTemplate = $drafts . '/panel1.tpl.php';

    $this->lblError_Create();
    $this->txtFirstName_Create();
    $this->txtLastName_Create();
    $this->lblEmail_Create();
    $this->btnSave_Create();
    $this->txtPword_Create();
    $this->txtConPword_Create();
    $this->txtScreenName_Create();
    $this->init();
  }
  
  protected function init() 
  {
    if ($this->objUser) {
      $this->lblEmail->Text = $this->objUser->Email;
      $this->txtFirstName->Text = $this->objUser->FirstName;
      $this->txtLastName->Text = $this->objUser->LastName;
      $this->txtPword->Text = Security::Decrypt($this->objUser->Pword);
      $this->txtConPword->Text = $this->txtPword->Text;
      $this->txtScreenName->Text = $this->objUser->ScreenName;
    }
  }

  public function Validate()
  {
    
    if ( self::DEBUG ) {
      print "DEBUG:  Entering Validate method <br />";
    }
    
    $blnReturn = true;
    $strError = '';
    foreach($this->ValidateChildren() as $objControl) {

      if ($objControl->ValidationError) {
        $strError .= $objControl->ValidationError . '<br />';
      } else if ($objControl->Warning) {
        $strError .= $objControl->Warning . '<br />';
      }
    } 

    if ( strlen($strError) > 0 ) {
      $blnReturn = false;
    } else {
      if (strcasecmp($this->txtPword->Text, $this->txtConPword->Text) !== 0) {
        $strError .= self::MsgPasswordNotMatch . '<br />';
        $blnReturn = false;
      }
      if ( strlen( $this->txtScreenName->Text ) > 0 && 
        strcasecmp( $this->objUser->ScreenName, $this->txtScreenName->Text)  !== 0 && 
      User::ScreenNameExist($this->txtScreenName->Text)) {
        $strError .= self::ScreenNameExist . '<br />';
        $blnReturn = false;
      }
    }
    $this->lblError->Text = $strError;    
    QApplication::ExecuteJavaScript( sprintf('qcodo.getControl("%s").focus()', 
                                     $this->txtFirstName->ControlId ) );
    
    if ( self::DEBUG ) {
       print "DEBUG:  Validate:  " .  $blnReturn . "<br />";   
    }                                                            
                                     
    return $blnReturn;   
  }     

  public function ValidateChildren( $blnErrorsOnly = false )
  {
    
    if ( self::DEBUG ) {
      print "DEBUG:  Entering ValidateChildren <br />";
    }
    
    $objToReturn = array();
    foreach($this->GetChildControls() as $objControl) {        
      if (!$objControl->Validate()) {
        array_push($objToReturn, $objControl);
      }
    }
    
    return $objToReturn;
  }
  
  public function lblError_Create()
  {
    $this->lblError = new QLabel($this);
    $this->lblError->Name = 'Error';
    $this->lblError->HtmlEntities = false;
    $this->lblError->CssClass =  'error';
  }
  
  public function txtFirstName_Create() 
  {
    $this->txtFirstName = new QTextBox($this);
    $this->txtFirstName->Required = true;
    $this->txtFirstName->Name = 'First Name';
  }
  
  public function txtLastName_Create() 
  {
    $this->txtLastName = new QTextBox($this);
    $this->txtLastName->Required = true;
    $this->txtLastName->Name = 'Last Name';
  }
  
  public function lblEmail_Create() 
  {
    $this->lblEmail = new QLabel($this);
    $this->lblEmail->Name = 'Email'; 
  }
  
  public function btnSave_Create()
  {
    $this->btnSave = new QButton($this);
    $this->btnSave->Text = 'Save Changes';
    $this->btnSave->AddAction( new QClickEvent(),
      new QServerControlAction( $this, 'btnSave_Click' ) );
    $this->btnSave->CausesValidation = $this;            
  }
  
  public function txtPword_Create() 
  {
    $this->txtPword = new QTextBox($this);
    $this->txtPword->Required = true;
    $this->txtPword->TextMode = QTextMode::Password;
    $this->txtPword->Name = 'Password';
  }
  
  public function txtConPword_Create() 
  {
    $this->txtConPword = new QTextBox($this);
    $this->txtConPword->Required = true;
    $this->txtConPword->TextMode = QTextMode::Password;
    $this->txtConPword->Name = 'Confirm Password'; 
  }
  
  public function txtScreenName_Create() 
  {
    $this->txtScreenName = new QTextBox($this);
    $this->txtScreenName->Required = true;
    $this->txtScreenName->Name = 'Screen Name'; 
  }
  
  public function btnSave_Click()
  {
    $currentUser = $this->objUser;
    $currentUser->FirstName = $this->txtFirstName->Text;
    $currentUser->LastName = $this->txtLastName->Text;
    $currentUser->Pword = Security::Encrypt($this->txtPword->Text);
    $currentUser->ScreenName = $this->txtScreenName->Text;
    
      if ( self::DEBUG ) { 
        echo 'Before Save:  $this->objUser->Id: ' . $this->objUser->Id . '<br />';
        echo 'Before Save:  $currentUser->FirstName: ' . $currentUser->FirstName . '<br />';
        echo 'Before Save:  $currentUser->LastName: ' . $currentUser->LastName . '<br />'; 
        echo 'Before Save:  $currentUser->ScreenName: ' . $currentUser->ScreenName . '<br />'; 
      }
    
    // Update this user's account information.
    $currentUser->Save();  // The issue appears to be with this save method.
    
     if ( self::DEBUG ) { 
        echo 'After Save:  $this->objUser->Id: ' . $this->objUser->Id . '<br />';
        echo 'After Save:  $currentUser->FirstName: ' . $currentUser->FirstName . '<br />';
        echo 'After Save:  $currentUser->LastName: ' . $currentUser->LastName . '<br />'; 
        echo 'After Save:  $currentUser->ScreenName: ' . $currentUser->ScreenName . '<br />'; 
      }
    
  }

}

The issues that I was having with Panel2 has been resolved.  Now, Panel1 simply doesn't want to save the data to the database.

-Conrad

#4  |  comradwt (Santa Monica, CA) United States of America
Thursday, March 4, 2010, 8:51 PM PST

Hi, I added the following in my parent panel.  However, it didn't resolve the issue that I was seeing:


$this->btnSave->CausesValidation =  QCausesValidation::SiblingsAndChildren;

Also, there's no feedback from the following whether the save returned false or true.


$this->objUser->Save(); // This should simply save but doesn't.

or

$this->objUser->Save(false,true);  //  This should force an update but doesn't.

Thus, I'm thinking that it might be best to write raw SQL instead of attempting
debug what Qcodo does and doesn't do at this point.

-Conrad

#5  |  Mike Ho (Sunnyvale, CA) United States of America Qcodo Administrator
Sunday, March 7, 2010, 1:22 PM PST

conrad,

out of curiosity, is there a difference between trying to call save() on an existing record (e.g. so it should be UPDATE-ing an existing row) vs. trying to call save() on a new record (e.g. so it should be INSERT-ing a new row)?

#6  |  comradwt (Santa Monica, CA) United States of America
Sunday, March 7, 2010, 2:51 PM PST

Mike, it should be updating an existing row.  In any case, I was able to determine that the update action did take place in Panel1.  However, it was be overwritten by another update on the same table.  Thus, I refactored the code above as follows:

// Reload the object from the database.
$this->objUser->Reload();

// Set the relevant fields.
$this->objUser->FirstName = $this->txtFirstName->Text;
$this->objUser->LastName = $this->txtLastName->Text;
$this->objUser->Pword = Security::Encrypt( $this->txtPword->Text );
$this->objUser->ScreenName = $this->txtScreenName->Text;

// Update the database for this user.
$this->objUser->Save(false,true);

Note:  I had to add the reload to the other panels that made changes to the user table within the form.

-Conrad



Copyright © 2005 - 2012, Quasidea Development, LLC
This open-source framework for PHP is released under the terms of The MIT License.