mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
Implemented a new (optional) UI for managing 1:n linksets.
SVN:trunk[2290]
This commit is contained in:
@@ -113,7 +113,7 @@ class ajax_page extends WebPage
|
|||||||
}
|
}
|
||||||
if (count($this->m_aTabs) > 0)
|
if (count($this->m_aTabs) > 0)
|
||||||
{
|
{
|
||||||
$this->add_ready_script(
|
$this->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
// The "tab widgets" to handle.
|
// The "tab widgets" to handle.
|
||||||
var tabs = $('div[id^=tabbedContent]');
|
var tabs = $('div[id^=tabbedContent]');
|
||||||
@@ -183,7 +183,33 @@ EOF
|
|||||||
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
||||||
$container_index++;
|
$container_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional UI widgets to be activated inside the ajax fragment ??
|
||||||
|
if ($this->sContentType == 'text/html')
|
||||||
|
{
|
||||||
|
$this->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
$(".date-pick").datepicker({
|
||||||
|
showOn: 'button',
|
||||||
|
buttonImage: '../images/calendar.png',
|
||||||
|
buttonImageOnly: true,
|
||||||
|
dateFormat: 'yy-mm-dd',
|
||||||
|
constrainInput: false,
|
||||||
|
changeMonth: true,
|
||||||
|
changeYear: true
|
||||||
|
});
|
||||||
|
$(".datetime-pick").datepicker({
|
||||||
|
showOn: 'button',
|
||||||
|
buttonImage: '../images/calendar.png',
|
||||||
|
buttonImageOnly: true,
|
||||||
|
dateFormat: 'yy-mm-dd 00:00:00',
|
||||||
|
constrainInput: false,
|
||||||
|
changeMonth: true,
|
||||||
|
changeYear: true
|
||||||
|
});
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
$s_captured_output = ob_get_contents();
|
$s_captured_output = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
if (($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'))
|
if (($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'))
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ require_once(APPROOT.'/application/applicationextension.inc.php');
|
|||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
require_once(APPROOT.'/application/applicationcontext.class.inc.php');
|
require_once(APPROOT.'/application/applicationcontext.class.inc.php');
|
||||||
require_once(APPROOT.'/application/ui.linkswidget.class.inc.php');
|
require_once(APPROOT.'/application/ui.linkswidget.class.inc.php');
|
||||||
|
require_once(APPROOT.'/application/ui.linksdirectwidget.class.inc.php');
|
||||||
require_once(APPROOT.'/application/ui.passwordwidget.class.inc.php');
|
require_once(APPROOT.'/application/ui.passwordwidget.class.inc.php');
|
||||||
require_once(APPROOT.'/application/ui.extkeywidget.class.inc.php');
|
require_once(APPROOT.'/application/ui.extkeywidget.class.inc.php');
|
||||||
require_once(APPROOT.'/application/ui.htmleditorwidget.class.inc.php');
|
require_once(APPROOT.'/application/ui.htmleditorwidget.class.inc.php');
|
||||||
@@ -266,58 +267,25 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
|||||||
if ($bEditMode && (!$bReadOnly))
|
if ($bEditMode && (!$bReadOnly))
|
||||||
{
|
{
|
||||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||||
if (get_class($oAttDef) == 'AttributeLinkedSet')
|
|
||||||
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
|
if ($oAttDef->IsIndirect())
|
||||||
{
|
{
|
||||||
// 1:n links
|
|
||||||
$sTargetClass = $oAttDef->GetLinkedClass();
|
|
||||||
if ($this->IsNew())
|
|
||||||
{
|
|
||||||
$oPage->p(Dict::Format('UI:BeforeAdding_Class_ObjectsSaveThisObject', MetaModel::GetName($sTargetClass)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription());
|
|
||||||
|
|
||||||
$oFilter = new DBObjectSearch($sTargetClass);
|
|
||||||
$oFilter->AddCondition($oAttDef->GetExtKeyToMe(), $this->GetKey(),'=');
|
|
||||||
|
|
||||||
$aDefaults = array($oAttDef->GetExtKeyToMe() => $this->GetKey());
|
|
||||||
$oAppContext = new ApplicationContext();
|
|
||||||
foreach($oAppContext->GetNames() as $sKey)
|
|
||||||
{
|
|
||||||
// The linked object inherits the parent's value for the context
|
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sKey))
|
|
||||||
{
|
|
||||||
$aDefaults[$sKey] = $this->Get($sKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$aParams = array(
|
|
||||||
'target_attr' => $oAttDef->GetExtKeyToMe(),
|
|
||||||
'object_id' => $this->GetKey(),
|
|
||||||
'menu' => true,
|
|
||||||
'default' => $aDefaults,
|
|
||||||
'table_id' => $sClass.'_'.$sAttCode,
|
|
||||||
);
|
|
||||||
|
|
||||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
|
||||||
$oBlock->Display($oPage, $sInputId, $aParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // get_class($oAttDef) == 'AttributeLinkedSetIndirect'
|
|
||||||
{
|
|
||||||
// n:n links
|
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
|
||||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||||
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription().'<span id="busy_'.$sInputId.'"></span>');
|
|
||||||
|
|
||||||
$sValue = $this->Get($sAttCode);
|
|
||||||
$sDisplayValue = ''; // not used
|
|
||||||
$aArgs = array('this' => $this);
|
|
||||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
|
||||||
$aFieldsMap[$sAttCode] = $sInputId;
|
|
||||||
$oPage->add($sHTMLValue);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sTargetClass = $sLinkedClass;
|
||||||
|
}
|
||||||
|
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription().'<span id="busy_'.$sInputId.'"></span>');
|
||||||
|
|
||||||
|
$oValue = $this->Get($sAttCode);
|
||||||
|
$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;
|
||||||
|
$oPage->add($sHTMLValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -414,6 +382,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
|||||||
$iInputId = 0;
|
$iInputId = 0;
|
||||||
$aFieldsMap = array();
|
$aFieldsMap = array();
|
||||||
$aFieldsComments = (isset($aExtraParams['fieldsComments'])) ? $aExtraParams['fieldsComments'] : array();
|
$aFieldsComments = (isset($aExtraParams['fieldsComments'])) ? $aExtraParams['fieldsComments'] : array();
|
||||||
|
$aExtraFlags = (isset($aExtraParams['fieldsFlags'])) ? $aExtraParams['fieldsFlags'] : array();
|
||||||
$bFieldComments = (count($aFieldsComments) > 0);
|
$bFieldComments = (count($aFieldsComments) > 0);
|
||||||
|
|
||||||
foreach($aDetailsStruct as $sTab => $aCols )
|
foreach($aDetailsStruct as $sTab => $aCols )
|
||||||
@@ -474,6 +443,11 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
|||||||
{
|
{
|
||||||
$iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object
|
$iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object
|
||||||
}
|
}
|
||||||
|
if (array_key_exists($sAttCode, $aExtraFlags))
|
||||||
|
{
|
||||||
|
// the caller may override some flags if needed
|
||||||
|
$iFlags = $iFlags | $aExtraFlags[$sAttCode];
|
||||||
|
}
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0))
|
if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0))
|
||||||
{
|
{
|
||||||
@@ -1608,12 +1582,19 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
|
if ($oAttDef->IsIndirect())
|
||||||
|
{
|
||||||
|
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix, $oAttDef->DuplicatesAllowed(), $aArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix, $aArgs);
|
||||||
|
}
|
||||||
$aEventsList[] ='validate';
|
$aEventsList[] ='validate';
|
||||||
$aEventsList[] ='change';
|
$aEventsList[] ='change';
|
||||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix, $oAttDef->DuplicatesAllowed(), $aArgs);
|
|
||||||
$oObj = isset($aArgs['this']) ? $aArgs['this'] : null;
|
$oObj = isset($aArgs['this']) ? $aArgs['this'] : null;
|
||||||
$sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj);
|
$sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Document':
|
case 'Document':
|
||||||
$aEventsList[] ='validate';
|
$aEventsList[] ='validate';
|
||||||
@@ -2434,6 +2415,50 @@ EOF
|
|||||||
$this->Set($sAttCode, $iValue);
|
$this->Set($sAttCode, $iValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() && ($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE))
|
||||||
|
{
|
||||||
|
$oLinkset = $this->Get($sAttCode);
|
||||||
|
$sLinkedClass = $oLinkset->GetClass();
|
||||||
|
$aObjSet = array();
|
||||||
|
$oLinkset->Rewind();
|
||||||
|
$bModified = false;
|
||||||
|
while($oLink = $oLinkset->Fetch())
|
||||||
|
{
|
||||||
|
if (in_array($oLink->GetKey(), $value['to_be_deleted']))
|
||||||
|
{
|
||||||
|
// The link is to be deleted, don't copy it in the array
|
||||||
|
$bModified = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aObjSet[] = $oLink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('to_be_created', $value) && (count($value['to_be_created']) > 0))
|
||||||
|
{
|
||||||
|
// Now handle the lniks to be created
|
||||||
|
foreach($value['to_be_created'] as $aData)
|
||||||
|
{
|
||||||
|
$sSubClass = $aData['class'];
|
||||||
|
if ( ($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass)) )
|
||||||
|
{
|
||||||
|
$aObjData = $aData['data'];
|
||||||
|
|
||||||
|
$oLink = new $sSubClass;
|
||||||
|
$oLink->UpdateObjectFromArray($aObjData);
|
||||||
|
$aObjSet[] = $oLink;
|
||||||
|
$bModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bModified)
|
||||||
|
{
|
||||||
|
$oNewSet = DBObjectSet::FromArray($oLinkset->GetClass(), $aObjSet);
|
||||||
|
$this->Set($sAttCode, $oNewSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!is_null($value))
|
if (!is_null($value))
|
||||||
@@ -2466,6 +2491,28 @@ EOF
|
|||||||
{
|
{
|
||||||
$value = array('fcontents' => utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents'));
|
$value = array('fcontents' => utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents'));
|
||||||
}
|
}
|
||||||
|
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() && ($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE))
|
||||||
|
{
|
||||||
|
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}', 'raw_data'), true);
|
||||||
|
$aToBeCreated = array();
|
||||||
|
foreach($aRawToBeCreated as $aData)
|
||||||
|
{
|
||||||
|
$sSubFormPrefix = $aData['formPrefix'];
|
||||||
|
$sObjClass = $aData['class'];
|
||||||
|
$aObjData = array();
|
||||||
|
foreach($aData as $sKey => $value)
|
||||||
|
{
|
||||||
|
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
||||||
|
{
|
||||||
|
$aObjData[$aMatches[1]] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$aToBeCreated[] = array('class' => $sObjClass, 'data' => $aObjData);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = array('to_be_created' => $aToBeCreated,
|
||||||
|
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true) );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$value = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
$value = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
||||||
|
|||||||
@@ -568,11 +568,13 @@ class DisplayBlock
|
|||||||
{
|
{
|
||||||
if ((UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
if ((UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||||
{
|
{
|
||||||
|
$sLinkTarget = '';
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sParams = $oAppContext->GetForLink();
|
$sParams = $oAppContext->GetForLink();
|
||||||
// 1:n links, populate the target object as a default value when creating a new linked object
|
// 1:n links, populate the target object as a default value when creating a new linked object
|
||||||
if (isset($aExtraParams['target_attr']))
|
if (isset($aExtraParams['target_attr']))
|
||||||
{
|
{
|
||||||
|
$sLinkTarget = ' target="_blank" ';
|
||||||
$aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
|
$aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
|
||||||
}
|
}
|
||||||
$sDefault = '';
|
$sDefault = '';
|
||||||
@@ -584,7 +586,7 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sHtml .= $oPage->GetP("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=new&class=$sClass&$sParams{$sDefault}\">".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sClass))."</a>\n");
|
$sHtml .= $oPage->GetP("<a{$sLinkTarget} href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=new&class=$sClass&$sParams{$sDefault}\">".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sClass))."</a>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ EOF
|
|||||||
changeMonth: true,
|
changeMonth: true,
|
||||||
changeYear: true
|
changeYear: true
|
||||||
});
|
});
|
||||||
$(".datetime-pick").datepicker({
|
$(".datetime-pick").datepicker({
|
||||||
showOn: 'button',
|
showOn: 'button',
|
||||||
buttonImage: '../images/calendar.png',
|
buttonImage: '../images/calendar.png',
|
||||||
buttonImageOnly: true,
|
buttonImageOnly: true,
|
||||||
@@ -290,23 +290,6 @@ EOF
|
|||||||
changeMonth: true,
|
changeMonth: true,
|
||||||
changeYear: true
|
changeYear: true
|
||||||
});
|
});
|
||||||
// Restore the persisted sortable order, for all sortable lists... if any
|
|
||||||
$('.sortable').each(function()
|
|
||||||
{
|
|
||||||
var sTemp = GetUserPreference(this.id+'_order', undefined);
|
|
||||||
if (sTemp != undefined)
|
|
||||||
{
|
|
||||||
var aSerialized = sTemp.split(',');
|
|
||||||
var sortable = $(this);
|
|
||||||
$.each(aSerialized, function(i,v) {
|
|
||||||
var item = $('#menu_'+v);
|
|
||||||
if (item.length > 0) // Check that the menu exists
|
|
||||||
{
|
|
||||||
sortable.append(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make sortable, everything that claims to be sortable
|
// Make sortable, everything that claims to be sortable
|
||||||
$('.sortable').sortable( {axis: 'y', cursor: 'move', handle: '.drag_handle', stop: function()
|
$('.sortable').sortable( {axis: 'y', cursor: 'move', handle: '.drag_handle', stop: function()
|
||||||
|
|||||||
238
application/ui.linksdirectwidget.class.inc.php
Normal file
238
application/ui.linksdirectwidget.class.inc.php
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
<?php
|
||||||
|
// Copyright (C) 2012 Combodo SARL
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; version 3 of the License.
|
||||||
|
//
|
||||||
|
// This program 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 General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
class UILinksWidgetDirect
|
||||||
|
{
|
||||||
|
protected $sClass;
|
||||||
|
protected $sAttCode;
|
||||||
|
protected $sInputid;
|
||||||
|
protected $sNameSuffix;
|
||||||
|
protected $sLinkedClass;
|
||||||
|
|
||||||
|
public function __construct($sClass, $sAttCode, $sInputId, $sNameSuffix = '')
|
||||||
|
{
|
||||||
|
$this->sClass = $sClass;
|
||||||
|
$this->sAttCode = $sAttCode;
|
||||||
|
$this->sInputid = $sInputId;
|
||||||
|
$this->sNameSuffix = $sNameSuffix;
|
||||||
|
$this->aZlist = array();
|
||||||
|
$this->sLinkedClass = '';
|
||||||
|
|
||||||
|
// Compute the list of attributes visible from the given objet:
|
||||||
|
// All the attributes from the "list" Zlist of the Link class except
|
||||||
|
// the ExternalKey that points to the current object and its related external fields
|
||||||
|
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
|
$this->sLinkedClass = $oLinksetDef->GetLinkedClass();
|
||||||
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
|
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
||||||
|
foreach($aZList as $sLinkedAttCode)
|
||||||
|
{
|
||||||
|
if ($sLinkedAttCode != $sExtKeyToMe)
|
||||||
|
{
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
|
|
||||||
|
if (!$oAttDef->IsExternalField() || ($oAttDef->GetKeyAttCode() != $sExtKeyToMe) )
|
||||||
|
{
|
||||||
|
$this->aZlist[] = $sLinkedAttCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Display(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||||
|
{
|
||||||
|
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
|
switch($oLinksetDef->GetEditMode())
|
||||||
|
{
|
||||||
|
case LINKSET_EDITMODE_NONE: // The linkset is read-only
|
||||||
|
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LINKSET_EDITMODE_ADDONLY: // The only possible action is to open (in a new window) the form to create a new object
|
||||||
|
if ($oCurrentObj && !$oCurrentObj->IsNew())
|
||||||
|
{
|
||||||
|
$sTargetClass = $oLinksetDef->GetLinkedClass();
|
||||||
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
|
$sDefault = "default[$sExtKeyToMe]=".$oCurrentObj->GetKey();
|
||||||
|
$oAppContext = new ApplicationContext();
|
||||||
|
$sParams = $oAppContext->GetForLink();
|
||||||
|
$oPage->p("<a target=\"_blank\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=new&class=$sTargetClass&$sParams{$sDefault}\">".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sTargetClass))."</a>\n");
|
||||||
|
}
|
||||||
|
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
|
||||||
|
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LINKSET_EDITMODE_ACTIONS:
|
||||||
|
default:
|
||||||
|
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, true /* bDisplayMenu*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function DisplayAsBlock(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $bDisplayMenu)
|
||||||
|
{
|
||||||
|
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
|
$sTargetClass = $oLinksetDef->GetLinkedClass();
|
||||||
|
if ($oCurrentObj && $oCurrentObj->IsNew() && $bDisplayMenu)
|
||||||
|
{
|
||||||
|
$oPage->p(Dict::Format('UI:BeforeAdding_Class_ObjectsSaveThisObject', MetaModel::GetName($sTargetClass)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$oFilter = new DBObjectSearch($sTargetClass);
|
||||||
|
$oFilter->AddCondition($oLinksetDef->GetExtKeyToMe(), $oCurrentObj->GetKey(),'=');
|
||||||
|
|
||||||
|
$aDefaults = array($oLinksetDef->GetExtKeyToMe() => $oCurrentObj->GetKey());
|
||||||
|
$oAppContext = new ApplicationContext();
|
||||||
|
foreach($oAppContext->GetNames() as $sKey)
|
||||||
|
{
|
||||||
|
// The linked object inherits the parent's value for the context
|
||||||
|
if (MetaModel::IsValidAttCode($this->sClass, $sKey) && $oCurrentObj)
|
||||||
|
{
|
||||||
|
$aDefaults[$sKey] = $oCurrentObj->Get($sKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$aParams = array(
|
||||||
|
'target_attr' => $oLinksetDef->GetExtKeyToMe(),
|
||||||
|
'object_id' => $oCurrentObj ? $oCurrentObj->GetKey() : null,
|
||||||
|
'menu' => $bDisplayMenu,
|
||||||
|
'default' => $aDefaults,
|
||||||
|
'table_id' => $this->sClass.'_'.$this->sAttCode,
|
||||||
|
);
|
||||||
|
|
||||||
|
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||||
|
$oBlock->Display($oPage, $this->sInputid, $aParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function DisplayEditInPlace(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||||
|
{
|
||||||
|
$aAttribs = $this->GetTableConfig();
|
||||||
|
|
||||||
|
$oValue->Rewind();
|
||||||
|
$oPage->add('<table class="listContainer" id="'.$this->sInputid.'"><tr><td>');
|
||||||
|
|
||||||
|
$aData = array();
|
||||||
|
while($oLinkObj = $oValue->Fetch())
|
||||||
|
{
|
||||||
|
$aRow = array();
|
||||||
|
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.$oLinkObj->GetKey().'"/>';
|
||||||
|
foreach($this->aZlist as $sLinkedAttCode)
|
||||||
|
{
|
||||||
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
|
}
|
||||||
|
$aData[] = $aRow;
|
||||||
|
}
|
||||||
|
$oPage->table($aAttribs, $aData);
|
||||||
|
$oPage->add('</td></tr></table>'); //listcontainer
|
||||||
|
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
|
||||||
|
$oPage->add_ready_script("$('#{$this->sInputid}').directlinks({class_name: '$this->sClass', att_code: '$this->sAttCode', input_name:'$sInputName' });");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetObjectCreationDlg(WebPage $oPage, $sProposedRealClass = '')
|
||||||
|
{
|
||||||
|
// For security reasons: check that the "proposed" class is actually a subclass of the linked class
|
||||||
|
// and that the current user is allowed to create objects of this class
|
||||||
|
$sRealClass = '';
|
||||||
|
$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
|
||||||
|
$aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||||
|
$aPossibleClasses = array();
|
||||||
|
foreach($aSubClasses as $sCandidateClass)
|
||||||
|
{
|
||||||
|
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||||
|
{
|
||||||
|
if ($sCandidateClass == $sProposedRealClass)
|
||||||
|
{
|
||||||
|
$sRealClass = $sProposedRealClass;
|
||||||
|
}
|
||||||
|
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Only one of the subclasses can be instantiated...
|
||||||
|
if (count($aPossibleClasses) == 1)
|
||||||
|
{
|
||||||
|
$aKeys = array_keys($aPossibleClasses);
|
||||||
|
$sRealClass = $aKeys[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sRealClass != '')
|
||||||
|
{
|
||||||
|
$oPage->add("<h1>".MetaModel::GetClassIcon($sRealClass)." ".Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($sRealClass))."</h1>\n");
|
||||||
|
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||||
|
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||||
|
$aFieldFlags = array( $sExtKeyToMe => OPT_ATT_HIDDEN);
|
||||||
|
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, null, array(), array('formPrefix' => $this->sInputid, 'noRelations' => true, 'fieldsFlags' => $aFieldFlags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sClassLabel = MetaModel::GetName($this->sLinkedClass);
|
||||||
|
$oPage->add('<p>'.Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
|
||||||
|
$oPage->add('<nobr><select name="class">');
|
||||||
|
asort($aPossibleClasses);
|
||||||
|
foreach($aPossibleClasses as $sClassName => $sClassLabel)
|
||||||
|
{
|
||||||
|
$oPage->add("<option value=\"$sClassName\">$sClassLabel</option>");
|
||||||
|
}
|
||||||
|
$oPage->add('</select>');
|
||||||
|
$oPage->add(' <button type="button" onclick="$(\'#'.$this->sInputid.'\').directlinks(\'subclassSelected\');">'.Dict::S('UI:Button:Apply').'</button><span class="indicator" style="display:inline-block;width:16px"></span></nobr></p>');
|
||||||
|
}
|
||||||
|
$oPage->add('</div></div>');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetObjectModificationDlg()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function GetTableConfig()
|
||||||
|
{
|
||||||
|
$aAttribs = array();
|
||||||
|
$aAttribs['form::select'] = array('label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>", 'description' => Dict::S('UI:SelectAllToggle+'));
|
||||||
|
|
||||||
|
foreach($this->aZlist as $sLinkedAttCode)
|
||||||
|
{
|
||||||
|
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
|
||||||
|
$aAttribs[$sLinkedAttCode] = array('label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint());
|
||||||
|
}
|
||||||
|
return $aAttribs;
|
||||||
|
}
|
||||||
|
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||||
|
{
|
||||||
|
$aAttribs = $this->GetTableConfig();
|
||||||
|
if ($sRealClass == '')
|
||||||
|
{
|
||||||
|
$sRealClass = $this->sLinkedClass;
|
||||||
|
}
|
||||||
|
$oLinkObj = new $sRealClass();
|
||||||
|
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
||||||
|
|
||||||
|
$aRow = array();
|
||||||
|
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.(-$iTempId).'"/>';
|
||||||
|
foreach($this->aZlist as $sLinkedAttCode)
|
||||||
|
{
|
||||||
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
|
}
|
||||||
|
return $oPage->GetTableRow($aRow, $aAttribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function UpdateFromArray($oObj, $aData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,6 +85,10 @@ define('LINKSET_TRACKING_LIST', 1); // Do track added/removed items
|
|||||||
define('LINKSET_TRACKING_DETAILS', 2); // Do track modified items
|
define('LINKSET_TRACKING_DETAILS', 2); // Do track modified items
|
||||||
define('LINKSET_TRACKING_ALL', 3); // Do track added/removed/modified items
|
define('LINKSET_TRACKING_ALL', 3); // Do track added/removed/modified items
|
||||||
|
|
||||||
|
define('LINKSET_EDITMODE_NONE', 0); // The linkset cannot be edited at all from inside this object
|
||||||
|
define('LINKSET_EDITMODE_ADDONLY', 1); // The only possible action is to open a new window to create a new object
|
||||||
|
define('LINKSET_EDITMODE_ACTIONS', 2); // Show the usual 'Actions' popup menu
|
||||||
|
define('LINKSET_EDITMODE_INPLACE', 3); // The "linked" objects can be created/modified/deleted in place
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -563,7 +567,7 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
return array_merge(parent::ListExpectedParams(), array("allowed_values", "depends_on", "linked_class", "ext_key_to_me", "count_min", "count_max"));
|
return array_merge(parent::ListExpectedParams(), array("allowed_values", "depends_on", "linked_class", "ext_key_to_me", "count_min", "count_max"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetEditClass() {return "List";}
|
public function GetEditClass() {return "LinkedSet";}
|
||||||
|
|
||||||
public function IsWritable() {return true;}
|
public function IsWritable() {return true;}
|
||||||
public function IsLinkSet() {return true;}
|
public function IsLinkSet() {return true;}
|
||||||
@@ -593,6 +597,11 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
return $this->GetOptional('tracking_level', LINKSET_TRACKING_LIST);
|
return $this->GetOptional('tracking_level', LINKSET_TRACKING_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetEditMode()
|
||||||
|
{
|
||||||
|
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
public function GetLinkedClass() {return $this->Get('linked_class');}
|
public function GetLinkedClass() {return $this->Get('linked_class');}
|
||||||
public function GetExtKeyToMe() {return $this->Get('ext_key_to_me');}
|
public function GetExtKeyToMe() {return $this->Get('ext_key_to_me');}
|
||||||
|
|
||||||
|
|||||||
249
js/linksdirectwidget.js
Normal file
249
js/linksdirectwidget.js
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
// jQuery UI style "widget" for managing 1:n links "in-place"
|
||||||
|
$(function()
|
||||||
|
{
|
||||||
|
// the widget definition, where "itop" is the namespace,
|
||||||
|
// "directlinks" the widget name
|
||||||
|
$.widget( "itop.directlinks",
|
||||||
|
{
|
||||||
|
// default options
|
||||||
|
options:
|
||||||
|
{
|
||||||
|
input_name: '',
|
||||||
|
class_name: '',
|
||||||
|
att_code: '',
|
||||||
|
submit_to: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||||
|
submit_parameters: {},
|
||||||
|
labels: { 'delete': 'Delete',
|
||||||
|
modify: 'Modify...' ,
|
||||||
|
creation_title: 'Creation of a new object...' ,
|
||||||
|
create: 'Create...'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// the constructor
|
||||||
|
_create: function()
|
||||||
|
{
|
||||||
|
var me = this;
|
||||||
|
this.id = this.element.attr('id');
|
||||||
|
|
||||||
|
this.element
|
||||||
|
.addClass('itop-directlinks');
|
||||||
|
|
||||||
|
this.datatable = this.element.find('table.listResults');
|
||||||
|
|
||||||
|
this.deleteBtn = $('<button type="button">' + this.options.labels['delete'] + '</button>');
|
||||||
|
this.modifyBtn = $('<button type="button">' + this.options.labels['modify'] + '</button>');
|
||||||
|
this.createBtn = $('<button type="button">' + this.options.labels['create'] + '</button>');
|
||||||
|
this.indicator = $('<span></span>');
|
||||||
|
this.inputToBeCreated = $('<input type="hidden" name="'+this.options.input_name+'_tbc" value="{}">');
|
||||||
|
this.toBeCreated = {};
|
||||||
|
this.inputToBeDeleted = $('<input type="hidden" name="'+this.options.input_name+'_tbd" value="[]">');
|
||||||
|
this.toBeDeleted = [];
|
||||||
|
|
||||||
|
|
||||||
|
this.element
|
||||||
|
.after(this.inputToBeCreated)
|
||||||
|
.after(this.inputToBeDeleted)
|
||||||
|
.after('<span style="float:left"> <img src="../images/tv-item-last.gif"> ')
|
||||||
|
.after(this.indicator).after(this.createBtn).after('  ')
|
||||||
|
.after(this.modifyBtn).after('  ')
|
||||||
|
.after(this.deleteBtn);
|
||||||
|
|
||||||
|
this.element.find('.selectList'+this.id).bind('change', function() { me._updateButtons(); });
|
||||||
|
this.deleteBtn.click(function() {
|
||||||
|
$('.selectList'+me.id+':checked', me.element).each( function() { me._deleteRow($(this)); });
|
||||||
|
});
|
||||||
|
this.createBtn.click(function() {
|
||||||
|
me._createRow();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.modifyBtn.hide(); //hidden for now since it's not yet implemented
|
||||||
|
|
||||||
|
this._updateButtons();
|
||||||
|
},
|
||||||
|
|
||||||
|
// called when created, and later when changing options
|
||||||
|
_refresh: function()
|
||||||
|
{
|
||||||
|
this._updateButtons();
|
||||||
|
},
|
||||||
|
// events bound via _bind are removed automatically
|
||||||
|
// revert other modifications here
|
||||||
|
destroy: function()
|
||||||
|
{
|
||||||
|
this.element
|
||||||
|
.removeClass('itop-directlinks');
|
||||||
|
|
||||||
|
// call the original destroy method since we overwrote it
|
||||||
|
$.Widget.prototype.destroy.call( this );
|
||||||
|
},
|
||||||
|
// _setOptions is called with a hash of all options that are changing
|
||||||
|
_setOptions: function()
|
||||||
|
{
|
||||||
|
// in 1.9 would use _superApply
|
||||||
|
$.Widget.prototype._setOptions.apply( this, arguments );
|
||||||
|
},
|
||||||
|
// _setOption is called for each individual option that is changing
|
||||||
|
_setOption: function( key, value )
|
||||||
|
{
|
||||||
|
// in 1.9 would use _super
|
||||||
|
$.Widget.prototype._setOption.call( this, key, value );
|
||||||
|
|
||||||
|
if (key == 'fields') this._refresh();
|
||||||
|
},
|
||||||
|
_updateButtons: function()
|
||||||
|
{
|
||||||
|
var oChecked = $('.selectList'+this.id+':checked', this.element);
|
||||||
|
switch(oChecked.length)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
this.deleteBtn.attr('disabled', 'disabled');
|
||||||
|
this.modifyBtn.attr('disabled', 'disabled');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
this.deleteBtn.removeAttr('disabled');
|
||||||
|
this.modifyBtn.removeAttr('disabled');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.deleteBtn.removeAttr('disabled');
|
||||||
|
this.modifyBtn.attr('disabled', 'disabled');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_updateTable: function()
|
||||||
|
{
|
||||||
|
var me = this;
|
||||||
|
this.datatable.trigger("update").trigger("applyWidgets");
|
||||||
|
this.datatable.tableHover();
|
||||||
|
this.datatable.find('.selectList'+this.id).bind('change', function() { me._updateButtons(); });
|
||||||
|
},
|
||||||
|
_updateDlgSize: function()
|
||||||
|
{
|
||||||
|
this.oDlg.dialog('option', { position: { my: "center", at: "center", of: window }});
|
||||||
|
},
|
||||||
|
_createRow: function()
|
||||||
|
{
|
||||||
|
this.createBtn.attr('disabled', 'disabled');
|
||||||
|
this.indicator.html('<img src="../images/indicator.gif">');
|
||||||
|
oParams = this.options.submit_parameters;
|
||||||
|
oParams.operation = 'createObject';
|
||||||
|
oParams['class'] = this.options.class_name;
|
||||||
|
oParams.real_class = '';
|
||||||
|
oParams.att_code = this.options.att_code;
|
||||||
|
oParams.iInputId = this.id;
|
||||||
|
var me = this;
|
||||||
|
$.post(this.options.submit_to, oParams, function(data){
|
||||||
|
me.oDlg = $('<div></div>');
|
||||||
|
$('body').append(me.oDlg);
|
||||||
|
me.oDlg.html(data);
|
||||||
|
me.oDlg.find('form').removeAttr('onsubmit').bind('submit', function() { me._onCreateRow(); return false; } );
|
||||||
|
me.oDlg.find('button.cancel').unbind('click').click( function() { me.oDlg.dialog('close'); } );
|
||||||
|
|
||||||
|
me.oDlg.dialog({
|
||||||
|
title: me.options.labels['creation_title'],
|
||||||
|
modal: true,
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
position: { my: "center", at: "center", of: window },
|
||||||
|
close: function() { me._onDlgClose(); }
|
||||||
|
});
|
||||||
|
me.indicator.html('');
|
||||||
|
me.createBtn.removeAttr('disabled');
|
||||||
|
me._updateDlgSize();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
subclassSelected: function()
|
||||||
|
{
|
||||||
|
var sRealClass = this.oDlg.find('select[name="class"]').val();
|
||||||
|
oParams = this.options.submit_parameters;
|
||||||
|
oParams.operation = 'createObject';
|
||||||
|
oParams['class'] = this.options.class_name;
|
||||||
|
oParams.real_class = sRealClass;
|
||||||
|
oParams.att_code = this.options.att_code;
|
||||||
|
oParams.iInputId = this.id;
|
||||||
|
var me = this;
|
||||||
|
me.oDlg.find('button').attr('disabled', 'disabled');
|
||||||
|
me.oDlg.find('span.indicator').html('<img src="../images/indicator.gif">');
|
||||||
|
$.post(this.options.submit_to, oParams, function(data){
|
||||||
|
me.oDlg.html(data);
|
||||||
|
me.oDlg.find('form').removeAttr('onsubmit').bind('submit', function() { me._onCreateRow(); return false; } );
|
||||||
|
me.oDlg.find('button.cancel').unbind('click').click( function() { me.oDlg.dialog('close'); } );
|
||||||
|
me._updateDlgSize();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_onCreateRow: function()
|
||||||
|
{
|
||||||
|
// Validate the form
|
||||||
|
var sFormId = this.oDlg.find('form').attr('id');
|
||||||
|
if (CheckFields(sFormId, true))
|
||||||
|
{
|
||||||
|
// Gather the values from the form
|
||||||
|
oParams = this.options.submit_parameters;
|
||||||
|
var oValues = {};
|
||||||
|
this.oDlg.find(':input').each( function() {
|
||||||
|
if (this.name != '')
|
||||||
|
{
|
||||||
|
oParams[this.name] = this.value;
|
||||||
|
oValues[this.name] = this.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var nextIdx = 0;
|
||||||
|
for(k in this.toBeCreated)
|
||||||
|
{
|
||||||
|
nextIdx++;
|
||||||
|
}
|
||||||
|
nextIdx++;
|
||||||
|
this.toBeCreated[nextIdx] = oValues;
|
||||||
|
this.inputToBeCreated.val(JSON.stringify(this.toBeCreated));
|
||||||
|
this.oDlg.dialog('close');
|
||||||
|
|
||||||
|
oParams = this.options.submit_parameters;
|
||||||
|
oParams.operation = 'getLinksetRow';
|
||||||
|
oParams['class'] = this.options.class_name;
|
||||||
|
oParams.att_code = this.options.att_code;
|
||||||
|
oParams.iInputId = this.id;
|
||||||
|
oParams.tempId = nextIdx;
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
this.createBtn.attr('disabled', 'disabled');
|
||||||
|
this.indicator.html('<img src="../images/indicator.gif">');
|
||||||
|
|
||||||
|
$.post(this.options.submit_to, oParams, function(data){
|
||||||
|
me.datatable.find('tbody').append(data);
|
||||||
|
me._updateTable();
|
||||||
|
me.indicator.html('');
|
||||||
|
me.createBtn.removeAttr('disabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_onDlgClose: function()
|
||||||
|
{
|
||||||
|
this.oDlg.remove();
|
||||||
|
this.oDlg = null;
|
||||||
|
},
|
||||||
|
_deleteRow: function(oCheckbox)
|
||||||
|
{
|
||||||
|
var iObjKey = parseInt(oCheckbox.val(), 10); // Number in base 10
|
||||||
|
|
||||||
|
if (iObjKey > 0)
|
||||||
|
{
|
||||||
|
// Existing objet: add it to the "to be deleted" list
|
||||||
|
this.toBeDeleted.push(iObjKey);
|
||||||
|
this.inputToBeDeleted.val(JSON.stringify(this.toBeDeleted));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Object to be created, just remove it from the "to be created" list
|
||||||
|
this.toBeCreated[-iObjKey] = undefined;
|
||||||
|
this.inputToBeCreated.val(JSON.stringify(this.toBeCreated));
|
||||||
|
}
|
||||||
|
// Now remove the row from the table
|
||||||
|
oRow = oCheckbox.closest('tr');
|
||||||
|
oRow.remove();
|
||||||
|
this._updateButtons();
|
||||||
|
this._updateTable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -532,6 +532,7 @@ try
|
|||||||
$oP->add_linked_script("../js/wizardhelper.js");
|
$oP->add_linked_script("../js/wizardhelper.js");
|
||||||
$oP->add_linked_script("../js/wizard.utils.js");
|
$oP->add_linked_script("../js/wizard.utils.js");
|
||||||
$oP->add_linked_script("../js/linkswidget.js");
|
$oP->add_linked_script("../js/linkswidget.js");
|
||||||
|
$oP->add_linked_script("../js/linksdirectwidget.js");
|
||||||
$oP->add_linked_script("../js/extkeywidget.js");
|
$oP->add_linked_script("../js/extkeywidget.js");
|
||||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
$oP->add_linked_script("../js/jquery.blockUI.js");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -238,6 +238,30 @@ try
|
|||||||
$oWidget->SearchObjectsToAdd($oPage, $sRemoteClass, $aAlreadyLinked);
|
$oWidget->SearchObjectsToAdd($oPage, $sRemoteClass, $aAlreadyLinked);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//ui.linksdirectwidget
|
||||||
|
case 'createObject':
|
||||||
|
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||||
|
$sRealClass = utils::ReadParam('real_class', '', false, 'class');
|
||||||
|
$sAttCode = utils::ReadParam('att_code', '');
|
||||||
|
$iInputId = utils::ReadParam('iInputId', '');
|
||||||
|
$oPage->SetContentType('text/html');
|
||||||
|
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
|
||||||
|
$oWidget->GetObjectCreationDlg($oPage, $sRealClass);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ui.linksdirectwidget
|
||||||
|
case 'getLinksetRow':
|
||||||
|
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||||
|
$sRealClass = utils::ReadParam('real_class', '', false, 'class');
|
||||||
|
$sAttCode = utils::ReadParam('att_code', '');
|
||||||
|
$iInputId = utils::ReadParam('iInputId', '');
|
||||||
|
$iTempId = utils::ReadParam('tempId', '');
|
||||||
|
$aValues = utils::ReadParam('values', array(), false, 'raw_data');
|
||||||
|
$oPage->SetContentType('text/html');
|
||||||
|
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
|
||||||
|
$oPage->add($oWidget->GetRow($oPage, $sRealClass, $aValues, $iTempId));
|
||||||
|
break;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// ui.extkeywidget
|
// ui.extkeywidget
|
||||||
|
|||||||
@@ -307,7 +307,28 @@ EOF;
|
|||||||
return $aXmlToPHP[$sTrackingLevel];
|
return $aXmlToPHP[$sTrackingLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to format the edit-mode for direct linkset
|
||||||
|
* @param string $sEditMode Value set from within the XML
|
||||||
|
* Returns string PHP flag
|
||||||
|
*/
|
||||||
|
protected function EditModeToPHP($sEditMode)
|
||||||
|
{
|
||||||
|
static $aXmlToPHP = array(
|
||||||
|
'none' => 'LINKSET_EDITMODE_NONE',
|
||||||
|
'add_only' => 'LINKSET_EDITMODE_ADDONLY',
|
||||||
|
'actions' => 'LINKSET_EDITMODE_ACTIONS',
|
||||||
|
'in_place' => 'LINKSET_EDITMODE_INPLACE',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!array_key_exists($sEditMode, $aXmlToPHP))
|
||||||
|
{
|
||||||
|
throw new exception("Edit mode: unknown value '$sTrackingLevel'");
|
||||||
|
}
|
||||||
|
return $aXmlToPHP[$sEditMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a path (file or url) as an absolute path or relative to the module or the app
|
* Format a path (file or url) as an absolute path or relative to the module or the app
|
||||||
*/
|
*/
|
||||||
@@ -584,6 +605,11 @@ EOF;
|
|||||||
{
|
{
|
||||||
$aParameters['tracking_level'] = $this->TrackingLevelToPHP($sTrackingLevel);
|
$aParameters['tracking_level'] = $this->TrackingLevelToPHP($sTrackingLevel);
|
||||||
}
|
}
|
||||||
|
$sEditMode = $oField->GetChildText('edit_mode');
|
||||||
|
if (!is_null($sEditMode))
|
||||||
|
{
|
||||||
|
$aParameters['edit_mode'] = $this->EditModeToPHP($sEditMode);
|
||||||
|
}
|
||||||
$aParameters['depends_on'] = $sDependencies;
|
$aParameters['depends_on'] = $sDependencies;
|
||||||
}
|
}
|
||||||
elseif ($sAttType == 'AttributeExternalKey')
|
elseif ($sAttType == 'AttributeExternalKey')
|
||||||
|
|||||||
Reference in New Issue
Block a user