Help: Adding new association tutorial part I

thread: 5 messages  |  last: a year ago  |  started: saturday, february 20, 2010, 8:23 pm pst


#1  |  kingwithin (San Francisco, CA) United States of America
Saturday, February 20, 2010, 8:23 PM PST

I am seeking help to flesh out a tutorial for a pretty common action, which is adding a button to a form which results in an ajax-update, meaning the input value results in new output without refreshing the screen.

    protected $txtNewCode;
    protected $btnAddCode;   

I am going to have a text field in my template defined as $txtNewCode and the button that will submit that new code is $btnAddCode.

// Add a new Code
$this->txtNewCode = new QTextbox($this); //textfield
$this->btnAddCode = new QButton($this); //button
$this->btnAddCode->Text = QApplication::Translate('Add Code'); 
$this->btnAddCode->CssClass = 'button';
$this->btnAddCode->AddAction(new QClickEvent(), new QAjaxAction('btnAddCode_Click'));

This is all that is needed to actually needed to create the controls in the template.

We define btnAddCode_Click with the following:

protected function btnAddCode_Click($strFormId, $strControlId, $strParameter) {
        
  $objUser = unserialize($_SESSION['User']);    // grab user from session
        
  $groupCode = GroupCode::LoadBySignupCode($this->txtNewCode->Text);
    if (!$groupCode) {
          // If not found, create new group code and save it in DB
        $groupCode = new GroupCode();
            $groupCode->SignupCode = $this->txtNewCode->Text;
        $groupCode->Save();
     }
        
   $objUser->AssociateGroupCode($groupCode); //associate User with the entered code
        
  $this->objUser->Save();
}

I use the existing LoadBySignupCode for the model GroupCode by passing the value I just entered in the txtAddCode field.

If there's nothing there, I create a new one with the value and save it.

Then I associate it using AssociateGroupCode to the User.

Please provide additions and modifications for this before I go to step 2, which is to update the panel with the new value.

To notify the user that it has been a successful action, I added after the $this->objUser->Save() the following:

$this->lblMessage->Text ="Successfully entered code:" . $this->txtNewCode->Text;
$this->lblMessage->Display = True;

I define $this->lblMessage earlier in the QForm with:

// Notification Label
$this->lblMessage = new QLabel($this);
$this->lblMessage->Display = false;
$this->lblMessage->CssClass = "message";

This hides the message, but allows me to take care of all styling with the css class.

In the template, I use the following in the appropriate location and markup:

<?php $this->lblMessage->Render()?>
<?php $this
->txtNewCode->RenderWithError(); ?>
<?php $this
->btnAddCode->Render(); ?>

Each respectively with create the HTML for the message, the form field for the new code, and the button.

Questions for the tutorial:

1) Have I covered all possible edge-cases for a code that is entered?
2) How do I output in the template all the associated codes with that user?

#2  |  Mike Ho (Sunnyvale, CA) United States of America Qcodo Administrator
Sunday, February 21, 2010, 8:03 AM PST

Overall, it looks good.  For (1), depending on how you define these codes, you might want to trim() any whitespace and normalize on casing (e.g. are codes mixed-case, upper-case or lower-case?)

Assuming they are always supposed to be upper-case, and to answer question #2, assuming that you want that in your lblMessage, you should be able to do something like this:

protected function btnAddCode_Click($strFormId, $strControlId, $strParameter) {
    $objUser = unserialize($_SESSION['User']);    // grab user from session

    $strGroupCode = trim(strtoupper($this->txtNewCode->Text));
    $objGroupCode = GroupCode::LoadBySignupCode($strGroupCode);

    if (!$objGroupCode) {
        // If not found, create new group code and save it in DB
        $objGroupCode = new GroupCode();
        $objGroupCode->SignupCode = $strGroupCode;
        $objGroupCode->Save();
    }

    $objUser->AssociateGroupCode($objGroupCode); //associate User with the entered code

    // Update the display
    $this->lblMessage->Display = true;
    $this->lblMessage->HtmlEntities = false;
    $this->lblMessage->Text = 'Successfully added new code.  Codes are:<ul>';
    foreach ($objUser->GetGroupCodeArray() as $objGroupCode) {
        $this->lblMessage->Text .= '<li>' . $objGroupCode->SignupCode . '</li>';
    }
    $this->lblMessage->Text = '</ul>';
}

Note that I added a $obj prefix to your $groupCode above -- this is important because we now have two different groupCode variables defined in your method, one being the “cleaned up” string value, and the other being the object.  It also adds to some consistency, in case you wanted to be consistent with the Qcodo coding standards.

Lastly, you don't need to call Save() on the User.  Associate-based methods end up altering your _assn table, and doesn't touch any fields on the User table itself, therefore no ->Save() call is necessary.

Hope that makes sense, please post if you have any further questions...

#3  |  kingwithin (San Francisco, CA) United States of America
Tuesday, February 23, 2010, 9:35 PM PST

Thanks, nice work.  Your suggestions were also good in terms of coding practices for people who want to use Qcodo.

Going to write the next tutorial around panels.  Tried to see what was out there and wasn't much so may need some commentary on it.

Thanks, again, Mike.

#4  |  kingwithin (San Francisco, CA) United States of America
Friday, February 26, 2010, 9:59 AM PST

There's something funky with the way arrays are working, I have found this problem elsewhere.

I used your code exactly and it makes sense -- I have similar code that was also having problems:

    foreach ($objUser->GetGroupCodeArray() as $objGroupCode) {
        $this->lblMessage->Text .= '<li>' . $objGroupCode->SignupCode . '</li>';
    }

When I remove it, it updates the label properly.  But it doesn't display anything when I use this.

I have a feeling that I'm getting some kind of error traversing the array, but don't know how to identify the problem.

#5  |  Mike Ho (Sunnyvale, CA) United States of America Qcodo Administrator
Friday, February 26, 2010, 2:11 PM PST

What type of variable / field is SignupCode?

Please correct me if i'm wrong, but from your various posts, it does look like you're having some issues understanding some of the OO constructs of Qcodo and PHP.  If you don't have a lot of experience with OO programming and design, I would highly encourage you to read up some of the PHP-related documentation on OO (on php.net) as well as pick up a good book on OO programming... I think it will go a long way in helping you to understand a lot of the stuff that is going on.



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