CTabView.php
6.44 KB
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
<?php
/**
* CTabView class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CTabView displays contents in multiple tabs.
*
* At any time, only one tab is visible. Users can click on the tab header
* to switch to see another tab of content.
*
* JavaScript is used to control the tab switching. If JavaScript is disabled,
* CTabView still manages to display the content in a semantically appropriate way.
*
* To specify contents and their tab structure, configure the {@link tabs} property.
* The {@link tabs} property takes an array with tab ID being mapped tab definition.
* Each tab definition is an array of the following structure:
* <ul>
* <li>title: the tab title.</li>
* <li>content: the content to be displayed in the tab.</li>
* <li>view: the name of the view to be displayed in this tab.
* The view will be rendered using the current controller's
* {@link CController::renderPartial} method.
* When both 'content' and 'view' are specified, 'content' will take precedence.
* </li>
* <li>url: a URL that the user browser will be redirected to when clicking on this tab.</li>
* <li>data: array (name=>value), this will be passed to the view when 'view' is specified.</li>
* </ul>
*
* For example, the {@link tabs} property can be configured as follows,
* <pre>
* $this->widget('CTabView', array(
* 'tabs'=>array(
* 'tab1'=>array(
* 'title'=>'tab 1 title',
* 'view'=>'view1',
* 'data'=>array('model'=>$model),
* ),
* 'tab2'=>array(
* 'title'=>'tab 2 title',
* 'url'=>'http://www.yiiframework.com/',
* ),
* ),
* ))?>
* </pre>
*
* By default, the first tab will be activated. To activate a different tab
* when the page is initially loaded, set {@link activeTab} to be the ID of the desired tab.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.widgets
* @since 1.0
*/
class CTabView extends CWidget
{
/**
* Default CSS class for the tab container
*/
const CSS_CLASS='yiiTab';
/**
* @var mixed the CSS file used for the widget. Defaults to null, meaning
* using the default CSS file included together with the widget.
* If false, no CSS file will be used. Otherwise, the specified CSS file
* will be included when using this widget.
*/
public $cssFile;
/**
* @var string the ID of the tab that should be activated when the page is initially loaded.
* If not set, the first tab will be activated.
*/
public $activeTab;
/**
* @var array the data that will be passed to the partial view rendered by each tab.
*/
public $viewData;
/**
* @var array additional HTML options to be rendered in the container tag.
*/
public $htmlOptions;
/**
* @var array tab definitions. The array keys are the IDs,
* and the array values are the corresponding tab contents.
* Each array value must be an array with the following elements:
* <ul>
* <li>title: the tab title. You need to make sure this is HTML-encoded.</li>
* <li>content: the content to be displayed in the tab.</li>
* <li>view: the name of the view to be displayed in this tab.
* The view will be rendered using the current controller's
* {@link CController::renderPartial} method.
* When both 'content' and 'view' are specified, 'content' will take precedence.
* </li>
* <li>url: a URL that the user browser will be redirected to when clicking on this tab.</li>
* <li>data: array (name=>value), this will be passed to the view when 'view' is specified.
* This option is available since version 1.1.1.</li>
* <li>visible: whether this tab is visible. Defaults to true.
* this option is available since version 1.1.11.</li>
* </ul>
* <pre>
* array(
* 'tab1'=>array(
* 'title'=>'tab 1 title',
* 'view'=>'view1',
* ),
* 'tab2'=>array(
* 'title'=>'tab 2 title',
* 'url'=>'http://www.yiiframework.com/',
* ),
* )
* </pre>
*/
public $tabs=array();
/**
* Runs the widget.
*/
public function run()
{
foreach($this->tabs as $id=>$tab)
if(isset($tab['visible']) && $tab['visible']==false)
unset($this->tabs[$id]);
if(empty($this->tabs))
return;
if($this->activeTab===null || !isset($this->tabs[$this->activeTab]))
{
reset($this->tabs);
list($this->activeTab, )=each($this->tabs);
}
$htmlOptions=$this->htmlOptions;
$htmlOptions['id']=$this->getId();
if(!isset($htmlOptions['class']))
$htmlOptions['class']=self::CSS_CLASS;
$this->registerClientScript();
echo CHtml::openTag('div',$htmlOptions)."\n";
$this->renderHeader();
$this->renderBody();
echo CHtml::closeTag('div');
}
/**
* Registers the needed CSS and JavaScript.
*/
public function registerClientScript()
{
$cs=Yii::app()->getClientScript();
$cs->registerCoreScript('yiitab');
$id=$this->getId();
$cs->registerScript('Yii.CTabView#'.$id,"jQuery(\"#{$id}\").yiitab();");
if($this->cssFile!==false)
self::registerCssFile($this->cssFile);
}
/**
* Registers the needed CSS file.
* @param string $url the CSS URL. If null, a default CSS URL will be used.
*/
public static function registerCssFile($url=null)
{
$cs=Yii::app()->getClientScript();
if($url===null)
$url=$cs->getCoreScriptUrl().'/yiitab/jquery.yiitab.css';
$cs->registerCssFile($url,'screen');
}
/**
* Renders the header part.
*/
protected function renderHeader()
{
echo "<ul class=\"tabs\">\n";
foreach($this->tabs as $id=>$tab)
{
$title=isset($tab['title'])?$tab['title']:'undefined';
$active=$id===$this->activeTab?' class="active"' : '';
$url=isset($tab['url'])?$tab['url']:"#{$id}";
echo "<li><a href=\"{$url}\"{$active}>{$title}</a></li>\n";
}
echo "</ul>\n";
}
/**
* Renders the body part.
*/
protected function renderBody()
{
foreach($this->tabs as $id=>$tab)
{
$inactive=$id!==$this->activeTab?' style="display:none"' : '';
echo "<div class=\"view\" id=\"{$id}\"{$inactive}>\n";
if(isset($tab['content']))
echo $tab['content'];
else if(isset($tab['view']))
{
if(isset($tab['data']))
{
if(is_array($this->viewData))
$data=array_merge($this->viewData, $tab['data']);
else
$data=$tab['data'];
}
else
$data=$this->viewData;
$this->getController()->renderPartial($tab['view'], $data);
}
echo "</div><!-- {$id} -->\n";
}
}
}