Allow to set a customized placeholder for ajax tabs in scrollable mode

This commit is contained in:
Stephen Abello
2021-02-19 17:38:27 +01:00
parent e5d8c885bc
commit ea502e9c81
13 changed files with 355 additions and 46 deletions

View File

@@ -35,6 +35,7 @@ use Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityPanel;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\Column;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumn;
use Combodo\iTop\Application\UI\Base\Layout\Object\ObjectFactory;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
@@ -543,7 +544,11 @@ EOF
{
continue;
}
$oPage->AddAjaxTab($oAttDef->GetLabel(), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='.get_class($this).'&id='.$this->GetKey().'&attcode='.$oAttDef->GetCode(), true, 'Class:'.$sClass.'/Attribute:'.$sAttCode);
$oPage->AddAjaxTab($oAttDef->GetLabel(),
utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='.get_class($this).'&id='.$this->GetKey().'&attcode='.$oAttDef->GetCode(),
true,
'Class:'.$sClass.'/Attribute:'.$sAttCode,
AjaxTab::ENUM_TAB_PLACEHOLDER_REL_PATH_DASHBOARD);
continue;
}

View File

@@ -15,6 +15,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
/**
@@ -284,7 +285,7 @@ class _Ticket extends cmdbAbstractObject
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery.contextMenu.css');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.contextMenu.js');
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/simple_graph.js');
$oPage->AddAjaxTab('Ticket:ImpactAnalysis', utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=ticket_impact&class='.get_class($this).'&id='.$this->GetKey(), true);
$oPage->AddAjaxTab('Ticket:ImpactAnalysis', utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=ticket_impact&class='.get_class($this).'&id='.$this->GetKey(), true, null, AjaxTab::ENUM_TAB_PLACEHOLDER_REL_PATH_MISC);
}
}
}

View File

@@ -0,0 +1,79 @@
<svg
role="img"
aria-labelledby="loading-aria"
viewBox="0 0 540 100"
preserveAspectRatio="none"
>
<rect
x="0"
y="0"
width="100%"
height="100%"
clip-path="url(#dashboard-clip-path)"
style='fill: url("#dashboard-fill");'
></rect>
<defs>
<clipPath id="dashboard-clip-path">
<circle cx="231" cy="30" r="30" />
<rect x="8" y="6" rx="2" ry="2" width="140" height="10" />
<rect x="8" y="28" rx="2" ry="2" width="20" height="10" />
<rect x="397" y="4" rx="2" ry="2" width="20" height="20" />
<rect x="38" y="28" rx="2" ry="2" width="20" height="10" />
<rect x="68" y="28" rx="2" ry="2" width="20" height="10" />
<rect x="98" y="28" rx="2" ry="2" width="20" height="10" />
<rect x="8" y="60" rx="2" ry="2" width="130" height="10" />
<rect x="8" y="80" rx="2" ry="2" width="40" height="10" />
<rect x="274" y="14" rx="3" ry="3" width="61" height="6" />
<rect x="274" y="24" rx="3" ry="3" width="61" height="6" />
<rect x="274" y="34" rx="3" ry="3" width="61" height="6" />
<rect x="204" y="70" rx="0" ry="0" width="30" height="10" />
<rect x="204" y="90" rx="0" ry="0" width="150" height="10" />
<rect x="425" y="9" rx="0" ry="0" width="120" height="10" />
<rect x="402" y="90" rx="2" ry="2" width="20" height="11" />
<rect x="432" y="40" rx="2" ry="2" width="20" height="60" />
<rect x="462" y="70" rx="2" ry="2" width="20" height="30" />
<rect x="492" y="60" rx="2" ry="2" width="20" height="40" />
</clipPath>
<linearGradient id="dashboard-fill">
<stop
offset="0.599964"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-2; -2; 1"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="1.59996"
stop-color="#ecebeb"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-1; -1; 2"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="2.59996"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="0; 0; 3"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,81 @@
<svg
role="img"
aria-labelledby="loading-aria"
viewBox="0 0 540 100"
preserveAspectRatio="none"
>
<title id="loading-aria">Loading...</title>
<rect
x="0"
y="0"
width="100%"
height="100%"
clip-path="url(#list-clip-path)"
style='fill: url("#list-fill");'
></rect>
<defs>
<clipPath id="list-clip-path">
<rect x="0" y="0" rx="3" ry="3" width="67" height="11" />
<rect x="76" y="0" rx="3" ry="3" width="140" height="11" />
<rect x="377" y="0" rx="3" ry="3" width="53" height="11" />
<rect x="438" y="0" rx="3" ry="3" width="100" height="11" />
<rect x="226" y="0" rx="3" ry="3" width="140" height="11" />
<rect x="0" y="30" rx="3" ry="3" width="67" height="11" />
<rect x="76" y="30" rx="3" ry="3" width="140" height="11" />
<rect x="377" y="30" rx="3" ry="3" width="53" height="11" />
<rect x="438" y="30" rx="3" ry="3" width="100" height="11" />
<rect x="226" y="30" rx="3" ry="3" width="140" height="11" />
<rect x="0" y="60" rx="3" ry="3" width="67" height="11" />
<rect x="76" y="60" rx="3" ry="3" width="140" height="11" />
<rect x="377" y="60" rx="3" ry="3" width="53" height="11" />
<rect x="438" y="60" rx="3" ry="3" width="100" height="11" />
<rect x="226" y="60" rx="3" ry="3" width="140" height="11" />
<rect x="0" y="90" rx="3" ry="3" width="67" height="11" />
<rect x="76" y="90" rx="3" ry="3" width="140" height="11" />
<rect x="377" y="90" rx="3" ry="3" width="53" height="11" />
<rect x="438" y="90" rx="3" ry="3" width="100" height="11" />
<rect x="226" y="90" rx="3" ry="3" width="140" height="11" />
</clipPath>
<linearGradient id="list-fill">
<stop
offset="0.599964"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-2; -2; 1"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="1.59996"
stop-color="#ecebeb"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-1; -1; 2"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="2.59996"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="0; 0; 3"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,87 @@
<svg
role="img"
aria-labelledby="loading-aria"
viewBox="0 0 540 100"
preserveAspectRatio="none"
>
<title id="loading-aria">Loading...</title>
<rect
x="0"
y="0"
width="100%"
height="100%"
clip-path="url(#object-clip-path)"
style='fill: url("#object-fill");'
></rect>
<defs>
<clipPath id="object-clip-path">
<rect x="0" y="0" rx="0" ry="0" width="NaN" height="NaN" />
<rect x="343" y="14" rx="0" ry="0" width="30" height="10" />
<circle cx="36" cy="20" r="20" />
<rect x="64" y="4" rx="5" ry="5" width="150" height="10" />
<rect x="84" y="23" rx="5" ry="5" width="55" height="10" />
<circle cx="-28" cy="121" r="18" />
<rect x="-49" y="98" rx="5" ry="5" width="30" height="10" />
<rect x="-20" y="114" rx="5" ry="5" width="60" height="10" />
<rect x="49" y="49" rx="5" ry="5" width="50" height="10" />
<rect x="49" y="89" rx="5" ry="5" width="80" height="10" />
<rect x="49" y="69" rx="5" ry="5" width="30" height="10" />
<rect x="278" y="130" rx="5" ry="5" width="163" height="10" />
<rect x="278" y="110" rx="5" ry="5" width="163" height="10" />
<rect x="64" y="23" rx="5" ry="5" width="10" height="10" />
<rect x="86" y="111" rx="5" ry="5" width="60" height="10" />
<rect x="155" y="46" rx="5" ry="5" width="40" height="10" />
<rect x="155" y="86" rx="5" ry="5" width="10" height="10" />
<rect x="155" y="66" rx="5" ry="5" width="45" height="10" />
<rect x="383" y="14" rx="0" ry="0" width="30" height="10" />
<rect x="423" y="14" rx="0" ry="0" width="30" height="10" />
<rect x="261" y="49" rx="5" ry="5" width="33" height="10" />
<rect x="261" y="89" rx="5" ry="5" width="70" height="10" />
<rect x="261" y="69" rx="5" ry="5" width="60" height="10" />
<rect x="367" y="46" rx="5" ry="5" width="40" height="10" />
<rect x="367" y="86" rx="5" ry="5" width="44" height="10" />
<rect x="367" y="66" rx="5" ry="5" width="38" height="10" />
</clipPath>
<linearGradient id="object-fill">
<stop
offset="0.599964"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-2; -2; 1"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="1.59996"
stop-color="#ecebeb"
stop-opacity="1"
>
<animate
attributeName="offset"
values="-1; -1; 2"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
<stop
offset="2.59996"
stop-color="#f3f3f3"
stop-opacity="1"
>
<animate
attributeName="offset"
values="0; 0; 3"
keyTimes="0; 0.25; 1"
dur="2s"
repeatCount="indefinite"
></animate>
</stop>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,48 +1,42 @@
<svg
role="img"
aria-labelledby="loading-aria"
viewBox="0 0 1000 300"
viewBox="0 0 540 100"
preserveAspectRatio="none"
>
<title id="loading-aria">Loading...</title>
<rect
x="0"
y="0"
width="100%"
height="100%"
clip-path="url(#clip-path)"
style='fill: url("#fill");'
clip-path="url(#misc-clip-path)"
style='fill: url("#misc-fill");'
></rect>
<defs>
<clipPath id="clip-path">
<clipPath id="misc-clip-path">
<rect x="0" y="0" rx="0" ry="0" width="NaN" height="NaN" />
<rect x="36" y="16" rx="5" ry="5" width="326" height="15" />
<circle cx="14" cy="68" r="12" />
<rect x="36" y="61" rx="5" ry="5" width="326" height="15" />
<circle cx="13" cy="26" r="12" />
<rect x="405" y="16" rx="0" ry="0" width="163" height="146" />
<circle cx="45" cy="135" r="42" />
<rect x="103" y="104" rx="5" ry="5" width="156" height="15" />
<rect x="104" y="146" rx="5" ry="5" width="257" height="15" />
<rect x="584" y="14" rx="5" ry="5" width="326" height="15" />
<rect x="922" y="14" rx="5" ry="5" width="69" height="15" />
<rect x="584" y="46" rx="5" ry="5" width="326" height="15" />
<rect x="922" y="46" rx="5" ry="5" width="69" height="15" />
<rect x="584" y="78" rx="5" ry="5" width="326" height="15" />
<rect x="922" y="78" rx="5" ry="5" width="69" height="15" />
<rect x="584" y="110" rx="5" ry="5" width="326" height="15" />
<rect x="922" y="110" rx="5" ry="5" width="69" height="15" />
<rect x="440" y="186" rx="5" ry="5" width="326" height="15" />
<circle cx="418" cy="238" r="12" />
<rect x="440" y="231" rx="5" ry="5" width="326" height="15" />
<circle cx="417" cy="196" r="12" />
<rect x="410" y="269" rx="5" ry="5" width="352" height="27" />
<rect x="805" y="176" rx="0" ry="0" width="163" height="146" />
<circle cx="44" cy="250" r="42" />
<rect x="102" y="219" rx="5" ry="5" width="156" height="15" />
<rect x="103" y="261" rx="5" ry="5" width="257" height="15" />
<rect x="20" y="1" rx="5" ry="5" width="103" height="10" />
<circle cx="6" cy="6" r="6" />
<rect x="247" y="2" rx="0" ry="0" width="72" height="64" />
<circle cx="18" cy="80" r="18" />
<rect x="41" y="66" rx="5" ry="5" width="70" height="10" />
<rect x="428" y="78" rx="0" ry="0" width="75" height="67" />
<circle cx="6" cy="26" r="6" />
<rect x="20" y="41" rx="5" ry="5" width="183" height="10" />
<circle cx="6" cy="46" r="6" />
<rect x="41" y="81" rx="5" ry="5" width="55" height="10" />
<circle cx="19" cy="121" r="18" />
<rect x="42" y="107" rx="5" ry="5" width="30" height="10" />
<rect x="42" y="122" rx="5" ry="5" width="60" height="10" />
<rect x="20" y="21" rx="5" ry="5" width="143" height="10" />
<rect x="334" y="8" rx="5" ry="5" width="163" height="10" />
<rect x="334" y="48" rx="5" ry="5" width="163" height="10" />
<rect x="334" y="28" rx="5" ry="5" width="163" height="10" />
<rect x="252" y="89" rx="5" ry="5" width="163" height="10" />
<rect x="252" y="129" rx="5" ry="5" width="163" height="10" />
<rect x="252" y="109" rx="5" ry="5" width="163" height="10" />
</clipPath>
<linearGradient id="fill">
<linearGradient id="misc-fill">
<stop
offset="0.599964"
stop-color="#f3f3f3"

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -11,9 +11,9 @@ $.widget( "itop.scrollabletabs", $.ui.tabs, {
if(tab.attr('data-role') === 'ibo-tab-container--tab-header')
{
panel.prepend('<div class="ibo-tab-container--tab-container--label"><span>' + tab.text() + '</span></div>');
var oTempDiv = $('<div>').addClass('ibo-tab--temporary-remote-content')
var oPlaceholder = $('<div>').addClass('ibo-tab--temporary-remote-content--placeholder').load(GetAbsoluteUrlAppRoot()+'images/placeholders/skeleton.svg');
var oLoadButton = $('<div>').addClass('ibo-tab--temporary-remote-content--button').text(placeholder).on('click', function(){tab.find('a').click()})
let oTempDiv = $('<div>').addClass('ibo-tab--temporary-remote-content')
let oPlaceholder = $('<div>').addClass('ibo-tab--temporary-remote-content--placeholder').load(tab.attr('data-placeholder'));
let oLoadButton = $('<div>').addClass('ibo-tab--temporary-remote-content--button').text(placeholder).on('click', function(){tab.find('a').click()})
oTempDiv.append(oPlaceholder)
oTempDiv.append(oLoadButton)
panel.append(oTempDiv);

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
try
{
ini_set('memory_limit', '256M');
@@ -1438,7 +1440,7 @@ EOF
if (Utils::GetConfig()->Get('csv_import_history_display'))
{
$oPage->SetCurrentTabContainer('tabs1');
$oPage->AddAjaxTab('UI:History:BulkImports', utils::GetAbsoluteUrlAppRoot().'pages/csvimport.php?step=11', true /* bCache */);
$oPage->AddAjaxTab('UI:History:BulkImports', utils::GetAbsoluteUrlAppRoot().'pages/csvimport.php?step=11', true /* bCache */, null, AjaxTab::ENUM_TAB_PLACEHOLDER_REL_PATH_MISC);
}
}

