Adding QForm instance to the cell of a QDataGrid

thread: 11 messages  |  last: a year ago  |  started: tuesday, february 23, 2010, 4:22 pm pst


#1  |  comradwt (Santa Monica, CA) United States of America
Tuesday, February 23, 2010, 4:22 PM PST

I'm new to the Qcodo API and I was wondering, what's the proper way to add a QForm to a cell of a QDataGrid component.  The examples that I have seen have been basic in nature but instructional on its use.  Next, the QForm that I'm wanting to add within a cell of each row should be a new instance of the QForm.  Thus, if any one has an example of such a construct, it would be greatly appreciated.

Thanks in advance,

-Conrad

#2  |  Mike Ho (Sunnyvale, CA) United States of America Qcodo Administrator
Tuesday, February 23, 2010, 6:17 PM PST

Unfortunately, no... but what functionality were you hoping to achieve by putting individual QForms into a DataGrid?

Usually, the same functionality can be had by using custom QPanels.  You can certainly place individual QPanels into a QDataGrid.

There is a specific examples page that discusses this in detail at http://examples.qcodo.com/examples/multiple_qform/intro.php

#3  |  comradwt (Santa Monica, CA) United States of America
Wednesday, February 24, 2010, 4:29 AM PST

In short, one needs to be able to enter information in the text field and submit the form for the selected row.  At this time, I have a Form with a QDataGrid inside of it.  I really don't understand why I have to use a QPanel instead of a QForm.  In short, I would like to be able to render a form instance in the grid cell for each row.

-Conrad



#4  |  Patrick Ranger (Montreal, Qc) Canada
Wednesday, February 24, 2010, 7:52 AM PST

Conrad,

This answer is also for the questions you posted in this thread.

I think a semantic precision has to be made here, for you can't have a QForm within a QDatagrid. QCodo only generates one FORM tag which somehow corresponds to the RenderBegin function in the template file. If I understand your question well, you want to have a QTextBox and a QButton within each row of a QDatagrid. Check out this example to achieve this : http://examples.qcodo.com/examples/dynamic/inline_editing.php. Hope this helps.

As for your issue “Accompanying HTML Include File does not exist”, you also need to edit your template file and edit the path at the bottom of your form which should look like this : YourFormName::Run('YourFormName', 'path/to/your/template/file/your_template.tpl.php');

patrick

#5  |  comradwt (Santa Monica, CA) United States of America
Wednesday, February 24, 2010, 12:43 PM PST

Patrick, I have decided to merge the QTextBox and QTextBox into QForm where the QDataGrid is located.  Thus, I have the following:

   public function OurForm_Render( Item $objItem ) {
     
     $strControlIdTextField = 'TextField' . $objAuctionItem->Id;
     $strControlIdButton    = 'Button' . $objAuctionItem->Id;
     
     // Let's see if the Form exists already.
     $TextField = $this->GetControl(  $strControlIdTextField );
     $Button = $this->GetControl(  $strControlIdButton );
     
     if ( !$TextField || !Button ) {
     
     // Create the text field.
       $TextField = new QTextBox( $this, $strControlIdTextField );
       
       // Create the button.
       $Button = new QButton( $this, $strControlIdButton );
         $Button->Text = 'Place Presale Bid?';
         $Button->Visible = true;
 
     }
     
         // What should one render here.
     return $TextField->Render( false );
     
   }

Now, I need to return both the text field and button so that they can be both rendered into the cells datagrid.  From the examples, I need to return something back to the calling program.  Thus, how does one achieve this

Thanks in advance,

-Conrad

#6  |  Patrick Ranger (Montreal, Qc) Canada
Wednesday, February 24, 2010, 1:19 PM PST

You are on the good path. The only thing is that you should render your QTextBox and QButton in 2 seperate columns, or at least by calling 2 seperate functions like this :

   public function TextBox_Render( Item $objItem ) {
     
     $strControlIdTextField = 'TextField' . $objAuctionItem->Id;
     
     // Let's see if the TextBox exists already.
     $TextField = $this->GetControl(  $strControlIdTextField );

     
     if ( !$TextField) {
        // Create the text field.
       $TextField = new QTextBox( $this, $strControlIdTextField ); 
     }
     
     // return the TextBox
     return $TextField->Render( false );
     
   }
   
   
   public function SaveButton_Render( Item $objItem ) {
     
     $strControlIdButton    = 'Button' . $objAuctionItem->Id;
     
     // Let's see if the button exists already.
     $Button = $this->GetControl(  $strControlIdButton );
     
     if ( !Button ) {
       // Create the button.
       $Button = new QButton( $this, $strControlIdButton );
       $Button->Text = 'Place Presale Bid?';
       $Button->Visible = true;
     }
     
    // Return the Button
     return $Button->Render( false );
     
   }
   

Let me know how it works out.

-Patrick

