QCubed - A PHP5 rapid development MVC framework.
Home  |  Updates

tutorial

Screencasts

First Steps with the Framework

splash.png splashFromScratch.png debuggingSplash.png
One: Intro to User
Interface Framework
Two: Building QForms from Scratch,
thru an example of a login page
Three: Debugging QCubed
Applications: JavaScript, SQL, PHP
mvc_thumb.png db_modelling_thumb.png
Four: Model-View-Controller (MVC)
in QCubed
Five: Data Modeling -
One-to-Many and Many-to-Many

Installation and Configuration of QCubed

splashInstall.png pluginSplash.png
Initial Configuration of QCubed (v1.1+) Installing Plugins

Tutorial - Nested QDataGrid The How To?

Hi everyone, as my first contribution to the community of qcubed I will explain and demonstrate how to create a nested QDatagrid.

With a MAster QDatagrid and through a button, usually a '+'to prove they can expand, appear a Child QDataGrid with other content as you can see in the screen_1.jpg attach.

Some preconceptions to consider first are:

- Master QDataGrid should go on the FORM.
- Child must be in QPanel QDataGrid (I like it better to say that the style created as User Controls. NET)
- We must always know who are the children and parents the QDataGrids.
- HtmlEntities in QdataGrid always 'False'. I Expend two days looking for this error =P.

Let's start ...

First we need to create the Master QDataGrid...

<?php
   
// Load the QCubed Development Framework
   
require ('../../qcubed.inc.php');

       
// Load User Controls -> This is the First Child QDataGrid.
        // It be  explian later, at the moment the only you need to know is
        // it was created like a .NET User Control and extends from a QPanel.
       
require (__APP_CONTROLS__ . '/records.summary.php');

       
        class