View File

@@ -24,6 +24,7 @@ use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\UIException;
use Dict;
use TabManager;
use utils;
/**
* Class AjaxTab
@@ -33,15 +34,37 @@ use TabManager;
* @since 3.0.0
*/
class AjaxTab extends Tab {
const ENUM_TAB_PLACEHOLDER_REL_PATH_LIST = 'images/placeholders/skeleton-list.svg';
const ENUM_TAB_PLACEHOLDER_REL_PATH_DASHBOARD = 'images/placeholders/skeleton-dashboard.svg';
const ENUM_TAB_PLACEHOLDER_REL_PATH_OBJECT = 'images/placeholders/skeleton-object.svg';
const ENUM_TAB_PLACEHOLDER_REL_PATH_MISC = 'images/placeholders/skeleton.svg';
const DEFAULT_TAB_PLACEHOLDER_REL_PATH = self::ENUM_TAB_PLACEHOLDER_REL_PATH_MISC;
// Overloaded constants
public const BLOCK_CODE = 'ibo-ajax-tab';
public const TAB_TYPE = TabManager::ENUM_TAB_TYPE_AJAX;
/** @var string Placeholder displayed before tab is loaded */
private $sPlaceholderRelPath;
/** @var string The target URL to be loaded asynchronously */
private $sUrl;
/** @var bool Whether the tab should should be cached by the browser or always refreshed */
private $bCache;
/**
* Tab constructor.
*
* @param string $sTabCode
* @param string $sTitle
* @param string $sPlaceholderRelPath
*/
public function __construct(string $sTabCode, string $sTitle, string $sPlaceholderRelPath = AjaxTab::DEFAULT_TAB_PLACEHOLDER_REL_PATH)
{
parent::__construct($sTabCode, $sTitle);
$this->sPlaceholderRelPath = $sPlaceholderRelPath;
}
/**
* @param string $sUrl
*
@@ -82,6 +105,35 @@ class AjaxTab extends Tab {
return $this->bCache ? 'true' : 'false';
}
/**
*
* @param string $sPlaceholderRelPath
*
* @return $this
*/
public function SetPlaceholderRelPath(string $sPlaceholderRelPath) {
$this->sPlaceholderRelPath = $sPlaceholderRelPath;
return $this;
}
/**
*
* @return string
*/
public function GetPlaceholderRelPath(): string {
return $this->sPlaceholderRelPath;
}
/**
*
* @return string
* @throws \Exception
*/
public function GetPlaceholderAbsPath(): string {
return utils::GetAbsoluteUrlAppRoot().$this->sPlaceholderRelPath;
}
//-------------------------------
// iUIBlock implementation
//-------------------------------

View File

@@ -113,13 +113,17 @@ class TabContainer extends UIContentBlock
/**
* @param string $sTabCode
* @param string $sTitle
* @param string|null $sPlaceholder
*
* @return \Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\Tab
* @throws \Combodo\iTop\Application\UI\Base\UIException
*/
public function AddAjaxTab(string $sTabCode, string $sTitle): Tab
public function AddAjaxTab(string $sTabCode, string $sTitle, ?string $sPlaceholder = null): Tab
{
$oTab = new AjaxTab($sTabCode, $sTitle);
if($sPlaceholder === null){
$sPlaceholder = AjaxTab::DEFAULT_TAB_PLACEHOLDER_REL_PATH;
}
$oTab = new AjaxTab($sTabCode, $sTitle, $sPlaceholder);
$this->AddSubBlock($oTab);
return $oTab;
}

View File

@@ -5,6 +5,7 @@
*/
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\Tab;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\TabContainer;
@@ -198,17 +199,18 @@ class TabManager
* the tab to be reloaded upon each activation.
*
* @param string|null $sTabTitle
* @param string $sPlaceholder
*
* @return string
*
* @throws \Combodo\iTop\Application\UI\Base\UIException
* @since 2.0.3
*/
public function AddAjaxTab(string $sTabCode, string $sUrl, bool $bCache = true, string $sTabTitle = null): string
public function AddAjaxTab(string $sTabCode, string $sUrl, bool $bCache = true, string $sTabTitle = null, string $sPlaceholder = null): string
{
// Set the content of the tab
/** @var \Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab $oTab */
$oTab = $this->InitTab($this->m_sCurrentTabContainer, $sTabCode, static::ENUM_TAB_TYPE_AJAX, $sTabTitle);
$oTab = $this->InitTab($this->m_sCurrentTabContainer, $sTabCode, static::ENUM_TAB_TYPE_AJAX, $sTabTitle, $sPlaceholder);
$oTab->SetUrl($sUrl)
->SetCache($bCache);
@@ -311,12 +313,13 @@ class TabManager
* @param string $sTabCode
* @param string $sTabType
* @param string|null $sTabTitle
* @param string|null $sPlaceholder
*
* @return \Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\Tab
* @throws \Combodo\iTop\Application\UI\Base\UIException
* @since 2.7.0
*/
protected function InitTab(string $sTabContainer, string $sTabCode, string $sTabType = self::DEFAULT_TAB_TYPE, string $sTabTitle = null): Tab
protected function InitTab(string $sTabContainer, string $sTabCode, string $sTabType = self::DEFAULT_TAB_TYPE, string $sTabTitle = null, string $sPlaceholder = null): Tab
{
$oTab = null;
if (!$this->TabExists($sTabContainer, $sTabCode)) {
@@ -330,7 +333,7 @@ class TabManager
switch ($sTabType) {
case static::ENUM_TAB_TYPE_AJAX:
$oTab = $oTabContainer->AddAjaxTab($sTabCode, $sTitle);
$oTab = $oTabContainer->AddAjaxTab($sTabCode, $sTitle, $sPlaceholder);
break;
case static::ENUM_TAB_TYPE_HTML:

View File

@@ -1045,9 +1045,9 @@ EOF
* @throws \Exception
* @since 2.0.3
*/
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null)
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null, $sPlaceholder = null)
{
$this->add($this->m_oTabs->AddAjaxTab($sTabCode, $sUrl, $bCache, $sTabTitle));
$this->add($this->m_oTabs->AddAjaxTab($sTabCode, $sUrl, $bCache, $sTabTitle, $sPlaceholder));
}
/**

View File

@@ -12,7 +12,8 @@
<li class="ibo-tab-container--tab-header" data-role="ibo-tab-container--tab-header"
data-tab-id="tab_{{ oTab.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER')) }}"
data-tab-type="{{ oTab.GetType() }}"
data-cache="{{ oTab.GetCache() }}">
data-cache="{{ oTab.GetCache() }}"
data-placeholder="{{ oTab.GetPlaceholderAbsPath() }}">
<a href="{{ oTab.GetUrl() }}" class="ibo-tab-container--tab-toggler"
data-role="ibo-tab-container--tab-toggler"><span>{{ oTab.GetTitle() }}</span></a>
</li>