PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/widgets/TbTabs.php

https://github.com/jacmoe/yiistrap-1
PHP | 257 lines | 133 code | 43 blank | 81 comment | 17 complexity | 65e1976f35f4d0441e80910f17dac10b MD5 | raw file
  1. <?php
  2. /**
  3. * TbTabs class file.
  4. * @author Antonio Ramirez <ramirez.cobos@gmail.com>
  5. * @copyright Copyright &copy; Christoffer Niska 2013-
  6. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  7. * @package bootstrap.widgets
  8. */
  9. Yii::import('bootstrap.widgets.TbWidget');
  10. /**
  11. * Class TbTabs
  12. */
  13. class TbTabs extends TbWidget
  14. {
  15. /**
  16. * @var array Additional data submitted to the views
  17. */
  18. public $viewData;
  19. /**
  20. * @var string the type of tabs to display. Defaults to 'tabs'. Valid values are 'tabs' and 'pills'.
  21. * Please not that Javascript pills are not fully supported in Bootstrap yet!
  22. * @see TbHtml::$navStyles
  23. */
  24. public $type = TbHtml::NAV_TABS;
  25. /**
  26. * @var string the placement of the tabs.
  27. * Valid values are TbHtml::TABS_TOP, TbHtml::TABS_RIGHT, TbHtml::TABS_LEFT, TbHtml::TABS_BELOW.
  28. * @see TbHtml::tabPlacements
  29. */
  30. public $placement;
  31. /**
  32. * @var array the tab configuration.
  33. */
  34. public $tabs = array();
  35. /**
  36. * @var string a javascript function that This event fires on tab show, but before the new tab has been shown.
  37. * Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available)
  38. * respectively.
  39. */
  40. public $onShow;
  41. /**
  42. * @var string a javascript function that fires on tab show after a tab has been shown. Use `event.target` and
  43. * `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively.
  44. */
  45. public $onShown;
  46. /**
  47. * @var array the HTML attributes for the widget container.
  48. */
  49. public $htmlOptions = array();
  50. /**
  51. * @var string[] the Javascript event handlers.
  52. */
  53. protected $events = array();
  54. /**
  55. * @var array the tab menu items.
  56. */
  57. protected $menuItems = array();
  58. /**
  59. * @var array the contents of the tabs.
  60. */
  61. protected $tabsContent = array();
  62. /**
  63. * Widget's initialization method
  64. */
  65. public function init()
  66. {
  67. if (!isset($this->htmlOptions['id']))
  68. $this->htmlOptions['id'] = $this->id;
  69. else
  70. $this->id = $this->htmlOptions['id'];
  71. if(isset($this->placement))
  72. $this->htmlOptions = TbHtml::addClassName('tabs-'.$this->placement, $this->htmlOptions);
  73. $this->menuItems = $this->normalizeTabs($this->tabs, $this->tabsContent);
  74. $this->initEvents();
  75. }
  76. /**
  77. * Initialize events if any
  78. */
  79. public function initEvents()
  80. {
  81. foreach(array('onShow', 'onShown') as $event)
  82. {
  83. if($this->$event!==null)
  84. {
  85. $modalEvent = strtolower(substr($event, 2));
  86. if($this->$event instanceof CJavaScriptExpression)
  87. $this->events[$modalEvent]=$this->$event;
  88. else
  89. $this->events[$modalEvent]=new CJavaScriptExpression($this->$event);
  90. }
  91. }
  92. }
  93. /**
  94. * Widget's run method
  95. */
  96. public function run()
  97. {
  98. ob_start();
  99. $this->renderTabsNavigation();
  100. $navigation = ob_get_clean();
  101. ob_start();
  102. $this->renderTabsContent();
  103. $content = ob_get_clean();
  104. $this->renderTabs($navigation, $content);
  105. $this->registerClientScript();
  106. }
  107. /**
  108. * Renders the
  109. * @param string $navigation the menu tabs
  110. * @param string $content the tabs contents
  111. */
  112. public function renderTabs($navigation, $content)
  113. {
  114. echo CHtml::openTag('div', $this->htmlOptions);
  115. echo $this->placement === TbHtml::TABS_BELOW
  116. ? $content.$navigation
  117. : $navigation.$content;
  118. echo '</div>';
  119. }
  120. /**
  121. * Renders tab navigation
  122. */
  123. public function renderTabsNavigation()
  124. {
  125. $navOptions = TbHtml::popOption('menuOptions', $this->htmlOptions, array());
  126. echo TbHtml::nav($this->type, $this->menuItems, $navOptions );
  127. }
  128. /**
  129. * Renders tabs contents
  130. */
  131. public function renderTabsContent()
  132. {
  133. $contentOptions = TbHtml::popOption('contentOptions', $this->htmlOptions, array());
  134. $contentOptions = TbHtml::addClassName('tab-content', $contentOptions);
  135. echo CHtml::openTag('div', $contentOptions );
  136. echo implode(' ', $this->tabsContent);
  137. echo '</div>';
  138. }
  139. /**
  140. * Normalizes the tab configuration.
  141. * @param array $tabs the tab configuration
  142. * @param array $panes a reference to the panes array
  143. * @param integer $i the current index
  144. * @return array the items
  145. */
  146. protected function normalizeTabs($tabs, &$panes, &$i = 0)
  147. {
  148. $id = TbHtml::getOption('id', $this->htmlOptions, $this->getId());
  149. $items = array();
  150. //Check if has an active item
  151. $hasActiveItem = false;
  152. foreach ($tabs as $tab)
  153. {
  154. if ($hasActiveItem = TbHtml::getOption('active', $tab, false) === true)
  155. break;
  156. }
  157. foreach ($tabs as $tab)
  158. {
  159. $item = $tab;
  160. if (isset($item['visible']) && $item['visible'] === false)
  161. continue;
  162. // if no tab should be active, activate first
  163. if (!$hasActiveItem && $i == 0)
  164. $item['active'] = true;
  165. // set the label to the title if any
  166. if (isset($item['title']))
  167. $item['label'] = TbHtml::defaultOption('label', TbHtml::popOption('title', $item), $item);
  168. $item = TbHtml::defaultOption('itemOptions', array(), $item);
  169. if (isset($tab['items']))
  170. {
  171. $item['linkOptions']['data-toggle'] = 'dropdown';
  172. $item['items'] = $this->normalizeTabs($item['items'], $panes, $i);
  173. }
  174. else
  175. {
  176. $item['linkOptions']['data-toggle'] = 'tab';
  177. $item = TbHtml::defaultOption('id', $id . '_tab_' . ($i + 1), $item);
  178. $item['url'] = '#' . $item['id'];
  179. // no content and we have a view?
  180. if (!isset($item['content']) && isset($item['view']))
  181. {
  182. $view = TbHtml::popOption('view', $item, '');
  183. $data = TbHtml::popOption('data', $item, array());
  184. if (is_array($this->viewData))
  185. $data = TbHtml::mergeOptions($this->viewData, $data);
  186. $process = TbHtml::popOption('processOutput', $item, false);
  187. $item['content'] = !empty($view)
  188. ? $this->getController()->renderPartial($view, $data, true, $process)
  189. : '';
  190. }
  191. $content = TbHtml::popOption('content', $item, '');
  192. $paneOptions = TbHtml::popOption('paneOptions', $item, array());
  193. $paneOptions['id'] = TbHtml::popOption('id', $item);
  194. $classes = array('tab-pane fade');
  195. if (isset($item['active']) && $item['active'])
  196. $classes[] = 'active in';
  197. $paneOptions = TbHtml::addClassName(implode(' ', $classes), $paneOptions);
  198. $panes[] = CHtml::tag('div', $paneOptions, $content);
  199. $i++; // increment the tab-index
  200. }
  201. $items[] = $item;
  202. }
  203. return $items;
  204. }
  205. /**
  206. * Registers necessary client scripts.
  207. */
  208. public function registerClientScript()
  209. {
  210. $selector = '#' . $this->htmlOptions['id'];
  211. Yii::app()->clientScript->registerScript(__CLASS__.$selector, "jQuery('{$selector}').tab('show');");
  212. $this->registerEvents($selector, $this->events);
  213. }
  214. }