summaryrefslogtreecommitdiff
path: root/framework/Web/UI/ActiveControls/TActiveDataGrid.php
blob: 04b23843972942c79438c27c77022d82bc696846 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<?php
/**
 * TActiveDataGrid class file
 *
 * @author LANDWEHR Computer und Software GmbH <programmierung@landwehr-software.de>
 * @link http://www.landwehr-software.de/
 * @copyright Copyright &copy; 2009 LANDWEHR Computer und Software GmbH
 * @license http://www.pradosoft.com/license/
 * @package System.Web.UI.ActiveControls
 */

/**
 * Includes the following used classes
 */
Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter');
Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton');
Prado::using('System.Web.UI.ActiveControls.TActiveImageButton');
Prado::using('System.Web.UI.ActiveControls.TActiveButton');
Prado::using('System.Web.UI.ActiveControls.TActiveImage');
Prado::using('System.Web.UI.ActiveControls.TActiveCheckBox');
Prado::using('System.Web.UI.ActiveControls.TCallbackOptions');
Prado::using('System.Web.UI.WebControls.TDataGrid');
Prado::using('System.Web.UI.WebControls.TBoundColumn');
Prado::using('System.Web.UI.WebControls.TEditCommandColumn');
Prado::using('System.Web.UI.WebControls.TButtonColumn');
Prado::using('System.Web.UI.WebControls.THyperLinkColumn');
Prado::using('System.Web.UI.WebControls.TCheckBoxColumn');

/**
 * TActiveDataGrid class
 *
 * TActiveDataGrid represents a data bound and updatable grid control which is the
 * active counterpart to the original {@link TDataGrid} control.
 *
 * This component can be used in the same way as the regular datagrid, the only
 * difference is that the active datagrid uses callbacks instead of postbacks
 * for interaction.
 *
 * There are also active datagrid columns to work with the TActiveDataGrid, which are
 * - {@link TActiveBoundColumn}, the active counterpart to {@link TBoundColumn}.
 * - {@link TActiveLiteralColumn}, the active counterpart to {@link TLiteralColumn}.
 * - {@link TActiveCheckBoxColumn}, the active counterpart to {@link TCheckBoxColumn}.
 * - {@link TActiveDropDownListColumn}, the active counterpart to {@link TDropDownListColumn}.
 * - {@link TActiveHyperLinkColumn}, the active counterpart to {@link THyperLinkColumn}.
 * - {@link TActiveEditCommandColumn}, the active counterpart to {@link TEditCommandColumn}.
 * - {@link TActiveButtonColumn}, the active counterpart to {@link TButtonColumn}.
 * - {@link TActiveTemplateColumn}, the active counterpart to {@link TTemplateColumn}.
 *
 * Please refer to the original documentation of the regular counterparts for usage.
 *
 * @author LANDWEHR Computer und Software GmbH <programmierung@landwehr-software.de>
 * @package System.Web.UI.ActiveControls
 * @since 3.1.9
 */
class TActiveDataGrid extends TDataGrid implements IActiveControl, ISurroundable {

	/**
	 * @return string Name of the class used in AutoGenerateColumns mode
	 */
	protected function getAutoGenerateColumnName()
	{
		return 'TActiveBoundColumn';
	}

	/**
	* Creates a new callback control, sets the adapter to
	* TActiveControlAdapter.
	*/
	public function __construct() {
		parent::__construct();
		$this->setAdapter(new TActiveControlAdapter($this));
	}

	/**
	 * @return TBaseActiveControl standard active control options.
	 */
	public function getActiveControl() {
		return $this->getAdapter()->getBaseActiveControl();
	}

	/**
	 * Sets the data source object associated with the datagrid control.
	 * In addition, the render method of all connected pagers is called so they
	 * get updated when the data source is changed. Also the datagrid registers
	 * itself for rendering in order to get it's content replaced on client side.
	 * @param Traversable|array|string data source object
	 */
	public function setDataSource($value) {
		parent::setDataSource($value);
		if($this->getActiveControl()->canUpdateClientSide()) {
			$this->renderPager();
			$this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter());
		}
	}

	/**
	 * Returns the id of the surrounding container (div).
	 * @return string container id
	 */
	public function getSurroundingTagId() {
		return $this->ClientID.'_Container';
	}

	/**
	 * Creates a pager button.
	 * Depending on the button type, a TActiveLinkButton or a TActiveButton may be created.
	 * If it is enabled (clickable), its command name and parameter will also be set.
	 * It overrides the datagrid's original method to create active controls instead, thus
	 * the pager will do callbacks instead of the regular postbacks.
	 * @param mixed the container pager instance of TActiveDatagridPager
	 * @param string button type, either LinkButton or PushButton
	 * @param boolean whether the button should be enabled
	 * @param string caption of the button
	 * @param string CommandName corresponding to the OnCommand event of the button
	 * @param string CommandParameter corresponding to the OnCommand event of the button
	 * @return mixed the button instance
	 */
	protected function createPagerButton($pager,$buttonType,$enabled,$text,$commandName,$commandParameter) {
		if($buttonType===TDataGridPagerButtonType::LinkButton) {
			if($enabled)
				$button=new TActiveLinkButton;
			else {
				$button=new TLabel;
				$button->setText($text);
				return $button;
			}
		}
		else {
			$button=new TActiveButton;
			if(!$enabled)
				$button->setEnabled(false);
		}
		$button->setText($text);
		$button->setCommandName($commandName);
		$button->setCommandParameter($commandParameter);
		$button->setCausesValidation(false);
		$button->getAdapter()->getBaseActiveControl()->setClientSide(
			$pager->getClientSide()
		);
		return $button;
	}

	protected function createPager()
	{
		$pager=new TActiveDataGridPager($this);
		$this->buildPager($pager);
		$this->onPagerCreated(new TActiveDataGridPagerEventParameter($pager));
		$this->getControls()->add($pager);
		return $pager;
	}

	/**
	 * Renders the datagrid.
	 * If the datagrid did not pass the prerender phase yet, it will register itself for rendering later.
	 * Else it will call the {@link renderDataGrid()} method which will do the rendering of the datagrid.
	 * @param THtmlWriter writer for the rendering purpose
	 */
	public function render($writer) {
		if($this->getHasPreRendered()) {
			$this->renderDataGrid($writer);
			if($this->getActiveControl()->canUpdateClientSide()) $this->getPage()->getCallbackClient()->replaceContent($this->getSurroundingTagId(),$writer);
		}
		else {
			$this->getPage()->getAdapter()->registerControlToRender($this,$writer);
		}
	}

	/**
	 * Loops through all {@link TActivePager} on the page and registers the ones which are set to paginate
	 * the datagrid for rendering. This is to ensure that the connected pagers are also rendered if the
	 * data source changed.
	 */
	private function renderPager() {
		$pager=$this->getPage()->findControlsByType('TActivePager', false);
		foreach($pager as $item) {
			if($item->ControlToPaginate==$this->ID) {
				$writer=$this->getResponse()->createHtmlWriter();
				$this->getPage()->getAdapter()->registerControlToRender($item,$writer);
			}
		}
	}

	/**
	 * Renders the datagrid by writing a div tag with the container id obtained from {@link getSurroundingTagId()}
	 * which will be called by the replacement method of the client script to update it's content.
	 * @param THtmlWriter writer for the rendering purpose
	 */
	private function renderDataGrid($writer) {
		$writer->write('<div id="'.$this->getSurroundingTagId().'">');
		parent::render($writer);
		$writer->write('</div>');
	}
}