183 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\v\bs3\plugins;
 | |
| 
 | |
| use nur\A;
 | |
| use nur\func;
 | |
| use nur\v\BasePlugin;
 | |
| use nur\v\js;
 | |
| use nur\v\v;
 | |
| use nur\v\vo;
 | |
| 
 | |
| class navtabPlugin extends BasePlugin {
 | |
|   const COD_KEY = null;
 | |
|   const TITLE_KEY = null;
 | |
| 
 | |
|   const FRAGMENT_PREFIX = "#nt:";
 | |
| 
 | |
|   /** @var array liste de tableaux [cod, title] */
 | |
|   private $tabs;
 | |
| 
 | |
|   /** @var array liste des codes valides */
 | |
|   private $tabCods;
 | |
| 
 | |
|   function __construct(?array $tabs=null) {
 | |
|     $this->setTabs($tabs);
 | |
|   }
 | |
| 
 | |
|   protected function filterTab($tab, ?array $tabs=null): bool {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   protected function getCod($tab): string {
 | |
|     $codKey = static::COD_KEY;
 | |
|     $tab = A::with($tab);
 | |
|     if ($codKey !== null) return A::get($tab, $codKey, "");
 | |
|     return A::first($tab, "");
 | |
|   }
 | |
| 
 | |
|   protected function getTitle($tab): ?string {
 | |
|     $titleKey = static::TITLE_KEY;
 | |
|     $tab = A::with($tab);
 | |
|     if ($titleKey !== null) return A::get($tab, $titleKey);
 | |
|     else return A::second($tab);
 | |
|   }
 | |
| 
 | |
|   private function getCodTitle($tab): array {
 | |
|     $cod = $this->getCod($tab);
 | |
|     $title = $this->getTitle($tab);
 | |
|     if ($title == null) $title = $cod;
 | |
|     return [$cod, $title];
 | |
|   }
 | |
| 
 | |
|   function setTabs(?array $tabs=null): void {
 | |
|     $tabs = A::with($tabs);
 | |
|     $filteredTabs = [];
 | |
|     $tabCods = [];
 | |
|     foreach ($tabs as $tab) {
 | |
|       if ($this->filterTab($tab, $tabs)) continue;
 | |
|       $filteredTabs[] = $tab;
 | |
|       $tabCods[] = $this->getCod($tab);
 | |
|     }
 | |
|     $this->tabs = $filteredTabs;
 | |
|     $this->tabCods = $tabCods;
 | |
|   }
 | |
| 
 | |
|   const HAVE_JQUERY = true;
 | |
| 
 | |
|   protected function jqSetup(): void {}
 | |
|   protected function jqBeforeDeactivate(): void {}
 | |
|   protected function jqAfterActivate(): void {}
 | |
| 
 | |
|   function printJquery(): void {
 | |
|     $tabCods = $this->tabCods;
 | |
|     if (!$tabCods) return;
 | |
|     ?>
 | |
| <script type="text/javascript">
 | |
|   <?php $this->jqSetup(); ?>
 | |
|   var NAV_TABS = <?=js::qvs($tabCods)?>;
 | |
|   function activateTab(activeTab) {
 | |
|     <?php $this->jqBeforeDeactivate(); ?>
 | |
|     for (let i in NAV_TABS) {
 | |
|       let tab = NAV_TABS[i];
 | |
|       if (tab === activeTab) continue;
 | |
|       $("#" + tab + "_tab").removeClass("active");
 | |
|       $("#" + tab + "_panel").addClass("hide");
 | |
|     }
 | |
|     $("#" + activeTab + "_panel").removeClass("hide");
 | |
|     $("#" + activeTab + "_tab").addClass("active");
 | |
|     <?php $this->jqAfterActivate(); ?>
 | |
|   }
 | |
|   <?php foreach ($tabCods as $tabCod): ?>
 | |
|   $(<?=js::qv("#${tabCod}_tab")?>).click(function() {
 | |
|     activateTab(<?=js::qv($tabCod)?>);
 | |
|     return false;
 | |
|   });
 | |
|   <?php endforeach; ?>
 | |
|   function updateTab(initial=false) {
 | |
|     let prefix = <?=js::qv(static::FRAGMENT_PREFIX)?>;
 | |
|     let hash = window.location.hash;
 | |
|     let hashOk = false;
 | |
|     if (hash.startsWith(prefix)) {
 | |
|       let tab = hash.slice(prefix.length);
 | |
|       if ($("#" + tab + "_tab").length) {
 | |
|         activateTab(tab);
 | |
|         hashOk = true;
 | |
|       }
 | |
|     }
 | |
|     if (!hashOk && initial) {
 | |
|       for (let i in NAV_TABS) {
 | |
|         let tab = NAV_TABS[i];
 | |
|         if ($("#" + tab + "_tab").length) {
 | |
|           activateTab(tab);
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   $(window).on("hashchange", function() {
 | |
|     updateTab();
 | |
|   });
 | |
|   updateTab(true);
 | |
| </script>
 | |
| <?php
 | |
|   }
 | |
| 
 | |
|   const URL_KEY = null;
 | |
|   protected function getUrl($tab): ?string {
 | |
|     $urlKey = static::URL_KEY;
 | |
|     if ($urlKey !== null) return A::get($tab, $urlKey);
 | |
|     else return null;
 | |
|   }
 | |
| 
 | |
|   const BADGE_KEY = null;
 | |
|   protected function getBadge($tab): ?string {
 | |
|     $badgeKey = static::BADGE_KEY;
 | |
|     if ($badgeKey !== null) return A::get($tab, $badgeKey);
 | |
|     else return null;
 | |
|   }
 | |
| 
 | |
|   function paTabs(?string $curCod=null): void {
 | |
|     $tabs = $this->tabs;
 | |
|     if (!$tabs) return;
 | |
|     vo::sul(["class" => "nav nav-tabs"]);
 | |
|     foreach ($tabs as $tab) {
 | |
|       [$cod, $title] = $this->getCodTitle($tab);
 | |
|       vo::li([
 | |
|         "id" => "${cod}_tab",
 | |
|         "class" => $cod === $curCod? "active": null,
 | |
|         "role" => "presentation",
 | |
|         v::a([
 | |
|           "href" => $this->getUrl($tab),
 | |
|           q($title),
 | |
|           v::span(["class" => "badge", $this->getBadge($tab)])
 | |
|         ]),
 | |
|       ]);
 | |
|     }
 | |
|     vo::eul();
 | |
|   }
 | |
| 
 | |
|   function paStartPanel($cod): void {
 | |
|     if (!is_string($cod)) $cod = $this->getCod($cod);
 | |
|     vo::sdiv(["id" => "${cod}_panel"]);
 | |
|   }
 | |
| 
 | |
|   function paEndPanel(): void {
 | |
|     vo::ediv();
 | |
|   }
 | |
| 
 | |
|   function printActions(?string $curCod, callable $printPanel, ?callable $beforePanels=null, ?callable $afterPanels=null): bool {
 | |
|     $tabs = $this->tabs;
 | |
|     if (!$tabs) return false;
 | |
|     $func = func::_prepare($printPanel);
 | |
|     $this->paTabs($curCod);
 | |
|     if ($beforePanels !== null) $beforePanels();
 | |
|     foreach ($this->tabs as $tab) {
 | |
|       $this->paStartPanel($tab);
 | |
|       func::_call($func, [$tab, $this]);
 | |
|       $this->paEndPanel();
 | |
|     }
 | |
|     if ($afterPanels !== null) $afterPanels();
 | |
|     return true;
 | |
|   }
 | |
| }
 |