diff --git a/js/ui-block.js b/js/ui-block.js new file mode 100644 index 000000000..85493e8cc --- /dev/null +++ b/js/ui-block.js @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013-2021 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + */ + +; +$(function () { + // the widget definition, where 'itop' is the namespace, + // 'panel' the widget name + $.widget('itop.ui_block', + { + // default options + options: {}, + css_classes: { + is_sticking: 'ibo-is-sticking', + }, + js_selectors: { + // Selectors that target any elements in the DOM + global: { + modal: '.ui-dialog', + modal_content: '.ui-dialog-content', + }, + // Selectors that target only the elements of this block + block: {} + }, + + // the constructor + _create: function () { + this._initializeMarkup(); + this._bindEvents(); + }, + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function () { + }, + + /** + * Initialize some markup dynamically when the UIBlock needs it + * @return {void} + * @private + */ + _initializeMarkup: function () { + // Meant for overloading + }, + /** + * Bind events relative to the UIBlock + * @return {void} + * @private + */ + _bindEvents: function () { + // Meant for overloading + }, + }); +}); diff --git a/pages/ajax.render.php b/pages/ajax.render.php index ea5db9f20..fdc228792 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -82,9 +82,11 @@ try break; case 'search': - $oPage->SetContentType('application/json'); + $oPage = new JsonPage(); + // Feeds dataTables directly + $oPage->SetOutputDataOnly(true); $aResult = AjaxRenderController::Search($sEncoding, $sFilter); - $oPage->add(json_encode($aResult)); + $oPage->SetData($aResult); break; case 'refreshDashletCount': diff --git a/sources/application/UI/Base/Component/DataTable/DataTable.php b/sources/application/UI/Base/Component/DataTable/DataTable.php index fcd8387d7..11abd37ea 100644 --- a/sources/application/UI/Base/Component/DataTable/DataTable.php +++ b/sources/application/UI/Base/Component/DataTable/DataTable.php @@ -23,6 +23,10 @@ class DataTable extends UIContentBlock // Overloaded constants public const BLOCK_CODE = 'ibo-datatable'; + // This block is handled by its own lib (dataTables) + public const INCLUDE_ANCESTORS_DEFAULT_JS_FILES = false; + public const INCLUDE_ANCESTORS_DEFAULT_CSS_FILES = false; + public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/components/datatable/layout'; public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'base/components/datatable/layout'; public const DEFAULT_JS_LIVE_TEMPLATE_REL_PATH = 'base/components/datatable/layout'; diff --git a/sources/application/UI/Base/Layout/Object/ObjectDetails.php b/sources/application/UI/Base/Layout/Object/ObjectDetails.php index fbc5d6c66..88dad6b5b 100644 --- a/sources/application/UI/Base/Layout/Object/ObjectDetails.php +++ b/sources/application/UI/Base/Layout/Object/ObjectDetails.php @@ -21,7 +21,6 @@ class ObjectDetails extends Panel implements iKeyboardShortcut public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/object/object-details/layout'; public const DEFAULT_JS_TEMPLATE_REL_PATH = 'base/layouts/object/object-details/layout'; public const DEFAULT_JS_FILES_REL_PATH = [ - 'js/components/panel.js', 'js/layouts/object/object-details.js', ]; diff --git a/sources/application/UI/Base/UIBlock.php b/sources/application/UI/Base/UIBlock.php index 7a5b809c2..777103e95 100644 --- a/sources/application/UI/Base/UIBlock.php +++ b/sources/application/UI/Base/UIBlock.php @@ -38,6 +38,16 @@ abstract class UIBlock implements iUIBlock * should be "ibo-my-custom-clock") */ public const BLOCK_CODE = 'ibo-block'; + /** + * @var bool Set to true so the block automatically includes its ancestors' external JS files. If set to false, only the files from the block itself will be included + * @see static::DEFAULT_JS_FILES_REL_PATH + */ + public const INCLUDE_ANCESTORS_DEFAULT_JS_FILES = true; + /** + * @var bool Set to true so the block automatically includes its ancestors' external CSS files. If set to false, only the files from the block itself will be included + * @see static::DEFAULT_CSS_FILES_REL_PATH + */ + public const INCLUDE_ANCESTORS_DEFAULT_CSS_FILES = true; /** @var string|null */ public const DEFAULT_GLOBAL_TEMPLATE_REL_PATH = null; @@ -48,7 +58,9 @@ abstract class UIBlock implements iUIBlock * **Warning** : if you need to call a JS var defined in one of this file, then this calling code MUST be in {@see DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH} * and not in {@see DEFAULT_JS_TEMPLATE_REL_PATH} ! Indeed the later is output before external files loading. */ - public const DEFAULT_JS_FILES_REL_PATH = []; + public const DEFAULT_JS_FILES_REL_PATH = [ + 'js/ui-block.js', + ]; /** @var string|null */ public const DEFAULT_JS_TEMPLATE_REL_PATH = null; /** @var string|null Relative path (from /templates/) to the JS template not deferred */ @@ -88,9 +100,9 @@ abstract class UIBlock implements iUIBlock /** @var string Relative path (from /templates/) to the CSS template */ protected $sCssTemplateRelPath; /** @var array Relative paths (from /) to the JS files */ - protected $aJsFilesRelPath; + protected $aJsFilesRelPath = []; /** @var array Relative paths (from /) to the CSS files */ - protected $aCssFilesRelPath; + protected $aCssFilesRelPath = []; /** @var array Array => which will be output as HTML data-xxx attributes (eg. data-="") */ protected $aDataAttributes = []; /** @var bool Whether the current block is shown or hidden */ @@ -106,8 +118,23 @@ abstract class UIBlock implements iUIBlock public function __construct(?string $sId = null) { $this->sId = $sId ?? $this->GenerateId(); - $this->aJsFilesRelPath = static::DEFAULT_JS_FILES_REL_PATH; - $this->aCssFilesRelPath = static::DEFAULT_CSS_FILES_REL_PATH; + + // Add external JS files + if(static::INCLUDE_ANCESTORS_DEFAULT_JS_FILES){ + foreach(array_reverse(class_parents(static::class)) as $sParentClass){ + $this->AddMultipleJsFilesRelPaths($sParentClass::DEFAULT_JS_FILES_REL_PATH); + } + } + $this->AddMultipleJsFilesRelPaths(static::DEFAULT_JS_FILES_REL_PATH); + + // Add external CSS files + if(static::INCLUDE_ANCESTORS_DEFAULT_CSS_FILES){ + foreach(array_reverse(class_parents(static::class)) as $sParentClass){ + $this->AddMultipleCssFilesRelPaths($sParentClass::DEFAULT_CSS_FILES_REL_PATH); + } + } + $this->AddMultipleCssFilesRelPaths(static::DEFAULT_CSS_FILES_REL_PATH); + $this->sHtmlTemplateRelPath = static::DEFAULT_HTML_TEMPLATE_REL_PATH; $this->aJsTemplatesRelPath[self::ENUM_JS_TYPE_LIVE] = static::DEFAULT_JS_LIVE_TEMPLATE_REL_PATH; $this->aJsTemplatesRelPath[self::ENUM_JS_TYPE_ON_INIT] = static::DEFAULT_JS_TEMPLATE_REL_PATH; @@ -238,7 +265,21 @@ abstract class UIBlock implements iUIBlock */ public function AddJsFileRelPath(string $sPath) { - $this->aJsFilesRelPath[] = $sPath; + if(!in_array($sPath, $this->aJsFilesRelPath)) { + $this->aJsFilesRelPath[] = $sPath; + } + + return $this; + } + + /** + * @inheritDoc + */ + public function AddMultipleJsFilesRelPaths(array $aPaths) + { + foreach($aPaths as $sPath){ + $this->AddJsFileRelPath($sPath); + } return $this; } @@ -248,7 +289,21 @@ abstract class UIBlock implements iUIBlock */ public function AddCssFileRelPath(string $sPath) { - $this->aCssFilesRelPath[] = $sPath; + if(!in_array($sPath, $this->aCssFilesRelPath)) { + $this->aCssFilesRelPath[] = $sPath; + } + + return $this; + } + + /** + * @inheritDoc + */ + public function AddMultipleCssFilesRelPaths(array $aPaths) + { + foreach($aPaths as $sPath){ + $this->AddCssFileRelPath($sPath); + } return $this; } diff --git a/sources/application/UI/Base/iUIBlock.php b/sources/application/UI/Base/iUIBlock.php index 14dd53917..a6cf8b7d6 100644 --- a/sources/application/UI/Base/iUIBlock.php +++ b/sources/application/UI/Base/iUIBlock.php @@ -137,7 +137,7 @@ interface iUIBlock { public function GetParameters(): array; /** - * Add a JS file to a block + * Add a JS file to a block (if not already present) * * @param string $sPath relative path of a JS file to add * @@ -146,7 +146,17 @@ interface iUIBlock { public function AddJsFileRelPath(string $sPath); /** - * Add a CSS file to a block + * Add several JS files to a block. + * Duplicates will not be added. + * + * @param string[] $aPaths + * + * @return mixed + */ + public function AddMultipleJsFilesRelPaths(array $aPaths); + + /** + * Add a CSS file to a block (if not already present) * * @param string $sPath relative path of a CSS file to add * @@ -154,4 +164,14 @@ interface iUIBlock { */ public function AddCssFileRelPath(string $sPath); + /** + * Add several CSS files to a block. + * Duplicates will not be added. + * + * @param string[] $aPaths + * + * @return mixed + */ + public function AddMultipleCssFilesRelPaths(array $aPaths); + }