diff --git a/js/dataTables.pipeline.js b/js/dataTables.pipeline.js index 05d12c950..592e6941f 100644 --- a/js/dataTables.pipeline.js +++ b/js/dataTables.pipeline.js @@ -8,7 +8,7 @@ // var numberCachePages = 5; -$.fn.dataTable.pipeline = function (opts) { +$.fn.dataTable.pipeline = function (opts, initJson) { // Configuration options var conf = $.extend({ pages: numberCachePages, // number of pages to cache @@ -75,8 +75,12 @@ $.fn.dataTable.pipeline = function (opts) { ajax = true; } } - - if (settings.clearCache) { + if (request.draw == 1 && initJson != null) { + //do nothing + cacheLastJson = $.extend(true, {}, initJson); + cacheLower = 0; + cacheUpper = initJson.data.length; + } else if (settings.clearCache) { // API requested that the cache be cleared ajax = true; settings.clearCache = false; diff --git a/sources/Controller/AjaxRenderController.php b/sources/Controller/AjaxRenderController.php index 57e138a2e..f9cc72897 100644 --- a/sources/Controller/AjaxRenderController.php +++ b/sources/Controller/AjaxRenderController.php @@ -36,6 +36,66 @@ use WizardHelper; class AjaxRenderController { + /** + * @param \DBObjectSet $oSet + * @param $aResult + * @param array $aClassAliases + * @param array $aColumnsLoad + * @param string $sIdName + * @param array $aExtraParams + * @param int $iDrawNumber + * + * @return mixed + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + */ + public static function GetDataForTable(DBObjectSet $oSet, array $aClassAliases, array $aColumnsLoad, string $sIdName = "", array $aExtraParams = [], int $iDrawNumber = 1) + { + if (isset($aExtraParams['show_obsolete_data'])) { + $bShowObsoleteData = $aExtraParams['show_obsolete_data']; + } else { + $bShowObsoleteData = utils::ShowObsoleteData(); + } + $oSet->SetShowObsoleteData($bShowObsoleteData); + $oKPI = new ExecutionKPI(); + $aResult["draw"] = $iDrawNumber; + $aResult["recordsTotal"] = $oSet->Count(); + $aResult["recordsFiltered"] = $oSet->Count(); + $aResult["data"] = []; + while ($aObject = $oSet->FetchAssoc()) { + $aObj = []; + foreach ($aClassAliases as $sAlias => $sClass) { + if (isset($aObject[$sAlias]) && !is_null($aObject[$sAlias])) { + $aObj[$sAlias."/_key_"] = $aObject[$sAlias]->GetKey(); + $aObj[$sAlias."/hyperlink"] = $aObject[$sAlias]->GetHyperlink(); + foreach ($aColumnsLoad[$sAlias] as $sAttCode) { + $aObj[$sAlias."/".$sAttCode] = $aObject[$sAlias]->GetAsHTML($sAttCode); + } + $sObjHighlightClass = $aObject[$sAlias]->GetHilightClass(); + if (!empty($sObjHighlightClass)) { + $aObj['@class'] = 'ibo-is-'.$sObjHighlightClass; + } + } + } + if (isset($aObj)) { + if ($sIdName != "") { + if (isset($aObj[$sIdName])) { + $aObj["id"] = $aObj[$sIdName]; + } else { + throw new Exception(Dict::Format('UI:Error:AnErrorOccuredWhileRunningTheQuery_Message', $oSet->GetFilter()->ToOQL())); + } + } + array_push($aResult["data"], $aObj); + } + } + $oKPI->ComputeAndReport('Data fetch and format'); + + return $aResult; + } + /** * @param \AjaxPage $oPage * @@ -220,16 +280,16 @@ class AjaxRenderController } else { $oFilter = DBSearch::unserialize($sFilter); } - $iStart = utils::ReadParam('start', 0); - $iEnd = utils::ReadParam('end', 1); - $iDrawNumber = utils::ReadParam('draw', 1); + $iStart = utils::ReadParam('start', 0, false, 'integer'); + $iEnd = utils::ReadParam('end', 1, false, 'integer'); + $iDrawNumber = utils::ReadParam('draw', 1, false, 'integer'); $aSort = utils::ReadParam('order', [], false, 'array'); $bForceSort = false; if (count($aSort) > 0) { $iSortCol = $aSort[0]["column"]; $sSortOrder = $aSort[0]["dir"]; - } else{ + } else { $bForceSort = true; $iSortCol = 0; $sSortOrder = "asc"; @@ -389,46 +449,7 @@ class AjaxRenderController $oSet = new DBObjectSet($oFilter, $aOrderBy, $aQueryParams, null, $iEnd - $iStart, $iStart); $oSet->OptimizeColumnLoad($aColumnsLoad); - if (isset($aExtraParams['show_obsolete_data'])) { - $bShowObsoleteData = $aExtraParams['show_obsolete_data']; - } else { - $bShowObsoleteData = utils::ShowObsoleteData(); - } - $oSet->SetShowObsoleteData($bShowObsoleteData); - $oKPI = new ExecutionKPI(); - $aResult["draw"] = $iDrawNumber; - $aResult["recordsTotal"] = $oSet->Count(); - $aResult["recordsFiltered"] = $oSet->Count(); - $aResult["data"] = []; - while ($aObject = $oSet->FetchAssoc()) { - $aObj = []; - foreach ($aClassAliases as $sAlias => $sClass) { - if (isset($aObject[$sAlias]) && !is_null($aObject[$sAlias])) { - $aObj[$sAlias."/_key_"] = $aObject[$sAlias]->GetKey(); - $aObj[$sAlias."/hyperlink"] = $aObject[$sAlias]->GetHyperlink(); - foreach ($aColumnsLoad[$sAlias] as $sAttCode) { - $aObj[$sAlias."/".$sAttCode] = $aObject[$sAlias]->GetAsHTML($sAttCode); - } - $sObjHighlightClass = $aObject[$sAlias]->GetHilightClass(); - if (!empty($sObjHighlightClass)) { - $aObj['@class'] = 'ibo-is-'.$sObjHighlightClass; - } - } - } - if (isset($aObj)) { - if ($sIdName != "") { - if (isset($aObj[$sIdName])) { - $aObj["id"] = $aObj[$sIdName]; - } else { - throw new Exception(Dict::Format('UI:Error:AnErrorOccuredWhileRunningTheQuery_Message', $oSet->GetFilter()->ToOQL())); - } - } - array_push($aResult["data"], $aObj); - } - } - $oKPI->ComputeAndReport('Data fetch and format'); - - return $aResult; + return self::GetDataForTable($oSet, $aClassAliases, $aColumnsLoad, $sIdName, $aExtraParams, $iDrawNumber); } /** diff --git a/sources/application/UI/Base/Component/DataTable/DataTable.php b/sources/application/UI/Base/Component/DataTable/DataTable.php index 5f85093b1..201564677 100644 --- a/sources/application/UI/Base/Component/DataTable/DataTable.php +++ b/sources/application/UI/Base/Component/DataTable/DataTable.php @@ -44,6 +44,7 @@ class DataTable extends UIContentBlock protected $aAjaxData; protected $aDisplayColumns; protected $aResultColumns; + protected $sJsonData; /** * Panel constructor. @@ -57,6 +58,7 @@ class DataTable extends UIContentBlock $this->aDisplayColumns = []; $this->aOptions = []; $this->aResultColumns = []; + $this->sJsonData = ''; } /** @@ -176,6 +178,26 @@ class DataTable extends UIContentBlock $this->aOptions = $aOptions; } + /** + * @return string + */ + public function GetJsonData(): string + { + return $this->sJsonData; + } + + /** + * @param string $aData + * + * @return $this + */ + public function SetJsonData(string $sJSON) + { + $this->sJsonData = $sJSON; + + return $this; + } + public function GetJSRefresh(): string { return "$('#".$this->sId."').DataTable().clearPipeline(); @@ -185,15 +207,17 @@ class DataTable extends UIContentBlock public function GetDisabledSelect(): array { $aExtraParams = $this->aAjaxData['extra_params']; - if(isset($aExtraParams['selection_enabled']) ){ + if (isset($aExtraParams['selection_enabled'])) { $aListDisabled = []; - foreach( $aExtraParams['selection_enabled'] as $sKey=>$bValue){ + foreach ($aExtraParams['selection_enabled'] as $sKey => $bValue) { if ($bValue == false) { $aListDisabled[] = $sKey; } } + return $aListDisabled; } + return []; } } diff --git a/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php b/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php index 728faeee6..c4d03b66a 100644 --- a/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php +++ b/sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php @@ -18,6 +18,7 @@ use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory; use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock; +use Combodo\iTop\Controller\AjaxRenderController; use DBObjectSet; use Dict; use MenuBlock; @@ -286,14 +287,14 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $oSet->SetLimit($oCustomSettings->iDefaultPageSize); } - if (count($oCustomSettings->aColumns) == 0) - { + if (count($oCustomSettings->aColumns) == 0) { $oCustomSettings->aColumns = $oDefaultSettings->aColumns; } - if(count($oCustomSettings->GetSortOrder()) == 0){ + if (count($oCustomSettings->GetSortOrder()) == 0) { $oCustomSettings->aSortOrder = $oDefaultSettings->aSortOrder; } + $sIdName = isset($extraParams["id_for_select"]) ? $extraParams["id_for_select"] : ""; // Load only the requested columns $aColumnsToLoad = array(); foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) { @@ -313,6 +314,10 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $aColumnsToLoad[$sAlias][] = $sAttCode; } } + } else { + if ($sIdName == "") { + $sIdName = $sAlias."/_key_"; + } } } } @@ -420,15 +425,16 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $oDataTable->SetOptions($aOptions); $oDataTable->SetAjaxUrl(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php"); $oDataTable->SetAjaxData([ - "operation" => 'search', - "filter" => $oSet->GetFilter()->serialize(), - "columns" => $oCustomSettings->aColumns, - "extra_params" => $aExtraParams, + "operation" => 'search', + "filter" => $oSet->GetFilter()->serialize(), + "columns" => $oCustomSettings->aColumns, + "extra_params" => $aExtraParams, "class_aliases" => $aClassAliases, - "select_mode" => $sSelectMode, + "select_mode" => $sSelectMode, ]); $oDataTable->SetDisplayColumns($aColumnDefinition); $oDataTable->SetResultColumns($oCustomSettings->aColumns); + $oDataTable->SetJsonData(json_encode(AjaxRenderController::GetDataForTable($oSet, $aClassAliases, $aColumnsToLoad, $sIdName, $aExtraParams))); return $oDataTable; } @@ -538,6 +544,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $oSet->SetLimit($oCustomSettings->iDefaultPageSize); } + $sIdName = isset($extraParams["id_for_select"]) ? $extraParams["id_for_select"] : ""; // Load only the requested columns $aColumnsToLoad = array(); foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) { @@ -553,13 +560,16 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $aColumnsToLoad[$sAlias][] = $sAttCode; } } + } else { + if ($sIdName == "") { + $sIdName = $sAlias."/_key_"; + } } } } $oSet->OptimizeColumnLoad($aColumnsToLoad); $aColumnDefinition = []; - $aSortOrder = []; $iIndexColumn = 0; $bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false; @@ -647,15 +657,16 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory $oDataTable->SetOptions($aOptions); $oDataTable->SetAjaxUrl("ajax.render.php"); $oDataTable->SetAjaxData([ - "operation" => 'search', - "filter" => $oSet->GetFilter()->serialize(), - "columns" => $oCustomSettings->aColumns, - "extra_params" => $aExtraParams, + "operation" => 'search', + "filter" => $oSet->GetFilter()->serialize(), + "columns" => $oCustomSettings->aColumns, + "extra_params" => $aExtraParams, "class_aliases" => $aClassAliases, - "select_mode" => $sSelectMode, + "select_mode" => $sSelectMode, ]); $oDataTable->SetDisplayColumns($aColumnDefinition); $oDataTable->SetResultColumns($oCustomSettings->aColumns); + $oDataTable->SetJsonData(json_encode(AjaxRenderController::GetDataForTable($oSet, $aClassAliases, $aColumnsToLoad, $sIdName, $aExtraParams))); return $oDataTable; } diff --git a/templates/base/components/datatable/layout.ready.js.twig b/templates/base/components/datatable/layout.ready.js.twig index 0281aad96..6da80ab43 100644 --- a/templates/base/components/datatable/layout.ready.js.twig +++ b/templates/base/components/datatable/layout.ready.js.twig @@ -162,11 +162,13 @@ var oTable{{ sListIDForVarSuffix }} = $('#{{ oUIBlock.GetId() }}').DataTable({ {% endfor %} ], ajax: $.fn.dataTable.pipeline({ - url: "{{ oUIBlock.GetAjaxUrl() }}", - data: {{ oUIBlock.GetJsonAjaxData() |raw }}, - method: "post", - pages: 1 // number of pages to cache - }), + url: "{{ oUIBlock.GetAjaxUrl() }}", + data: {{ oUIBlock.GetJsonAjaxData() |raw }}, + method: "post", + pages: 1 + }, // number of pages to cache + {{ oUIBlock.GetJsonData() |raw }} + ), createdRow: function (row, data, dataIndex) { if (data['@class'] !== undefined) {