diff --git a/application/dashboard.class.inc.php b/application/dashboard.class.inc.php
index be0ebda65..35b9833e6 100644
--- a/application/dashboard.class.inc.php
+++ b/application/dashboard.class.inc.php
@@ -46,8 +46,6 @@ abstract class Dashboard
protected $aCells;
/** @var \ModelReflection $oMetaModel */
protected $oMetaModel;
- /** @var bool $bCustomized */
- protected $bCustomized;
/**
* Dashboard constructor.
@@ -63,7 +61,6 @@ abstract class Dashboard
$this->aCells = array();
$this->oDOMNode = null;
$this->sId = $sId;
- $this->bCustomized = false;
}
/**
@@ -421,24 +418,6 @@ abstract class Dashboard
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$iAutoReloadSec);
}
- /**
- * @return bool
- * @since 2.7.0
- */
- public function GetCustomFlag()
- {
- return $this->bCustomized;
- }
-
- /**
- * @param bool $bCustomized
- * @since 2.7.0
- */
- public function SetCustomFlag($bCustomized)
- {
- $this->bCustomized = $bCustomized;
- }
-
/**
* @param \Dashlet $oDashlet
*/
@@ -619,13 +598,9 @@ EOF
/** @var \Dashlet $oDashlet */
foreach($aCell as $oDashlet)
{
-
- $aDashletCoordinates = $oLayout->GetDashletCoordinates($iCellIdx);
- $sId = $oDashlet->GetID();
- $sFinalId = static::GetDashletUniqueId($this->bCustomized, $this->GetSanitizedId(), $aDashletCoordinates[1], $aDashletCoordinates[0], $sId);
if ($oDashlet->IsVisible())
{
- $oPage->add('
');
+ $oPage->add('
');
$oForm = $oDashlet->GetForm();
$this->SetFormParams($oForm, $aExtraParams);
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
@@ -689,20 +664,16 @@ EOF
}
/**
- * Prepare dashlet for rendering:
- * - Fix ID to unique within the dashboard
+ * Prepare dashlet for rendering (eg. change its ID or another processing).
+ * Meant to be overloaded.
*
* @param \Dashlet $oDashlet
- * @param array $aCoordinates Contains x, y (starting from 0)
+ * @param array $aCoordinates
* @param array $aExtraParams
+ *
+ * @return void
*/
- protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
- {
- $sDashletIdOrig = $oDashlet->GetID();
- $sDashboardSanitizedId = $this->GetSanitizedId();
- $sDashletIdNew = static::GetDashletUniqueId($this->GetCustomFlag(), $sDashboardSanitizedId, $aCoordinates[1], $aCoordinates[0], $sDashletIdOrig);
- $oDashlet->SetID($sDashletIdNew);
- }
+ abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array());
/**
* @param \DesignerForm $oForm
@@ -744,12 +715,12 @@ EOF
*/
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
{
- if(strpos($sDashletOrigId, 'IDrow') !== false)
+ if(strpos($sDashletOrigId, '_ID_row') !== false)
{
return $sDashletOrigId;
}
- $sDashletId = $sDashboardDivId."_IDrow$iRow-col$iCol-$sDashletOrigId";
+ $sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
if ($bIsCustomized)
{
$sDashletId = 'CUSTOM_'.$sDashletId;
@@ -768,6 +739,8 @@ class RuntimeDashboard extends Dashboard
private $sDefinitionFile = '';
/** @var null $sReloadURL */
private $sReloadURL = null;
+ /** @var bool $bCustomized */
+ protected $bCustomized;
/**
* @inheritDoc
@@ -776,6 +749,25 @@ class RuntimeDashboard extends Dashboard
{
parent::__construct($sId);
$this->oMetaModel = new ModelReflectionRuntime();
+ $this->bCustomized = false;
+ }
+
+ /**
+ * @return bool
+ * @since 2.7.0
+ */
+ public function GetCustomFlag()
+ {
+ return $this->bCustomized;
+ }
+
+ /**
+ * @param bool $bCustomized
+ * @since 2.7.0
+ */
+ public function SetCustomFlag($bCustomized)
+ {
+ $this->bCustomized = $bCustomized;
}
/**
@@ -1515,7 +1507,9 @@ JS
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
{
$sDashletIdOrig = $oDashlet->GetID();
- parent::PrepareDashletForRendering($oDashlet, $aCoordinates);
+ $sDashboardSanitizedId = $this->GetSanitizedId();
+ $sDashletIdNew = static::GetDashletUniqueId($this->GetCustomFlag(), $sDashboardSanitizedId, $aCoordinates[1], $aCoordinates[0], $sDashletIdOrig);
+ $oDashlet->SetID($sDashletIdNew);
$this->UpdateDashletUserPrefs($oDashlet, $sDashletIdOrig, $aExtraParams);
}
diff --git a/js/dashboard.js b/js/dashboard.js
index a39e516d6..4c8350bcc 100644
--- a/js/dashboard.js
+++ b/js/dashboard.js
@@ -144,29 +144,27 @@ $(function()
}
});
},
- // We need a unique dashlet id, we will get it using an ajax query
- _get_dashletid_ajax: function(options, sTempDashletId)
- {
- var me = this;
- var $container = options.container;
- var oParams = this.options.new_dashletid_parameters;
- oParams.dashboardid = me.options.dashboard_id;
- oParams.iRow = $container.closest("tr").data("dashboard-row-index");
- oParams.iCol = $container.data("dashboard-column-index");
- oParams.dashletid = sTempDashletId;
-
- $.post(this.options.new_dashletid_endpoint, oParams, function(data) {
- var sFinalDashletId = data;
- me.add_dashlet_prepare(options, sFinalDashletId);
- });
- },
add_dashlet: function(options)
{
- var $container = options.container,
- iNumberOfExistingDashletsInDashboard = $container.closest("table").find("div.dashlet").length,
- sTempDashletId = iNumberOfExistingDashletsInDashboard+1;
+ var $container = options.container;
+ var aDashletsIds = $container.closest("table").find("div.dashlet").map(function(){
+ // Note:
+ // - At runtime a unique dashlet ID is generated (see \Dashboard::GetDashletUniqueId) to avoid JS widget collisions
+ // - At design time, the dashlet ID is not touched (same as in the XML datamodel)
+ var sDashletUniqueId = $(this).attr("id");
+ var sDashletIdParts = sDashletUniqueId.split('_');
+ var sDashletOrigId = sDashletIdParts[sDashletIdParts.length - 1];
+ return isNaN(sDashletOrigId) ? 0 : parseInt(sDashletOrigId);
+ }).get();
+ // Note: Use of .apply() to be compatible with IE10
+ var iHighestDashletOrigId = Math.max.apply(null, aDashletsIds);
- this._get_dashletid_ajax(options, sTempDashletId);
+ this._get_dashletid_ajax(options, iHighestDashletOrigId + 1);
+ },
+ // Get the real dashlet ID from the temporary ID
+ _get_dashletid_ajax: function(options, sTempDashletId)
+ {
+ // Do nothing, meant for overloading
},
add_dashlet_prepare: function(options, sFinalDashletId)
{
@@ -333,6 +331,22 @@ $(function()
}
});
},
+ // We need a unique dashlet id, we will get it using an ajax query
+ _get_dashletid_ajax: function(options, sTempDashletId)
+ {
+ var me = this;
+ var $container = options.container;
+ var oParams = this.options.new_dashletid_parameters;
+ oParams.dashboardid = me.options.dashboard_id;
+ oParams.iRow = $container.closest("tr").data("dashboard-row-index");
+ oParams.iCol = $container.data("dashboard-column-index");
+ oParams.dashletid = sTempDashletId;
+
+ $.post(this.options.new_dashletid_endpoint, oParams, function(data) {
+ var sFinalDashletId = data;
+ me.add_dashlet_prepare(options, sFinalDashletId);
+ });
+ },
add_dashlet_ajax: function(options, sDashletId)
{
var oParams = this.options.new_dashlet_parameters;
diff --git a/pages/ajax.render.php b/pages/ajax.render.php
index 17e8f90be..07d75b609 100644
--- a/pages/ajax.render.php
+++ b/pages/ajax.render.php
@@ -57,7 +57,6 @@ try
case 'cke_img_upload':
case 'cke_upload_and_browse':
case 'cke_browse':
- case 'new_dashlet_id':
$sRequestedPortalId = null;
break;
@@ -1218,7 +1217,7 @@ EOF
case 'new_dashlet_id':
$sDashboardDivId = utils::ReadParam("dashboardid");
- $bIsCustomized = utils::ReadParam("isCustomized", "true") === "true";
+ $bIsCustomized = true; // Only called at runtime when customizing a dashboard
$iRow = utils::ReadParam("iRow");
$iCol = utils::ReadParam("iCol");
$sDashletIdOrig = utils::ReadParam("dashletid");