DomainList extends QForm {

               
// Datagrid List Control for Domains
               
protected $dtgDomains;

               
// This is for refresh the QDataGrid and make appear the childs
                // Datagrid becaouse i use ajax.
               
protected function Form_PreRender() {
                   
parent::Form_PreRender();

                   
$this->dtgDomains->Refresh();
                }

                protected function
Form_Create() {
                   
parent::Form_Create();

                   
// Create the Master DataGrid
                    // I make derived from another QDataGrid but is just for
                    // apply styles css, nothing important

                   
$this->dtgDomains = new DomainGridControl($this);
                   
$this->dtgDomains->SetDataBinder('dtgDomains_Bind');

                   
// Here we start, create our first control a simple toogle
                    // button
                   
$this->dtgDomains->AddColumn(
                            new
QDataGridColumn('','<?= $_FORM->render_btnToggleRecordsSummary($_ITEM) ?>
','HtmlEntities=false', 'Width=1px'));

                    // And some other data columns...
                    $this->dtgDomains->MetaAddColumn(QQN::Domains()->Zone,'Name=Domain',
                            array('OrderByClause' => QQ::OrderBy(QQN::Domains()->Zone),
                                  'ReverseOrderByClause' => QQ::OrderBy(QQN::Domains()->Zone, false))
                           );

                    // Second... we need to create out Child QDataGrid sp put them
                    // hide in a column.
                    $this->dtgDomains->AddColumn(
                            new QDataGridColumn('','<?= $_FORM->render_ucRecordsSummary($_ITEM) ?>','HtmlEntities=false','Width=1px'));
                }

                public function dtgDomains_Bind() {
                    // Bind... nothing important...
                }

                // Function to render our toggle button column
                // As you can see we pass as a parameter the item binded in the
                // row of QDataGrid
                public function render_btnToggleRecordsSummary(Domains $objDomain) {

                    // Create their unique id...
                    $objControlId = 'btnToggleRecordsSummary' . $objDomain->Id;

                    if (!$objControl = $this->GetControl($objControlId)) {

                        // If not exists create our toggle button who his parent
                        // is our master QDataGrid...
                        $objControl = new QButton($this->dtgDomains, $objControlId);
                        $objControl->Text = '+';
                        $objControl->CssClass = 'inputbutton';

                        // Pass the id of the bounded item just for other process
                        // on click event

                        $objControl->ActionParameter = $objDomain->Id;

                        // Add event on click the toogle button
                        $objControl->AddAction(new QClickEvent(), new QAjaxAction('btnToggleRecordsSummary_Click',$this->dtgDomains->WaitIcon));
                    }

                    // We pass the parameter of "false" to make sure the control doesn't render
                    // itself RIGHT HERE - that it instead returns its string rendering result.
                    return $objControl->Render(false);
                }


                // Clicking the toogle button...
                public function btnToggleRecordsSummary_Click($strFormId, $strControlId, $strParameter) {

                    // First get the button himself for change '+' to '-'
                    $srcControl = $this->GetControl($strControlId);

                    $intDomainId = intval($strParameter);

                    // Look for our child QDatagrid if is render...
                    $objControlId = 'ucRecordsSummary' . $intDomainId;
                    $objControl = $this->GetControl($objControlId);

                    if ($objControl) {
                        // Ask if our Child DataGrid is visible...
                        if ($objControl->Visible) {
                            // Make it desapear ...
                            $objControl->Visible = false;
                            $srcControl->Text = '+';
                        } else {
                            // Or make it appear...
                            $objControl->Visible = true;
                            $srcControl->Text = '-';
                        }

                        // Important! Refresh the parent QDataGrid...
                        $this->dtgDomains->Refresh();
                    }                   
                }

                // Ladys and Gentleman... Our Child QDataGrid... =P
                public function render_ucRecordsSummary(Domains $objDomain) {

                    $objControlId = 'ucRecordsSummary' . $objDomain->Id;

                    if (!$objControl = $this->GetControl($objControlId)) {

                        // Create the User Control Child QDataGrid passing the
                        // parent, in this case Master QDataGrid and the unique id.
                        $objControl = new RecordsSummary($this->dtgDomains, $objDomain, $objControlId);

                        //Put invisible at the begging, the toogle button gona do
                        //the job
                        $objControl->Visible = false;
                    }

                    return $objControl->Render(false);
                }
        }

DomainList::Run('DomainList', __APP_VIEW_ACCOUNT__ . '/domain.list.tpl.php');
?>

Well thats all for the Master QDataGrid, at here everythings looks normal uh?

ok here is the Child QDataGrid...

<?php
       
// Load the QCubed Development Framework
       
require_once('../../qcubed.inc.php');

       
// Load User Controls -> Load Other QDataGrids Child of this one
        // This is not awseome? QdataGrid can do everything!!
       
require (__APP_CONTROLS__ . '/a.records.list.php');
        require (
__APP_CONTROLS__ . '/cname.records.list.php');
        require (
__APP_CONTROLS__ . '/mx.records.list.php');
        require (
__APP_CONTROLS__ . '/srv.records.list.php');
        require (
__APP_CONTROLS__ . '/spf.records.list.php');


       
// As you can see thie QDataGrid extends the QPanel not a QForm
       
class RecordsSummary extends QPanel {

               
// QDatagrid Records Summary
               
public $dtgRecordsSummary;

               
// dtgDomains -> this is our Master QDataGrid
               
protected $objParentObject;

               
// Protected Objects
               
protected $objDomain;
           
               
// in the contructor pass the item bounded too just for other
                // process
               
public function __construct($objParentObject, Domains $objDomain, $strControlId = null) {

                    try {
                       
                       
parent::__construct($objParentObject, $strControlId);
                       
                       
// Watch out for template later gonna talk about it,
                        // need a trick to look good.
                       
$this->Template = __APP_CONTROLS__ . '/records.summary.tpl.php';

                       
// Setting local the MAster QDataGrid to refresh on
                        // Saves on the Child DataGrid..
                       
$this->objParentObject = $objParentObject;
                       
$this->objDomain = $objDomain;
                      
                       
// Create the child DataGrid as a simply...QDataGrid
                        // normal
                       
$this->dtgRecordsSummary = new QDataGrid($this);
                       
                       
// Bind him, the normal...
                       
$this->dtgRecordsSummary->SetDataBinder('dtgRecordsSummary_Bind', $this);

                       
// Need another Child QDataGrid? ok add their toogle
                        // button...
                       
$this->dtgRecordsSummary->AddColumn(
                            new
QDataGridColumn('','<?= $_CONTROL->ParentControl->render_btnToggleRecords($_CONTROL, $_ITEM) ?>
','HtmlEntities=false', 'Width=1px'));

                       // Add some QDataGrid data to show...
                        $this->dtgRecordsSummary->AddColumn(
                            new QDataGridColumn('', '<?= $_ITEM . " Records" ?>'));
                       // Add if you need another column with the other child QDataGrid to show if you need
                        $this->dtgRecordsSummary->AddColumn(
                            new QDataGridColumn('','<?= $_CONTROL->ParentControl->render_ucRecords($_CONTROL, $_ITEM) ?>','HtmlEntities=false','Width=1px'));
                       
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }
                }

                public function dtgRecordsSummary_Bind() {
                   //Bind...
                }

                // Render other toggle...
                public function render_btnToggleRecords($parControl, $strType) {

                    $strControlId = 'btnToggleRecords' . $this->objDomain->Id . $strType;

                    if (!$objControl = $parControl->GetChildControl($strControlId)) {
                        // But in this case the parent control of the button
                        // woluld be this child QDataGrid, dont forget that...
                        $objControl = new QButton($parControl, $strControlId);
                        $objControl->Text = '+';
                        $objControl->CssClass = 'inputbutton';
                        $objControl->ActionParameter = $strType;

                        // Important! for a better coding we want to all
                        // actions referer to the child QdataGris stay
                        // in the child Qdatagrid, so the actions are now
                        // QAjaxControlAction or QServerControlAction, were the
                        // controlId parameter is $this, becaouse in $this class
                        // is defined the event for this button... kind of easy,
                        // and clean.

                        $objControl->AddAction(new QClickEvent(), new QAjaxControlAction($this,'btnToggleRecords_Click',$this->objParentObject->WaitIcon));
                    }

                    // We pass the parameter of "false" to make sure the control doesn't render
                    // itself RIGHT HERE - that it instead returns its string rendering result.
                    return $objControl->Render(false);
                }

                // Button press make other child QDataGrid Appear..
                public function btnToggleRecords_Click($strFormId, $strControlId, $strParameter) {

                    $srcControl = $this->Form->GetControl($strControlId);
                    $parControl = $srcControl->ParentControl;
                    $strType = $strParameter;

                    $objControlId = 'ucRecords' . $this->objDomain->Id . $strType;
                   
                    if ($objControl = $parControl->GetChildControl($objControlId)) {
                        if ($objControl->Visible) {
                            $objControl->Visible = false;
                            $srcControl->Text = '+';
                        } else {
                            $objControl->Visible = true;
                            $srcControl->Text = '-';
                        }
                       
                        // And refresh the Child QdataGrid this time...
                        $this->dtgRecordsSummary->Refresh();
                    }
                }

                // Create another child if you want... follow the same exactly
                // idea as applid in Master QdataGrid...
                public function render_ucRecords($parControl, $strType) {

                    $strControlId = 'ucRecords' . $this->objDomain->Id . $strType;

                    if (!$objControl = $parControl->GetChildControl($strControlId)) {

                        switch ($strType) {

                            case Records::A :
                                $objControl = new ARecordsList($this->dtgRecordsSummary, $this->objDomain, $strControlId);
                                break;

                            case Records::CNAME :
                                $objControl = new CNAMERecordsList($this->dtgRecordsSummary, $this->objDomain, $strControlId);
                                break;

                            case Records::MX :
                                $objControl = new MXRecordsList($this->dtgRecordsSummary, $this->objDomain, $strControlId);
                                break;

                            case Records::SRV :
                                $objControl = new SRVRecordsList($this->dtgRecordsSummary, $this->objDomain, $strControlId);
                               
                                break;

                            case Records::SPF :
                                $objControl = new SPFRecordsList($this->dtgRecordsSummary, $this->objDomain, $strControlId);
                                break;

                            default:
                                $objControl = new QDataGrid($parControl);
                                break;
                        }

                        $objControl->Visible = false;
                    }
                   
                    return $objControl->Render(false);
                }
        }
?>

As i say before the tpl.php file has a trick to show good we need to break the row of qdatagrid to show pretty and not break the html...

here is the code

        </td>
    </tr>
    <tr>
        <td colspan="6">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tr>
                    <td><?php $_CONTROL->dtgRecordsSummary->Render(); ?></td>
                </tr>
            </table>
         </td>
    </tr>
    <tr>
        <td>

Well thats it, the QDataGrid, hope must be usefull for someone it was for me.

In next post gonna expand this and make it with inline editing.

Regards,

JMI

ereg_replace deprecated

Is there an update to the wiki tutorial for 1.1. I pretty much figured out everything, except that ereg_replace has been deprecated. I haven't figured out how to exchange it for preg_replace.

Screencast - Installing Plugins

I just finished a second video tutorial on how to install plugins. It is meant for those new to QCubed.

http://www.youtube.com/watch?v=NSfb2u643cM

Screencast - installing QCubed 1.1

An earlier thread had asked for volunteers to start making screencast http://qcu.be/content/screencasts. Well the wife is under the weather and I can't sleep so I was able to throw together a quick video tutorial on installing QCubed 1.1.

The file is 5Mb so a little large to install here so I posted it to YouTube. YouTube's compression seems to have lessoned the quality considerably so it would probably be better posted here.

http://www.youtube.com/watch?v=ucl-mUI_b9s

Screencast - Introduction to QCubed - Part 4

Screencast - Introduction to QCubed - Part 3

Screencast - Introduction to QCubed - Part 2

Screencast - Introduction to QCubed - Part 1