CTabView.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. /**
  3. * CTabView class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CTabView displays contents in multiple tabs.
  12. *
  13. * At any time, only one tab is visible. Users can click on the tab header
  14. * to switch to see another tab of content.
  15. *
  16. * JavaScript is used to control the tab switching. If JavaScript is disabled,
  17. * CTabView still manages to display the content in a semantically appropriate way.
  18. *
  19. * To specify contents and their tab structure, configure the {@link tabs} property.
  20. * The {@link tabs} property takes an array with tab ID being mapped tab definition.
  21. * Each tab definition is an array of the following structure:
  22. * <ul>
  23. * <li>title: the tab title.</li>
  24. * <li>content: the content to be displayed in the tab.</li>
  25. * <li>view: the name of the view to be displayed in this tab.
  26. * The view will be rendered using the current controller's
  27. * {@link CController::renderPartial} method.
  28. * When both 'content' and 'view' are specified, 'content' will take precedence.
  29. * </li>
  30. * <li>url: a URL that the user browser will be redirected to when clicking on this tab.</li>
  31. * <li>data: array (name=>value), this will be passed to the view when 'view' is specified.</li>
  32. * </ul>
  33. *
  34. * For example, the {@link tabs} property can be configured as follows,
  35. * <pre>
  36. * $this->widget('CTabView', array(
  37. * 'tabs'=>array(
  38. * 'tab1'=>array(
  39. * 'title'=>'tab 1 title',
  40. * 'view'=>'view1',
  41. * 'data'=>array('model'=>$model),
  42. * ),
  43. * 'tab2'=>array(
  44. * 'title'=>'tab 2 title',
  45. * 'url'=>'http://www.yiiframework.com/',
  46. * ),
  47. * ),
  48. * ));
  49. * </pre>
  50. *
  51. * By default, the first tab will be activated. To activate a different tab
  52. * when the page is initially loaded, set {@link activeTab} to be the ID of the desired tab.
  53. *
  54. * @author Qiang Xue <qiang.xue@gmail.com>
  55. * @package system.web.widgets
  56. * @since 1.0
  57. */
  58. class CTabView extends CWidget
  59. {
  60. /**
  61. * Default CSS class for the tab container
  62. */
  63. const CSS_CLASS='yiiTab';
  64. /**
  65. * @var mixed the CSS file used for the widget. Defaults to null, meaning
  66. * using the default CSS file included together with the widget.
  67. * If false, no CSS file will be used. Otherwise, the specified CSS file
  68. * will be included when using this widget.
  69. */
  70. public $cssFile;
  71. /**
  72. * @var string the ID of the tab that should be activated when the page is initially loaded.
  73. * If not set, the first tab will be activated.
  74. */
  75. public $activeTab;
  76. /**
  77. * @var array the data that will be passed to the partial view rendered by each tab.
  78. */
  79. public $viewData;
  80. /**
  81. * @var array additional HTML options to be rendered in the container tag.
  82. */
  83. public $htmlOptions;
  84. /**
  85. * @var array tab definitions. The array keys are the IDs,
  86. * and the array values are the corresponding tab contents.
  87. * Each array value must be an array with the following elements:
  88. * <ul>
  89. * <li>title: the tab title. You need to make sure this is HTML-encoded.</li>
  90. * <li>content: the content to be displayed in the tab.</li>
  91. * <li>view: the name of the view to be displayed in this tab.
  92. * The view will be rendered using the current controller's
  93. * {@link CController::renderPartial} method.
  94. * When both 'content' and 'view' are specified, 'content' will take precedence.
  95. * </li>
  96. * <li>url: a URL that the user browser will be redirected to when clicking on this tab.</li>
  97. * <li>data: array (name=>value), this will be passed to the view when 'view' is specified.
  98. * This option is available since version 1.1.1.</li>
  99. * <li>visible: whether this tab is visible. Defaults to true.
  100. * this option is available since version 1.1.11.</li>
  101. * </ul>
  102. * <pre>
  103. * array(
  104. * 'tab1'=>array(
  105. * 'title'=>'tab 1 title',
  106. * 'view'=>'view1',
  107. * ),
  108. * 'tab2'=>array(
  109. * 'title'=>'tab 2 title',
  110. * 'url'=>'http://www.yiiframework.com/',
  111. * ),
  112. * )
  113. * </pre>
  114. */
  115. public $tabs=array();
  116. /**
  117. * Runs the widget.
  118. */
  119. public function run()
  120. {
  121. foreach($this->tabs as $id=>$tab)
  122. if(isset($tab['visible']) && $tab['visible']==false)
  123. unset($this->tabs[$id]);
  124. if(empty($this->tabs))
  125. return;
  126. if($this->activeTab===null || !isset($this->tabs[$this->activeTab]))
  127. {
  128. reset($this->tabs);
  129. list($this->activeTab, )=each($this->tabs);
  130. }
  131. $htmlOptions=$this->htmlOptions;
  132. if(isset($this->htmlOptions['id']))
  133. $this->id=$this->htmlOptions['id'];
  134. else
  135. $htmlOptions['id']=$this->id;
  136. if(!isset($htmlOptions['class']))
  137. $htmlOptions['class']=self::CSS_CLASS;
  138. $this->registerClientScript();
  139. echo CHtml::openTag('div',$htmlOptions)."\n";
  140. $this->renderHeader();
  141. $this->renderBody();
  142. echo CHtml::closeTag('div');
  143. }
  144. /**
  145. * Registers the needed CSS and JavaScript.
  146. */
  147. public function registerClientScript()
  148. {
  149. $cs=Yii::app()->getClientScript();
  150. $cs->registerCoreScript('yiitab');
  151. $id=$this->getId();
  152. $cs->registerScript('Yii.CTabView#'.$id,"jQuery(\"#{$id}\").yiitab();");
  153. if($this->cssFile!==false)
  154. self::registerCssFile($this->cssFile);
  155. }
  156. /**
  157. * Registers the needed CSS file.
  158. * @param string $url the CSS URL. If null, a default CSS URL will be used.
  159. */
  160. public static function registerCssFile($url=null)
  161. {
  162. $cs=Yii::app()->getClientScript();
  163. if($url===null)
  164. $url=$cs->getCoreScriptUrl().'/yiitab/jquery.yiitab.css';
  165. $cs->registerCssFile($url,'screen');
  166. }
  167. /**
  168. * Renders the header part.
  169. */
  170. protected function renderHeader()
  171. {
  172. echo "<ul class=\"tabs\">\n";
  173. foreach($this->tabs as $id=>$tab)
  174. {
  175. $title=isset($tab['title'])?$tab['title']:'undefined';
  176. $active=$id===$this->activeTab?' class="active"' : '';
  177. $url=isset($tab['url'])?$tab['url']:"#{$id}";
  178. echo "<li><a href=\"{$url}\"{$active}>{$title}</a></li>\n";
  179. }
  180. echo "</ul>\n";
  181. }
  182. /**
  183. * Renders the body part.
  184. */
  185. protected function renderBody()
  186. {
  187. foreach($this->tabs as $id=>$tab)
  188. {
  189. $inactive=$id!==$this->activeTab?' style="display:none"' : '';
  190. echo "<div class=\"view\" id=\"{$id}\"{$inactive}>\n";
  191. if(isset($tab['content']))
  192. echo $tab['content'];
  193. elseif(isset($tab['view']))
  194. {
  195. if(isset($tab['data']))
  196. {
  197. if(is_array($this->viewData))
  198. $data=array_merge($this->viewData, $tab['data']);
  199. else
  200. $data=$tab['data'];
  201. }
  202. else
  203. $data=$this->viewData;
  204. $this->getController()->renderPartial($tab['view'], $data);
  205. }
  206. echo "</div><!-- {$id} -->\n";
  207. }
  208. }
  209. }