1: <?php
2: class ProjectViewPanel extends QPanel {
3: // Child Controls must be Publically Accessible so that they can be rendered in the template
4: // Typically, you would want to do this by having public __getters for each control
5: // But for simplicity of this demo, we'll simply make the child controls public, themselves.
6: public $pnlTitle;
7: public $dtgMembers;
8: public $btnEditProject;
9: public $txtBlah;
10:
11: // The Local Project object which this panel represents
12: protected $objProject;
13:
14: // The Reference to the Main Form's "Right Panel" so that this panel
15: // can make changes to the right panel on the page
16: protected $strPanelRightControlId;
17:
18: // Specify the Template File for this custom QPanel
19: protected $strTemplate = 'ProjectViewPanel.tpl.php';
20:
21: // Customize the Look/Feel
22: protected $strPadding = '10px';
23: protected $strBackColor = '#fefece';
24:
25: // We Create a new __constructor that takes in the Project we are "viewing"
26: // The functionality of __construct in a custom QPanel is similar to the QForm's Form_Create() functionality
27: public function __construct($objParentObject, $objProject, $strPanelRightControlId, $strControlId = null) {
28: // First, let's call the Parent's __constructor
29: try {
30: parent::__construct($objParentObject, $strControlId);
31: } catch (QCallerException $objExc) {
32: $objExc->IncrementOffset();
33: throw $objExc;
34: }
35:
36: // Next, we set the local project object
37: $this->objProject = $objProject;
38:
39: /* Let's record the reference to the form's RightPanel
40: * Note: this ProjectViewPanel needs the reference to the main form's RightPanel so that it can
41: * "update" the RightPanel's contents during the ProjectViewPanel's event handlers (e.g., when the user
42: * click's "Edit" on a Person, this ProjectViewPanel's btnEdit_Click handler will update RightPanel
43: * to display the PersonEditPanel panel.
44: *
45: * HOWEVER, realize that this interaction can be done many different ways.
46: * A very suitable alternative would be for this __construct to take in a public method name from the Form instead
47: * of $strPanelRightControlId. And btnEdit_Click, instead of updating the right panel directly, could simply
48: * make a call to the Form's method, and the interaction could be defined on the Form itself.
49: *
50: * This design decision depends on how tightly coupled the custom panels are together, or if each panel
51: * is to be more independent and you want the Form to define the interaction only. So it would depend on how
52: * the developer would want to do it.
53: *
54: * We show an example of accessing the RightPanel direclty in ProjectViewPanel, and we show examples
55: * of MethodCallbacks on the Form in ProjectEditPanel and PersonEditPanel.
56: */
57: $this->strPanelRightControlId = $strPanelRightControlId;
58:
59: // Let's set up some other local child control
60: // Notice that we define the child controls' parents to be "this", which is this ProjectViewPanel object.
61: $this->pnlTitle = new QPanel($this);
62: $this->pnlTitle->Text = $objProject->Name;
63: $this->pnlTitle->CssClass = 'projectTitle';
64:
65: $this->btnEditProject = new QButton($this);
66: $this->btnEditProject->Text = 'Edit Project Name';
67: $this->btnEditProject->AddAction(new QClickEvent(), new QAjaxControlAction($this, 'btnEditProject_Click'));
68:
69: // Now, let's set up this custom panel's child controls
70: $this->dtgMembers = new QDataGrid($this);
71: $col = $this->dtgMembers->CreateNodeColumn('ID', QQN::Person()->Id);
72: $col->CellStyler->Width = 30;
73: $col = $this->dtgMembers->CreateNodeColumn('First Name', QQN::Person()->FirstName);
74: $col->CellStyler->Width = 120;
75: $col = $this->dtgMembers->CreateNodeColumn('Last Name', QQN::Person()->LastName);
76: $col->CellStyler->Width = 120;
77: $col = $this->dtgMembers->CreateCallableColumn('Edit', [$this, 'EditColumn_Render']);
78: $col->HtmlEntities = false;
79:
80:
81: // Let's make sorting Ajax-ified
82: $this->dtgMembers->UseAjax = true;
83:
84: // Finally, we take advantage of the DataGrid's SetDataBinder to specify the method we use to actually bind
85: // a datasource to the DataGrid
86: $this->dtgMembers->SetDataBinder('dtgMembers_Bind', $this);
87: }
88:
89: // This is the method that will perform the actual databinding on the dtgMembers datagrid
90: // Note that because it is called by the QForm, this needs to be public
91: public function dtgMembers_Bind() {
92: $this->dtgMembers->DataSource = $this->objProject->GetPersonAsTeamMemberArray(QQ::Clause($this->dtgMembers->OrderByClause));
93: }
94:
95: // DataGrid Render Handlers Below
96: public function EditColumn_Render(Person $objPerson) {
97: // Let's specify a specific Control ID for our button, using the datagrid's CurrentRowIndex
98: $strControlId = 'btnEditPerson' . $this->dtgMembers->CurrentRowIndex;
99:
100: $btnEdit = $this->objForm->GetControl($strControlId);
101: if (!$btnEdit) {
102: // Only create/instantiate a new Edit button for this Row if it doesn't yet exist
103: $btnEdit = new QButton($this->dtgMembers, $strControlId);
104: $btnEdit->Text = 'Edit';
105:
106: // Define an Event Handler on the Button
107: // Because the event handler, itself, is defined in the control, we use QAjaxControlAction instead of QAjaxAction
108: $btnEdit->AddAction(new QClickEvent(), new QAjaxControlAction($this, 'btnEditPerson_Click'));
109: }
110:
111: // Finally, update the Actionparameter for our button to store the $objPerson's ID.
112: $btnEdit->ActionParameter = $objPerson->Id;
113:
114: // Return the Rendered Button Control
115: return $btnEdit->Render(false);
116: }
117:
118: // Event Handlers Here
119: public function btnEditPerson_Click($strFormId, $strControlId, $strParameter) {
120: // Get pnlRight from the Parent Form
121: $pnlRight = $this->objForm->GetControl($this->strPanelRightControlId);
122:
123: // First, remove all children panels from pnlRight
124: $pnlRight->RemoveChildControls(true);
125:
126: // Now create a new PersonEditPanel, setting pnlRight as its parent
127: // and specifying parent form's "CloseRightPanel" as the method callback
128: // See the note in _constructor, above, for more information
129: $objPersonToEdit = Person::Load($strParameter);
130: new PersonEditPanel($pnlRight, $objPersonToEdit, 'CloseRightPanel');
131: }
132:
133: public function btnEditProject_Click($strFormId, $strControlId, $strParameter) {
134: // Get pnlRight from the Parent Form
135: $pnlRight = $this->objForm->GetControl($this->strPanelRightControlId);
136:
137: // First, remove all children panels from pnlRight
138: $pnlRight->RemoveChildControls(true);
139:
140: // Now create a new PersonEditPanel, setting pnlRight as its parent
141: // and specifying parent form's "CloseRightPanel" as the method callback
142: // See the note in _constructor, above, for more information
143: new ProjectEditPanel($pnlRight, $this->objProject, 'CloseRightPanel');
144: }
145: }