|
@@ -32,6 +32,11 @@ class UILinksWidget
|
|
|
protected $m_sAttCode;
|
|
|
protected $m_sNameSuffix;
|
|
|
protected $m_iInputId;
|
|
|
+ protected $m_aAttributes;
|
|
|
+ protected $m_sExtKeyToRemote;
|
|
|
+ protected $m_sLinkedClass;
|
|
|
+ protected $m_sRemoteClass;
|
|
|
+ protected static $iWidgetIndex = 0;
|
|
|
|
|
|
public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '')
|
|
|
{
|
|
@@ -39,120 +44,197 @@ class UILinksWidget
|
|
|
$this->m_sAttCode = $sAttCode;
|
|
|
$this->m_sNameSuffix = $sNameSuffix;
|
|
|
$this->m_iInputId = $iInputId;
|
|
|
- }
|
|
|
-
|
|
|
- public function Display(WebPage $oPage, $oCurrentValuesSet = null)
|
|
|
- {
|
|
|
- $sHTMLValue = '';
|
|
|
- $sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
|
|
- // #@# todo - add context information, otherwise any value will be authorized for external keys
|
|
|
- $aAllowedValues = MetaModel::GetAllowedValues_att($this->m_sClass, $this->m_sAttCode, array(), '');
|
|
|
+ $this->m_aEditableFields = array();
|
|
|
+ self::$iWidgetIndex++;
|
|
|
+
|
|
|
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
|
|
- $sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
|
|
+ $this->m_sLinkedClass = $oAttDef->GetLinkedClass();
|
|
|
+ $this->m_sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
|
|
+ $oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
|
|
+ $this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
|
|
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
|
|
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
|
|
- $sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
|
|
+ $sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
|
|
|
|
|
- $aAttributes = array();
|
|
|
- $sLinkedClass = $oAttDef->GetLinkedClass();
|
|
|
- foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
|
|
+ $this->m_aEditableFields = array();
|
|
|
+ $this->m_aTableConfig = array();
|
|
|
+ $this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onChange=\"var value = this.checked; $('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection').each( function() { this.checked = value; } ); oWidget".self::$iWidgetIndex.".OnSelectChange();\">", 'description' => Dict::S('UI:SelectAllToggle+'));
|
|
|
+
|
|
|
+ foreach(MetaModel::ListAttributeDefs($this->m_sLinkedClass) as $sAttCode=>$oAttDef)
|
|
|
{
|
|
|
if ($sStateAttCode == $sAttCode)
|
|
|
{
|
|
|
// State attribute is always hidden from the UI
|
|
|
}
|
|
|
- else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
|
|
+ else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $this->m_sExtKeyToRemote) && ($sAttCode != 'finalclass'))
|
|
|
{
|
|
|
- $iFlags = MetaModel::GetAttributeFlags($this->m_sClass, $sDefaultState, $sAttCode);
|
|
|
+ $iFlags = MetaModel::GetAttributeFlags($this->m_sLinkedClass, $sDefaultState, $sAttCode);
|
|
|
if ( !($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY) )
|
|
|
{
|
|
|
- $aAttributes[] = $sAttCode;
|
|
|
+ $this->m_aEditableFields[] = $sAttCode;
|
|
|
+ $this->m_aTableConfig[$sAttCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- $sAttributes = '[]';
|
|
|
- if (count($aAttributes) > 0)
|
|
|
+ foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
|
|
{
|
|
|
- $sAttributes = "['".implode("','", $aAttributes)."']";
|
|
|
+ // TO DO: check the state of the attribute: hidden or visible ?
|
|
|
+ if ($sFieldCode != 'finalclass')
|
|
|
+ {
|
|
|
+ $oAttDef = MetaModel::GetAttributeDef($this->m_sRemoteClass, $sFieldCode);
|
|
|
+ $this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
|
|
+ }
|
|
|
}
|
|
|
- if ($oCurrentValuesSet != null)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A one-row form for editing a link record
|
|
|
+ * @param WebPage $oP Web page used for the ouput
|
|
|
+ * @param DBObject $oLinkedObj The object to which all the elements of the linked set refer to
|
|
|
+ * @param mixed $linkObjOrId Either the object linked or a unique number for new link records to add
|
|
|
+ * @param Hash $aArgs Extra context arguments
|
|
|
+ * @return string The HTML fragment of the one-row form
|
|
|
+ */
|
|
|
+ protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId = null, $aArgs = array() )
|
|
|
+ {
|
|
|
+ $sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
|
|
+ $aRow = array();
|
|
|
+ if(is_object($linkObjOrId))
|
|
|
{
|
|
|
- // Serialize the link set into a JSon object
|
|
|
- $aCurrentValues = array();
|
|
|
- $oCurrentValuesSet->Rewind(); // Make sure we can iterate through this set...
|
|
|
- while($oLinkObj = $oCurrentValuesSet->Fetch())
|
|
|
+ $key = $linkObjOrId->GetKey();
|
|
|
+ $sPrefix .= "[$key][";
|
|
|
+ $sNameSuffix = "]"; // To make a tabular form
|
|
|
+ $aArgs['prefix'] = $sPrefix;
|
|
|
+ $aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onChange=\"oWidget".self::$iWidgetIndex.".OnSelectChange();\" value=\"$key\">";
|
|
|
+ foreach($this->m_aEditableFields as $sFieldCode)
|
|
|
{
|
|
|
- $sRow = '{';
|
|
|
- foreach($aAttributes as $sLinkAttCode)
|
|
|
- {
|
|
|
- $sRow.= "\"$sLinkAttCode\": \"".addslashes($oLinkObj->Get($sLinkAttCode))."\", ";
|
|
|
- }
|
|
|
- $sRow .= "\"$sExtKeyToRemote\": ".$oLinkObj->Get($sExtKeyToRemote).'}';
|
|
|
- $aCurrentValues[] = $sRow;
|
|
|
+ $oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
|
|
+ $aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $linkObjOrId->Get($sFieldCode), '' /* DisplayValue */, $key, $sNameSuffix, 0, $aArgs);
|
|
|
}
|
|
|
- $sJSON = '['.implode(',', $aCurrentValues).']';
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- $sJSON = '[]'; // Empty array;
|
|
|
-//echo "JSON VA IECH<br/>\n";
|
|
|
+ // form for creating a new record
|
|
|
+ $sPrefix .= "[$linkObjOrId][";
|
|
|
+ $sNameSuffix = "]"; // To make a tabular form
|
|
|
+ $aArgs['prefix'] = $sPrefix;
|
|
|
+ $aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onChange=\"oWidget".self::$iWidgetIndex.".OnSelectChange();\" value=\"$linkObjOrId\">";
|
|
|
+ $aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"attr_attr_{$sPrefix}id{$sNameSuffix}\" value=\"\">";
|
|
|
+ foreach($this->m_aEditableFields as $sFieldCode)
|
|
|
+ {
|
|
|
+ $oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
|
|
+ $aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue($oObject->ToArgs()) */, '' /* DisplayValue */, '' /* id */, $sNameSuffix, 0, $aArgs);
|
|
|
+ }
|
|
|
}
|
|
|
-//echo "JASON: $sJSON<br/>\n";;
|
|
|
|
|
|
- // Many values (or even a unknown list) display an autocomplete
|
|
|
- if ( (count($aAllowedValues) == 0) || (count($aAllowedValues) > 50) )
|
|
|
+ foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
|
|
{
|
|
|
- // too many choices, use an autocomplete
|
|
|
- // The input for the auto complete
|
|
|
- $sTitle = $oAttDef->GetDescription();
|
|
|
- $sHTMLValue .= "<script type=\"text/javascript\">\n";
|
|
|
- $sHTMLValue .= "oLinkWidget{$this->m_iInputId} = new LinksWidget('{$this->m_iInputId}', '$sLinkedClass', '$sExtKeyToMe', '$sExtKeyToRemote', $sAttributes);\n";
|
|
|
- $sHTMLValue .= "</script>\n";
|
|
|
- $oPage->add_at_the_end($this->GetObjectPickerDialog($oPage, $sTargetClass, 'oLinkWidget'.$this->m_iInputId.'.OnOk')); // Forms should not be inside forms
|
|
|
- $oPage->add_at_the_end($this->GetLinkObjectDialog($oPage, $this->m_iInputId)); // Forms should not be inside forms
|
|
|
- $sHTMLValue .= "<input type=\"text\" id=\"ac_{$this->m_iInputId}\" size=\"35\" value=\"\" title=\"".Dict::S('UI:LinksWidget:Autocomplete+')."\"/>";
|
|
|
- $sHTMLValue .= "<input type=\"button\" id=\"ac_add_{$this->m_iInputId}\" value=\"".Dict::S('UI:Button:AddObject')."\" class=\"action\" onClick=\"oLinkWidget{$this->m_iInputId}.AddObject();\"/>";
|
|
|
- $sHTMLValue .= " <input type=\"button\" value=\"".Dict::S('UI:Button:BrowseObjects')."\" class=\"action\" onClick=\"return ManageObjects('$sTitle', '$sTargetClass', '$this->m_iInputId', '$sExtKeyToRemote');\"/> <span id=\"v_{$this->m_iInputId}\"></span>\n";
|
|
|
- // another hidden input to store & pass the object's Id
|
|
|
- $sHTMLValue .= "<input type=\"hidden\" id=\"id_ac_{$this->m_iInputId}\" onChange=\"EnableAddButton('{$this->m_iInputId}');\"/>\n";
|
|
|
- $sHTMLValue .= "<input type=\"hidden\" id=\"{$this->m_iInputId}\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\"/>\n";
|
|
|
- $oPage->add_ready_script("\$('#{$this->m_iInputId}').val('$sJSON');\noLinkWidget{$this->m_iInputId}.Init();\n\$('#ac_{$this->m_iInputId}').autocomplete('./ajax.render.php', { scroll:true, minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#id_ac_{$this->m_iInputId}', extraParams:{operation:'ui.linkswidget', sclass:'{$this->m_sClass}', attCode:'{$this->m_sAttCode}', max:30}});");
|
|
|
- $oPage->add_ready_script("\$('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled');");
|
|
|
- $oPage->add_ready_script("\$('#ac_{$this->m_iInputId}').result( function(event, data, formatted) { if (data) { $('#id_ac_{$this->m_iInputId}').val(data[1]); $('#ac_add_{$this->m_iInputId}').attr('disabled', ''); } else { $('#ac_add_{$this->m_iInputId}').attr('disabled', 'disabled'); } } );");
|
|
|
+ $aRow['static::'.$sFieldCode] = $oLinkedObj->GetAsHTML($sFieldCode);
|
|
|
+ }
|
|
|
+ return $aRow;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Display one row of the whole form
|
|
|
+ * @return none
|
|
|
+ */
|
|
|
+ protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId)
|
|
|
+ {
|
|
|
+ $sHtml = '';
|
|
|
+ $sHtml .= "<tr id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_row_$iRowId\">\n";
|
|
|
+ foreach($aConfig as $sName=>$void)
|
|
|
+ {
|
|
|
+ $sHtml .= "<td>".$aRow[$sName]."</td>\n";
|
|
|
+ }
|
|
|
+ $sHtml .= "</tr>\n";
|
|
|
+
|
|
|
+ return $sHtml;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Display the table with the form for editing all the links at once
|
|
|
+ * @param WebPage $oP The web page used for the output
|
|
|
+ * @param Hash $aConfig The table's header configuration
|
|
|
+ * @param Hash $aData The tabular data to be displayed
|
|
|
+ * @return string Html fragment representing the form table
|
|
|
+ */
|
|
|
+ protected function DisplayFormTable(WebPage $oP, $aConfig, $aData)
|
|
|
+ {
|
|
|
+ $sHtml = '';
|
|
|
+ $sHtml .= "<table class=\"listResults\">\n";
|
|
|
+ // Header
|
|
|
+ $sHtml .= "<thead>\n";
|
|
|
+ $sHtml .= "<tr>\n";
|
|
|
+ foreach($aConfig as $sName=>$aDef)
|
|
|
+ {
|
|
|
+ $sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
|
|
+ }
|
|
|
+ $sHtml .= "</tr>\n";
|
|
|
+ $sHtml .= "</thead>\n";
|
|
|
+
|
|
|
+ // Content
|
|
|
+ $sHtml .= "</tbody>\n";
|
|
|
+ if (count($aData) == 0)
|
|
|
+ {
|
|
|
+ $sHtml .= "<tr id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">".Dict::S('UI:Message:EmptyList:UseAdd')."<input type=\"hidden\" name=\"attr_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"\"></td></td>";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // Few choices, use a normal 'select'
|
|
|
- $sHTMLValue = "<select name=\"attr_{$this->m_sAttCode}\" id=\"{$this->m_iInputId}\">\n";
|
|
|
- $sHTMLValue .= "<option value=\"0\">".Dict::S('UI:Combo:SelectValue')."</option>\n";
|
|
|
- if (count($aAllowedValues) > 0)
|
|
|
+ foreach($aData as $iRowId => $aRow)
|
|
|
{
|
|
|
- foreach($aAllowedValues as $key => $value)
|
|
|
- {
|
|
|
- $sHTMLValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
|
|
|
- }
|
|
|
- }
|
|
|
- $sHTMLValue .= "</select>\n";
|
|
|
+ $sHtml .= $this->DisplayFormRow($oP, $aConfig, $aRow, $iRowId);
|
|
|
+ }
|
|
|
}
|
|
|
- $sHTMLValue .= "<div id=\"{$this->m_iInputId}_values\">\n";
|
|
|
- if ($oCurrentValuesSet != null)
|
|
|
+ $sHtml .= "</tbody>\n";
|
|
|
+
|
|
|
+ // Footer
|
|
|
+ $sHtml .= "</table>\n";
|
|
|
+
|
|
|
+ return $sHtml;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get the HTML fragment corresponding to the linkset editing widget
|
|
|
+ * @param WebPage $oP The web page used for all the output
|
|
|
+ * @param DBObjectSet The initial value of the linked set
|
|
|
+ * @param Hash $aArgs Extra context arguments
|
|
|
+ * @return string The HTML fragment to be inserted into the page
|
|
|
+ */
|
|
|
+ public function Display(WebPage $oPage, DBObjectSet $oValue, $aArgs = array())
|
|
|
+ {
|
|
|
+ $iWidgetIndex = self::$iWidgetIndex;
|
|
|
+ $sHtmlValue = '';
|
|
|
+ $sTargetClass = self::GetTargetClass($this->m_sClass, $this->m_sAttCode);
|
|
|
+ $sHtmlValue .= "<div id=\"linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
|
|
+ $oValue->Rewind();
|
|
|
+ $aForm = array();
|
|
|
+ $oContext = new UserContext();
|
|
|
+ while($oCurrentLink = $oValue->Fetch())
|
|
|
{
|
|
|
- // transform the DBObjectSet into a CMDBObjectSet !!!
|
|
|
- $aLinkedObjects = $oCurrentValuesSet->ToArray(false);
|
|
|
- // Actual values will be displayed asynchronously, no need to display them here
|
|
|
- //if (count($aLinkedObjects) > 0)
|
|
|
- //{
|
|
|
- // $oSet = CMDBObjectSet::FromArray($sLinkedClass, $aLinkedObjects);
|
|
|
- // $oDisplayBlock = DisplayBlock::FromObjectSet($oSet, 'list');
|
|
|
- // $sHTMLValue .= $oDisplayBlock->GetDisplay($oPage, $this->m_iInputId.'_current', array('linkage' => $sExtKeyToMe, 'menu' => false));
|
|
|
- //}
|
|
|
+ $aRow = array();
|
|
|
+ $key = $oCurrentLink->GetKey();
|
|
|
+ $oLinkedObj = $oContext->GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote));
|
|
|
+
|
|
|
+ $aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs);
|
|
|
}
|
|
|
- $sHTMLValue .= "</div>\n";
|
|
|
- return $sHTMLValue;
|
|
|
+ $sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
|
|
+ $oPage->add_ready_script(<<<EOF
|
|
|
+ oWidget$iWidgetIndex = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}');
|
|
|
+ oWidget$iWidgetIndex.Init();
|
|
|
+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$iWidgetIndex.RemoveSelected();\" >";
|
|
|
+ $sHtmlValue .= " <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget$iWidgetIndex.AddObjects();\"></span>\n";
|
|
|
+ $sHtmlValue .= "<span style=\"clear:both;\"><p> </p></span>\n";
|
|
|
+ $sHtmlValue .= "</div>\n";
|
|
|
+ $oPage->add_at_the_end($this->GetObjectPickerDialog($oPage)); // To prevent adding forms inside the main form
|
|
|
+ return $sHtmlValue;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* This static function is called by the Ajax Page when there is a need to fill an autocomplete combo
|
|
|
- * @param $oPage WebPage The ajax page used for the put^put (sent back to the browser
|
|
|
+ * @param $oPage WebPage The ajax page used for the output (sent back to the browser)
|
|
|
* @param $oContext UserContext The context of the user (for limiting the search)
|
|
|
* @param $sClass string The name of the class of the current object being edited
|
|
|
* @param $sAttCode string The name of the attribute being edited
|
|
@@ -257,111 +339,106 @@ class UILinksWidget
|
|
|
return $sTargetClass;
|
|
|
}
|
|
|
|
|
|
- protected function GetObjectPickerDialog($oPage, $sTargetClass, $sOkFunction)
|
|
|
+ protected function GetObjectPickerDialog($oPage)
|
|
|
{
|
|
|
- $sDialogTitle = Dict::S('UI:ManageObjectsDlg');
|
|
|
- $sOkBtnLabel = Dict::S('UI:Button:Ok');
|
|
|
- $sCancelBtnLabel = Dict::S('UI:Button:Cancel');
|
|
|
- $sAddBtnLabel = Dict::S('UI:Button:AddToList');
|
|
|
- $sRemoveBtnLabel = Dict::S('UI:Button:RemoveFromList');
|
|
|
- $sFilterBtnLabel = Dict::S('UI:Button:FilterList');
|
|
|
- $sLabelSelectedObjects = Dict::S('UI:Label:SelectedObjects');
|
|
|
- $sLabelAvailableObjects = Dict::S('UI:Label:AvailableObjects');
|
|
|
- $sHTML = <<< EOF
|
|
|
- <div style="display:none" title="$sDialogTitle" id="ManageObjectsDlg_{$this->m_iInputId}">
|
|
|
- <div class="wizContainer">
|
|
|
- <table width="100%">
|
|
|
- <tr>
|
|
|
- <td>
|
|
|
- <p>$sLabelSelectedObjects</p>
|
|
|
- <button type="button" class="action" onClick="FilterLeft('$sTargetClass');"><span>$sFilterBtnLabel</span></button>
|
|
|
- <p><select id="selected_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
|
|
- </select></p>
|
|
|
- </td>
|
|
|
- <td style="text-align:center; valign:middle;">
|
|
|
- <p><button type="button" id="btn_add_objects_{$this->m_iInputId}" onClick="Manage_AddObjects('$this->m_iInputId');">$sAddBtnLabel</button></p>
|
|
|
- <p><button type="button" id="btn_remove_objects_{$this->m_iInputId}" onClick="Manage_RemoveObjects('$this->m_iInputId');">$sRemoveBtnLabel</button></p>
|
|
|
- </td>
|
|
|
- <td>
|
|
|
- <p>$sLabelAvailableObjects</p>
|
|
|
- <button type="button" class="action" onClick="FilterRight('$sTargetClass');"><span>$sFilterBtnLabel</span></button>
|
|
|
- <p><select id="available_objects_{$this->m_iInputId}" size="10" multiple onChange="Manage_UpdateButtons('$this->m_iInputId')" style="width:300px;">
|
|
|
- </select></p>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- <tr>
|
|
|
- <td colspan="3">
|
|
|
- <input type="submit" onClick="$('#ManageObjectsDlg_{$this->m_iInputId}').dialog('close'); $sOkFunction('$sTargetClass', 'selected_objects'); return false;" value="$sOkBtnLabel" /> <button type="button" onClick="$('#ManageObjectsDlg_{$this->m_iInputId}').dialog('close');">$sCancelBtnLabel</button>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </table>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-EOF;
|
|
|
- $oPage->add_ready_script("$('#ManageObjectsDlg_$this->m_iInputId').dialog( {autoOpen: false, modal: true, width: 750, height: 350} );"); // JQuery UI dialog
|
|
|
- //$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
|
|
- return $sHTML;
|
|
|
+ $sHtml = "<div id=\"dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}\">";
|
|
|
+ //$oTargetObj = $oContext->GetObject($sTargetClass, $this->m_iObjectId);
|
|
|
+ $sHtml .= "<div class=\"wizContainer\">\n";
|
|
|
+ //$sHtml .= "<div class=\"page_header\">\n");
|
|
|
+ //$sHtml .= "<h1>".Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName(get_class($oTargetObj)), "<span class=\"hilite\">".$oTargetObj->GetHyperlink()."</span>")."</h1>\n");
|
|
|
+ //$sHtml .= "</div>\n");
|
|
|
+
|
|
|
+ $oContext = new UserContext();
|
|
|
+ $iWidgetIndex = self::$iWidgetIndex;
|
|
|
+ $oFilter = $oContext->NewFilter($this->m_sRemoteClass);
|
|
|
+ $oSet = new CMDBObjectSet($oFilter);
|
|
|
+ $oBlock = new DisplayBlock($oFilter, 'search', false);
|
|
|
+ $sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}", array('open' => true));
|
|
|
+ $sHtml .= "<form id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\" OnSubmit=\"return oWidget$iWidgetIndex.DoAddObjects(this.id);\">\n";
|
|
|
+ $sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
|
|
+ $sHtml .= "<div style=\"height: 100px; background: #fff;border-color:#F6F6F1 #E6E6E1 #E6E6E1 #F6F6F1; border-style:solid; border-width:3px; text-align: center; vertical-align: center;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
|
|
+ $sHtml .= "</div>\n";
|
|
|
+ $sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\"> <input type=\"submit\" value=\"".Dict::S('UI:Button:Add')."\">";
|
|
|
+ $sHtml .= "</div>\n";
|
|
|
+ $sHtml .= "</form>\n";
|
|
|
+ $sHtml .= "</div>\n";
|
|
|
+ $oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ autoOpen: false, modal: true });");
|
|
|
+ $oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('option', {title:'".Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass), "<span class=\"hilite\"> ZZZZ </span>")."'});");
|
|
|
+ $oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} form').bind('submit.uilinksWizard', oWidget$iWidgetIndex.SearchObjectsToAdd);");
|
|
|
+ return $sHtml;
|
|
|
}
|
|
|
-
|
|
|
- protected function GetLinkObjectDialog($oPage, $sId)
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Search for objects to be linked to the current object (i.e "remote" objects)
|
|
|
+ * @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
|
|
+ * @param UserContext $oContext User context to limit the search...
|
|
|
+ * @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of m_sRemoteClass
|
|
|
+ * @param Array $aAlreadyLinkedIds List of IDs of objects of "remote" class already linked, to be filtered out of the search
|
|
|
+ */
|
|
|
+ public function SearchObjectsToAdd(WebPage $oP, UserContext $oContext, $sRemoteClass = '', $aAlreadyLinkedIds = array())
|
|
|
{
|
|
|
- $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
|
|
- $sLinkedClass = $oAttDef->GetLinkedClass();
|
|
|
- $sStateAttCode = MetaModel::GetStateAttributeCode($sLinkedClass);
|
|
|
- $sDefaultState = MetaModel::GetDefaultState($sLinkedClass);
|
|
|
- $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sAttCode);
|
|
|
- $sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
|
|
- $sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
|
|
-
|
|
|
- $sHTML = "<div style=\"display:none\" title=\"".Dict::Format('UI:Link_Class_Attributes', MetaModel::GetName($sLinkedClass))."\" id=\"LinkDlg_$sId\">\n";
|
|
|
- $sHTML .= "<div class=\"wizContainer\">\n";
|
|
|
- $sHTML .= "<form action=\"./UI.php\" onSubmit=\"return oLinkWidget$sId.OnLinkOk();\">\n";
|
|
|
- $index = 0;
|
|
|
- $aAttrsMap = array();
|
|
|
- $aDetails = array();
|
|
|
- foreach(MetaModel::ListAttributeDefs($sLinkedClass) as $sAttCode=>$oAttDef)
|
|
|
+ if ($sRemoteClass != '')
|
|
|
{
|
|
|
- if ($sStateAttCode == $sAttCode)
|
|
|
- {
|
|
|
- // State attribute is always hidden from the UI
|
|
|
- //$sHTMLValue = $this->GetStateLabel();
|
|
|
- //$aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
|
|
- }
|
|
|
- else if (!$oAttDef->IsExternalField() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $sExtKeyToRemote))
|
|
|
+ // assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
|
|
|
+ $oFilter = $oContext->NewFilter($sRemoteClass);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // No remote class specified use the one defined in the linkedset
|
|
|
+ $oFilter = $oContext->NewFilter($this->m_sRemoteClass);
|
|
|
+ }
|
|
|
+ if (count($aAlreadyLinkedIds) > 0)
|
|
|
+ {
|
|
|
+ // Positive IDs correspond to existing link records
|
|
|
+ // negative IDs correspond to "remote" objects to be linked
|
|
|
+ $aLinkIds = array();
|
|
|
+ $aRemoteObjIds = array();
|
|
|
+ foreach($aAlreadyLinkedIds as $iId)
|
|
|
{
|
|
|
- $iFlags = MetaModel::GetAttributeFlags($sLinkedClass, $sDefaultState, $sAttCode);
|
|
|
- if ($iFlags & OPT_ATT_HIDDEN)
|
|
|
+ if ($iId > 0)
|
|
|
{
|
|
|
- // Attribute is hidden, do nothing
|
|
|
+ $aLinkIds[] = $iId;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if ($iFlags & OPT_ATT_READONLY)
|
|
|
- {
|
|
|
- // Attribute is read-only
|
|
|
- $sHTMLValue = $this->GetAsHTML($sAttCode);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $sValue = ""; //$this->Get($sAttCode);
|
|
|
- $sDisplayValue = ""; //$this->GetEditValue($sAttCode);
|
|
|
- $sSubId = $sId.'_'.$index;
|
|
|
- $aAttrsMap[$sAttCode] = $sSubId;
|
|
|
- $index++;
|
|
|
- $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sLinkedClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sSubId, $this->m_sAttCode);
|
|
|
- }
|
|
|
- $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue);
|
|
|
+ $aRemoteObjIds[] = -$iId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (count($aLinkIds) >0)
|
|
|
+ {
|
|
|
+ // Search for the links to find to which "remote" object they are linked
|
|
|
+ $oLinkFilter = $oContext->NewFilter($this->m_sLinkedClass);
|
|
|
+ $oLinkFilter->AddCondition('id', $aLinkIds, 'IN');
|
|
|
+ $oLinkSet = new CMDBObjectSet($oLinkFilter);
|
|
|
+ while($oLink = $oLinkSet->Fetch())
|
|
|
+ {
|
|
|
+ $aRemoteObjIds[] = $oLink->Get($this->m_sExtKeyToRemote);
|
|
|
}
|
|
|
}
|
|
|
+ $oFilter->AddCondition('id', $aRemoteObjIds, 'NOTIN');
|
|
|
+ }
|
|
|
+ $oSet = new CMDBObjectSet($oFilter);
|
|
|
+ $oBlock = new DisplayBlock($oFilter, 'list', false);
|
|
|
+ $oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results
|
|
|
+ }
|
|
|
+
|
|
|
+ public function DoAddObjects(WebPage $oP, UserContext $oContext, $aLinkedObjectIds = array())
|
|
|
+ {
|
|
|
+ $aTable = array();
|
|
|
+ foreach($aLinkedObjectIds as $iObjectId)
|
|
|
+ {
|
|
|
+ $oLinkedObj = $oContext->GetObject($this->m_sRemoteClass, $iObjectId);
|
|
|
+ if (is_object($oLinkedObj))
|
|
|
+ {
|
|
|
+ $aRow = $this->GetFormRow($oP, $oLinkedObj, -$iObjectId ); // Not yet created link get negative Ids
|
|
|
+ $oP->add($this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iObjectId));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ $oP->p(Dict::Format('UI:Error:Object_Class_Id_NotFound', $this->m_sLinkedClass, $iObjectId));
|
|
|
+ }
|
|
|
}
|
|
|
- $sHTML .= $oPage->GetDetails($aDetails);
|
|
|
- $sHTML .= "<input type=\"submit\" onClick=\"oLinkWidget$sId.OnLinkOk(); return false;\" value=\"".Dict::S('UI:Button:Ok')."\" /> <button type=\"button\" onClick=\"oLinkWidget$sId.OnLinkCancel()\">".Dict::S('UI:Button:Cancel')."</button>\n";
|
|
|
- $sHTML .= "</form>\n";
|
|
|
- $sHTML .= "</div>\n";
|
|
|
- $sHTML .= "</div>\n";
|
|
|
- $oPage->add_ready_script("$('#LinkDlg_$sId').dialog( {autoOpen: false, modal: true, width: 300 } );"); // jQuery UI dialog
|
|
|
- //$oPage->add_ready_script("UpdateObjectList('$sClass');");
|
|
|
- return $sHTML;
|
|
|
}
|
|
|
}
|
|
|
?>
|