223 lines
6.5 KiB
PHP
223 lines
6.5 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* CTabView class file.
|
||
|
*
|
||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||
|
* @link http://www.yiiframework.com/
|
||
|
* @copyright 2008-2013 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>
|
||
|
* @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;
|
||
|
if(isset($this->htmlOptions['id']))
|
||
|
$this->id=$this->htmlOptions['id'];
|
||
|
else
|
||
|
$htmlOptions['id']=$this->id;
|
||
|
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'];
|
||
|
elseif(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";
|
||
|
}
|
||
|
}
|
||
|
}
|