mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
#704: preserve the content of a "linkedset" when changing the initial state of the object being created !
SVN:trunk[2737]
This commit is contained in:
@@ -80,6 +80,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
{
|
||||
protected $m_iFormId; // The ID of the form used to edit the object (when in edition mode !)
|
||||
static $iGlobalFormId = 1;
|
||||
protected $aFieldsMap;
|
||||
|
||||
/**
|
||||
* returns what will be the next ID for the forms
|
||||
@@ -289,6 +290,16 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
|
||||
return $aFieldsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a field to the map: attcode => id used when building a form
|
||||
* @param string $sAttCode The attribute code of the field being edited
|
||||
* @param string $sInputId The unique ID of the control/widget in the page
|
||||
*/
|
||||
protected function AddToFieldsMap($sAttCode, $sInputId)
|
||||
{
|
||||
$this->aFieldsMap[$sAttCode] = $sInputId;
|
||||
}
|
||||
|
||||
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
@@ -345,7 +356,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$sDisplayValue = ''; // not used
|
||||
$aArgs = array('this' => $this);
|
||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $oValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
||||
$aFieldsMap[$sAttCode] = $sInputId;
|
||||
$this->AddToFieldsMap($sAttCode, $sInputId);
|
||||
$oPage->add($sHTMLValue);
|
||||
}
|
||||
else
|
||||
@@ -1819,6 +1830,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
public function DisplayModifyForm(WebPage $oPage, $aExtraParams = array())
|
||||
{
|
||||
self::$iGlobalFormId++;
|
||||
$this->aFieldsMap = array();
|
||||
$sPrefix = '';
|
||||
if (isset($aExtraParams['formPrefix']))
|
||||
{
|
||||
@@ -1963,7 +1975,8 @@ EOF
|
||||
// Now display the relations, one tab per relation
|
||||
if (!isset($aExtraParams['noRelations']))
|
||||
{
|
||||
$this->DisplayBareRelations($oPage, true); // Edit mode
|
||||
$this->DisplayBareRelations($oPage, true); // Edit mode, will fill $this->aFieldsMap
|
||||
$aFieldsMap = array_merge($aFieldsMap, $this->aFieldsMap);
|
||||
}
|
||||
|
||||
$oPage->SetCurrentTab('');
|
||||
|
||||
@@ -106,7 +106,7 @@ class UILinksWidget
|
||||
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
||||
$aRow = array();
|
||||
$aFieldsMap = array();
|
||||
if(is_object($linkObjOrId))
|
||||
if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
||||
{
|
||||
$key = $linkObjOrId->GetKey();
|
||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||
@@ -130,12 +130,24 @@ class UILinksWidget
|
||||
else
|
||||
{
|
||||
// form for creating a new record
|
||||
if (is_object($linkObjOrId))
|
||||
{
|
||||
// New link existing only in memory
|
||||
$oNewLinkObj = $linkObjOrId;
|
||||
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
$linkObjOrId = -$iRemoteObjKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iRemoteObjKey = -$linkObjOrId;
|
||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, -$linkObjOrId);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
}
|
||||
$sPrefix .= "[$linkObjOrId][";
|
||||
$iRemoteObjKey = -$linkObjOrId;
|
||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, -$linkObjOrId);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".(-$linkObjOrId);
|
||||
@@ -275,6 +287,7 @@ EOF
|
||||
$sHtmlValue = '';
|
||||
$sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
||||
$sHtmlValue .= "<div id=\"linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
||||
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
|
||||
$oValue->Rewind();
|
||||
$aForm = array();
|
||||
while($oCurrentLink = $oValue->Fetch())
|
||||
@@ -284,7 +297,7 @@ EOF
|
||||
if ($oCurrentLink->IsNew())
|
||||
{
|
||||
$key = -$oLinkedObj->GetKey();
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $key, $aArgs, $oCurrentObj);
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -297,8 +310,9 @@ EOF
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper);
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}');
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
$('#{$this->m_iInputId}').bind('update_value', function() { $(this).val(oWidget{$this->m_iInputId}.GetUpdatedValue()); })
|
||||
EOF
|
||||
);
|
||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||
|
||||
@@ -4464,7 +4464,7 @@ class AttributeComputedFieldVoid extends AttributeDefinition
|
||||
public function GetEditClass() {return "";}
|
||||
|
||||
public function GetValuesDef() {return null;}
|
||||
public function GetPrerequisiteAttributes() {return $this->Get("depends_on");}
|
||||
public function GetPrerequisiteAttributes() {return $this->GetOptional("depends_on", array());}
|
||||
|
||||
public function IsDirectField() {return true;}
|
||||
public function IsScalar() {return true;}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// JavaScript Document
|
||||
function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizHelper)
|
||||
function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizHelper, sExtKeyToRemote)
|
||||
{
|
||||
this.id = id;
|
||||
this.iInputId = iInputId;
|
||||
@@ -8,6 +8,7 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH
|
||||
this.sSuffix = sSuffix;
|
||||
this.bDuplicates = bDuplicates;
|
||||
this.oWizardHelper = oWizHelper;
|
||||
this.sExtKeyToRemote = sExtKeyToRemote;
|
||||
var me = this;
|
||||
this.Init = function()
|
||||
{
|
||||
@@ -59,7 +60,7 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH
|
||||
{
|
||||
$('#'+me.id+'_btnRemove').attr('disabled','disabled');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.AddObjects = function()
|
||||
{
|
||||
@@ -288,4 +289,44 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH
|
||||
form_height = searchForm.outerHeight();
|
||||
results.height(height - form_height - 40); // Leave some space for the buttons
|
||||
};
|
||||
|
||||
this.GetUpdatedValue = function()
|
||||
{
|
||||
var sSelector = '#linkedset_'+me.id+' input[name^=attr_'+me.id+']';
|
||||
var aIndexes = [];
|
||||
var aValues = [];
|
||||
$(sSelector).each(function() {
|
||||
var re = /\[([^\[]+)\]\[(.+)\]/;
|
||||
var aMatches = [];
|
||||
if (aMatches = this.name.match(re))
|
||||
{
|
||||
var idx = aMatches[1];
|
||||
var index = aIndexes.indexOf(idx);
|
||||
if (index == -1)
|
||||
{
|
||||
aIndexes.push(idx);
|
||||
index = aIndexes.indexOf(idx);
|
||||
aValues[index] = {};
|
||||
}
|
||||
var value = $(this).val();
|
||||
if (aMatches[2] == "id")
|
||||
{
|
||||
var iId = parseInt(aMatches[1], 10);
|
||||
if (iId < 0)
|
||||
{
|
||||
aValues[index][me.sExtKeyToRemote] = -iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
aValues[index]['id'] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aValues[index][aMatches[2]] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
return JSON.stringify(aValues);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,19 +36,18 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
this.SetFieldsMap = function (oFieldsMap)
|
||||
{
|
||||
this.m_oData.m_oFieldsMap = oFieldsMap;
|
||||
}
|
||||
};
|
||||
|
||||
this.SetFieldsCount = function (count)
|
||||
{
|
||||
this.m_oData.m_iFieldsCount = count;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.GetFieldId = function(sFieldName)
|
||||
{
|
||||
id = this.m_oData.m_oFieldsMap[sFieldName];
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
this.RequestDefaultValue = function (sFieldName)
|
||||
{
|
||||
@@ -57,26 +56,28 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
{
|
||||
this.m_oData.m_aDefaultValueRequested.push(sFieldName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.RequestAllowedValues = function (sFieldName)
|
||||
{
|
||||
this.m_oData.m_aAllowedValuesRequested.push(sFieldName);
|
||||
}
|
||||
};
|
||||
|
||||
this.SetCurrentValue = function (sFieldName, currentValue)
|
||||
{
|
||||
this.m_oData.m_oCurrentValues[sFieldName] = currentValue;
|
||||
}
|
||||
};
|
||||
|
||||
this.ToJSON = function ()
|
||||
{
|
||||
return JSON.stringify(this.m_oData);
|
||||
}
|
||||
};
|
||||
|
||||
this.FromJSON = function (sJSON)
|
||||
{
|
||||
//console.log('Parsing JSON:'+sJSON);
|
||||
this.m_oData = JSON.parse(sJSON);
|
||||
}
|
||||
};
|
||||
|
||||
this.ResetQuery = function ()
|
||||
{
|
||||
@@ -84,7 +85,7 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
this.m_oData.m_oDefaultValue = {};
|
||||
this.m_oData.m_aAllowedValuesRequested = [];
|
||||
this.m_oData.m_oAllowedValues = {};
|
||||
}
|
||||
};
|
||||
|
||||
this.UpdateFields = function ()
|
||||
{
|
||||
@@ -120,10 +121,10 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
// For each "refreshed" field, asynchronously trigger a change in case there are dependent fields to update
|
||||
for(i=0; i<aRefreshed.length; i++)
|
||||
{
|
||||
var sString = "$('#"+aRefreshed[i]+"').trigger('change').trigger('update');"
|
||||
var sString = "$('#"+aRefreshed[i]+"').trigger('change').trigger('update');";
|
||||
window.setTimeout(sString, 1); // Synchronous 'trigger' does nothing, call it asynchronously
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.UpdateWizard = function ()
|
||||
{
|
||||
@@ -134,16 +135,13 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
//console.log(sFieldCode);
|
||||
this.UpdateCurrentValue(sCleanFieldCode);
|
||||
}
|
||||
// Remove unnecessary stuff
|
||||
this.m_oData.m_oDefaultValue = {};
|
||||
this.m_oData.m_oAllowedValues = {};
|
||||
}
|
||||
};
|
||||
|
||||
this.UpdateWizardToJSON = function ()
|
||||
{
|
||||
this.UpdateWizard();
|
||||
return this.ToJSON()
|
||||
}
|
||||
return this.ToJSON();
|
||||
};
|
||||
|
||||
this.AjaxQueryServer = function ()
|
||||
{
|
||||
@@ -159,7 +157,7 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
//console.log(oWizardHelper);
|
||||
//$('#wizStep'+ G_iCurrentStep).unblock( {fadeOut: 0} );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.Preview = function (divId)
|
||||
{
|
||||
@@ -170,10 +168,11 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
function(responseText, textStatus, XMLHttpRequest){
|
||||
$('#wizStep'+ G_iCurrentStep).unblock( {fadeOut: 0} );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.UpdateCurrentValue = function (sFieldCode)
|
||||
{
|
||||
$('#'+this.m_oData.m_oFieldsMap[sFieldCode]).trigger('update_value'); // Give the widget a chance to update its value (if it is aware of this event)
|
||||
value = $('#'+this.m_oData.m_oFieldsMap[sFieldCode]).val();
|
||||
if (value == '')
|
||||
{
|
||||
@@ -181,7 +180,7 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
}
|
||||
this.m_oData.m_oCurrentValues[sFieldCode] = value;
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
this.UpdateDependentFields = function(aFieldNames)
|
||||
{
|
||||
@@ -197,7 +196,7 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
index++;
|
||||
}
|
||||
this.AjaxQueryServer();
|
||||
}
|
||||
};
|
||||
|
||||
this.ReloadObjectCreationForm = function(sFormId, sTargetState)
|
||||
{
|
||||
@@ -224,5 +223,5 @@ function WizardHelper(sClass, sFormPrefix, sState)
|
||||
$('#'+sFormId).unblock();
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user