<?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; } }