#7  |  comradwt (Santa Monica, CA) United States of America
Wednesday, February 24, 2010, 2:56 PM PST

Patrick, I have refactored things so that I have a single render method for each of the controls I need (i.e. text box and button).  Now, I have added the following:

if ( !$Button ) {
     // Create the button.
     $Button = new QButton( $this, $strControlIdButton );
     $Button->Text = 'Enter amount?';
     $Button->Visible = true;
     $Button->AddAction( new QClickEvent(), new QServerAction( 'Button_Click' ) );
     $Button->CausesValidation = true;

}

However, I need a confirmation dialog to fire when the button is clicked with a “OK” and “Cancel”.  When the user selects the OK button, the validation should take place but I need to have access to the entered value in the validate method.  Finally, the validation happens first but placing the code with Form_Validate method doesn't fire:

   protected function Form_Validate()
   {
     
     QApplication::DisplayAlert( 'Your bid has been placed.' );

       }


-Conrad



#8  |  Patrick Ranger (Montreal, Qc) Canada
Wednesday, February 24, 2010, 4:03 PM PST

Just add a QConfirmAction before the QServerAction that saves the form :

 if ( !$Button ) {
     // Create the button.
     $Button = new QButton( $this, $strControlIdButton );
     $Button->Text = 'Enter amount?';
     $Button->Visible = true;
     $Button->AddAction(new QClickEvent(), new QConfirmAction('Your message here'));
     $Button->AddAction( new QClickEvent(), new QServerAction( 'Button_Click' ) );
     $Button->CausesValidation = true;
}

For Form_Validate() to be fired, it depends on your architecture.  I guess since your button is within your datagrid, you need to access the Form_Validate() function of the parent object. Although I have never done this, I think you need to add $Button->CausesValidation = $this->objParentControl;. If from within the Form_Validate() function you want to access the value submitted, I think you need to access it with $this->YourDatagridObject->GetChildControl($controlID). Tell me about it.

-Patrick

#9  |  comradwt (Santa Monica, CA) United States of America
Wednesday, February 24, 2010, 5:49 PM PST

OK, I was able to add the confirmation dialog as expected.  However, I'm not 100% sure about accessing the control.  For example, the following doesn't generate errors and from the docs:

protected function getTextField() {
     
 $objItem = Item::LoadByItemId( $_ITEM->Id );
 return $this->dtgItem->GetChildControl( 'TextField' . $objItem->Id );
   
}

From the manual, $_ITEM is equivalent to the Item class.  Now, I'm seeing some errors that $_ITEM is undefined.

-Conrad

#10  |  Patrick Ranger (Montreal, Qc) Canada
Thursday, February 25, 2010, 11:20 AM PST

Yeah I think a misleaded you on this one. I'll try to give you a more complete answer here.

In the first place when you create your textboxes, you should have an array of textboxes so that you can access them later out of the scope of your function. Instead of

$TextField = new QTextBox( $this, $strControlIdTextField ); 

you would first declare a variable (in the form itself, not in a function), something like

protected $TextFieldArray;

and then when you create your textbox (note that the datagrid is the parent, not the form):

$this->TextFieldArray[$strControlIdTextField ] = new QTextBox($this->dtgItem, $strControlIdTextField ); 

Same thing when you create your button, but then you will add an ActionParameter to your button :

 if ( !$Button ) {
     // Create the button.
     $this->ButtonArray[strControlIdButton] = new QButton($this->dtgItem, $strControlIdButton );
     $this->ButtonArray[strControlIdButton]->ActionParameter = $strControlIdButton;
     $this->ButtonArray[strControlIdButton]->Text = 'Enter amount?';
     $this->ButtonArray[strControlIdButton]->Visible = true;
     $this->ButtonArray[strControlIdButton]->AddAction(new QClickEvent(), new QConfirmAction('Your message here'));
     $this->ButtonArray[strControlIdButton]->AddAction( new QClickEvent(), new QServerAction( 'Button_Click' ) );
     $this->ButtonArray[strControlIdButton]->CausesValidation = true;
}

Next, when you want to get the value of one of your TextFieldArray item, your function has to receive the parameters that are automatically send when your button is clicked and that you can optionally use.

protected function TextField_Save ($strFormId, $strControlId, $strParameter) {

 $strValueEntered = $this->TextFieldArray[$strParameter]->Text;
 
 $objItem = Item::LoadByItemId($strParameter);
 
 $objItem->YourDBfield = $strValueEntered;
 $objItem->Save();
   
}

Just a precision on $_ITEM : you can only access it within the scope of your Datagrid. Meaning if you want to use it outside of this scope, you need to pass it to the function you are calling from your datagrid column declaration, like this : $_FORM->SaveButton_Render($_ITEM). Then, your function SaveButton_Render ( Item $objItem ) can receive the the object and you can use $objItem->YourobjDBfield.

Hope this helps. Sorry for rounding corners in my previous posts.

-patrick



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