mirror of
https://github.com/Combodo/iTop.git
synced 2026-08-22 14:18:18 +02:00
#757 Better UI to manage direct linksets... on going...
SVN:trunk[2927]
This commit is contained in:
@@ -2541,7 +2541,8 @@ EOF
|
||||
$this->Set($sAttCode, $iValue);
|
||||
}
|
||||
}
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() && ($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE))
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() &&
|
||||
(($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE) || ($oAttDef->GetEditMode() == LINKSET_EDITMODE_ADDREMOVE)))
|
||||
{
|
||||
$oLinkset = $this->Get($sAttCode);
|
||||
$sLinkedClass = $oLinkset->GetClass();
|
||||
@@ -2557,13 +2558,16 @@ EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
$aObjSet[] = $oLink;
|
||||
if (!array_key_exists('to_be_removed', $value) || !in_array($oLink->GetKey(), $value['to_be_removed']))
|
||||
{
|
||||
$aObjSet[] = $oLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('to_be_created', $value) && (count($value['to_be_created']) > 0))
|
||||
{
|
||||
// Now handle the lniks to be created
|
||||
// Now handle the links to be created
|
||||
foreach($value['to_be_created'] as $aData)
|
||||
{
|
||||
$sSubClass = $aData['class'];
|
||||
@@ -2578,7 +2582,35 @@ EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('to_be_added', $value) && (count($value['to_be_added']) > 0))
|
||||
{
|
||||
// Now handle the links to be added by making the remote object point to self
|
||||
foreach($value['to_be_added'] as $iObjKey)
|
||||
{
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false);
|
||||
if ($oLink)
|
||||
{
|
||||
$aObjSet[] = $oLink;
|
||||
$bModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('to_be_removed', $value) && (count($value['to_be_removed']) > 0))
|
||||
{
|
||||
// Now handle the links to be removed by making the remote object point to nothing
|
||||
// Keep them in the set (modified), DBWriteLinks will handle them
|
||||
foreach($value['to_be_removed'] as $iObjKey)
|
||||
{
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false);
|
||||
if ($oLink)
|
||||
{
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$oLink->Set($sExtKeyToMe, null);
|
||||
$aObjSet[] = $oLink;
|
||||
$bModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($bModified)
|
||||
{
|
||||
$oNewSet = DBObjectSet::FromArray($oLinkset->GetClass(), $aObjSet);
|
||||
@@ -2617,7 +2649,8 @@ EOF
|
||||
{
|
||||
$value = array('fcontents' => utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents'));
|
||||
}
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() && ($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE))
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() &&
|
||||
(($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE) || ($oAttDef->GetEditMode() == LINKSET_EDITMODE_ADDREMOVE)) )
|
||||
{
|
||||
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}', 'raw_data'), true);
|
||||
$aToBeCreated = array();
|
||||
@@ -2637,7 +2670,9 @@ EOF
|
||||
}
|
||||
|
||||
$value = array('to_be_created' => $aToBeCreated,
|
||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true) );
|
||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true),
|
||||
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]', 'raw_data'), true),
|
||||
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]', 'raw_data'), true) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -54,6 +54,7 @@ class UILinksWidgetDirect
|
||||
|
||||
default:
|
||||
$aZList = MetaModel::FlattenZList(MetaModel::GetZListItems($this->sLinkedClass, 'list'));
|
||||
array_unshift($aZList, 'friendlyname');
|
||||
}
|
||||
foreach($aZList as $sLinkedAttCode)
|
||||
{
|
||||
@@ -97,6 +98,18 @@ class UILinksWidgetDirect
|
||||
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj);
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_ADDREMOVE: // The whole linkset can be edited 'in-place'
|
||||
$sTargetClass = $oLinksetDef->GetLinkedClass();
|
||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||
$oExtKeyDef = MetaModel::GetAttributeDef($sTargetClass, $sExtKeyToMe);
|
||||
$aButtons = array('add');
|
||||
if ($oExtKeyDef->IsNullAllowed())
|
||||
{
|
||||
$aButtons = array('add', 'remove');
|
||||
}
|
||||
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons);
|
||||
break;
|
||||
|
||||
case LINKSET_EDITMODE_ACTIONS:
|
||||
default:
|
||||
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, true /* bDisplayMenu*/);
|
||||
@@ -139,7 +152,7 @@ class UILinksWidgetDirect
|
||||
}
|
||||
}
|
||||
|
||||
protected function DisplayEditInPlace(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||
protected function DisplayEditInPlace(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
|
||||
@@ -165,10 +178,16 @@ class UILinksWidgetDirect
|
||||
// 'modify' => 'Modify...' ,
|
||||
'creation_title' => Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sLinkedClass)),
|
||||
'create' => Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($this->sLinkedClass)),
|
||||
'remove' => Dict::S('UI:Button:Remove'),
|
||||
'add' => Dict::Format('UI:AddAnExisting_Class', MetaModel::GetName($this->sLinkedClass)),
|
||||
'selection_title' => Dict::Format('UI:SelectionOf_Class', MetaModel::GetName($this->sLinkedClass)),
|
||||
);
|
||||
$sSubmitUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
|
||||
$oContext = new ApplicationContext();
|
||||
$sSubmitUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?'.$oContext->GetForLink();
|
||||
$sJSONLabels = json_encode($aLabels);
|
||||
$oPage->add_ready_script("$('#{$this->sInputid}').directlinks({class_name: '$this->sClass', att_code: '$this->sAttCode', input_name:'$sInputName', labels: $sJSONLabels, sumit_to: '$sSubmitUrl' });");
|
||||
$sJSONButtons = json_encode($aButtons);
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script("$('#{$this->sInputid}').directlinks({class_name: '$this->sClass', att_code: '$this->sAttCode', input_name:'$sInputName', labels: $sJSONLabels, submit_to: '$sSubmitUrl', buttons: $sJSONButtons, oWizardHelper: $sWizHelper });");
|
||||
}
|
||||
|
||||
public function GetObjectCreationDlg(WebPage $oPage, $sProposedRealClass = '')
|
||||
@@ -221,6 +240,71 @@ class UILinksWidgetDirect
|
||||
$oPage->add('</div></div>');
|
||||
}
|
||||
|
||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj)
|
||||
{
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
||||
if ($oCurrentObj != null)
|
||||
{
|
||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}", array('open' => true));
|
||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->sInputid}\">\n";
|
||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->sInputid}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->sInputid}\" value=\"0\"/>";
|
||||
$sHtml .= "<button type=\"button\" class=\"cancel\">".Dict::S('UI:Button:Cancel')."</button> <button class=\"ok\" disabled=\"disabled\">".Dict::S('UI:Button:Add')."</button>";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "</form>\n";
|
||||
$oPage->add($sHtml);
|
||||
//$oPage->add_ready_script("$('#SearchFormToAdd_{$this->sAttCode}{$this->sNameSuffix} form').bind('submit.uilinksWizard', oWidget{$this->sInputId}.SearchObjectsToAdd);");
|
||||
//$oPage->add_ready_script("$('#SearchFormToAdd_{$this->sAttCode}{$this->sNameSuffix}').resize(oWidget{$this->siInputId}.UpdateSizes);");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of $this->sLinkedClass
|
||||
* @param array $aAlreadyLinked Array of indentifiers of objects which are already linke to the current object (or about to be linked)
|
||||
* @param DBObject $oCurrentObj The object currently being edited... if known...
|
||||
*/
|
||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null)
|
||||
{
|
||||
if ($sRemoteClass == '')
|
||||
{
|
||||
$sRemoteClass = $this->sLinkedClass;
|
||||
}
|
||||
$oFilter = new DBObjectSearch($sRemoteClass);
|
||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($sRemoteClass, $this->sClass))
|
||||
{
|
||||
// Prevent linking to self if the linked object is of the same family
|
||||
// and laready present in the database
|
||||
if (!$oCurrentObj->IsNew())
|
||||
{
|
||||
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||
}
|
||||
}
|
||||
if (count($aAlreadyLinked) > 0)
|
||||
{
|
||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", array('menu' => false, 'cssCount'=> '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
public function DoAddObjects(WebPage $oP, $oFullSetFilter)
|
||||
{
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
$oLinkObj = MetaModel::GetObject($this->sLinkedClass, $iObjectId);
|
||||
$oP->add($this->GetObjectRow($oP, $oLinkObj, $oLinkObj->GetKey()));
|
||||
}
|
||||
}
|
||||
|
||||
public function GetObjectModificationDlg()
|
||||
{
|
||||
|
||||
@@ -238,9 +322,9 @@ class UILinksWidgetDirect
|
||||
}
|
||||
return $aAttribs;
|
||||
}
|
||||
|
||||
public function GetRow($oPage, $sRealClass, $aValues, $iTempId)
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
if ($sRealClass == '')
|
||||
{
|
||||
$sRealClass = $this->sLinkedClass;
|
||||
@@ -248,17 +332,60 @@ class UILinksWidgetDirect
|
||||
$oLinkObj = new $sRealClass();
|
||||
$oLinkObj->UpdateObjectFromPostedForm($this->sInputid);
|
||||
|
||||
return $this->GetObjectRow($oPage, $oLinkObj, $iTempId);
|
||||
}
|
||||
|
||||
protected function GetObjectRow($oPage, $oLinkObj, $iTempId)
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
$aRow = array();
|
||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.(-$iTempId).'"/>';
|
||||
$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);
|
||||
return $oPage->GetTableRow($aRow, $aAttribs);
|
||||
}
|
||||
|
||||
public function UpdateFromArray($oObj, $aData)
|
||||
/**
|
||||
* Initializes the default search parameters based on 1) a 'current' object and 2) the silos defined by the context
|
||||
* @param DBObject $oSourceObj
|
||||
* @param DBObjectSearch $oSearch
|
||||
*/
|
||||
protected function SetSearchDefaultFromContext($oSourceObj, &$oSearch)
|
||||
{
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sSrcClass = get_class($oSourceObj);
|
||||
$sDestClass = $oSearch->GetClass();
|
||||
foreach($oAppContext->GetNames() as $key)
|
||||
{
|
||||
// Find the value of the object corresponding to each 'context' parameter
|
||||
$aCallSpec = array($sSrcClass, 'MapContextParam');
|
||||
$sAttCode = '';
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode))
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sSrcClass, $sAttCode);
|
||||
$defaultValue = $oSourceObj->Get($sAttCode);
|
||||
|
||||
// Find the attcode for the same 'context' parameter in the destination class
|
||||
// and sets its value as the default value for the search condition
|
||||
$aCallSpec = array($sDestClass, 'MapContextParam');
|
||||
$sAttCode = '';
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||
}
|
||||
|
||||
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue))
|
||||
{
|
||||
$oSearch->AddCondition($sAttCode, $defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ define('LINKSET_EDITMODE_NONE', 0); // The linkset cannot be edited at all from
|
||||
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
|
||||
define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/removed in place
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1201,24 +1201,39 @@ abstract class DBObject
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef)
|
||||
{
|
||||
if (!$oAttDef->IsLinkSet()) continue;
|
||||
|
||||
|
||||
$oOriginalSet = $this->m_aOrigValues[$sAttCode];
|
||||
if ($oOriginalSet != null)
|
||||
{
|
||||
$aOriginalList = $oOriginalSet->ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aOriginalList = array();
|
||||
}
|
||||
|
||||
$oLinks = $this->Get($sAttCode);
|
||||
$oLinks->Rewind();
|
||||
while ($oLinkedObject = $oLinks->Fetch())
|
||||
{
|
||||
$oLinkedObject->Set($oAttDef->GetExtKeyToMe(), $this->m_iKey);
|
||||
if (!array_key_exists($oLinkedObject->GetKey(), $aOriginalList))
|
||||
{
|
||||
// New object added to the set, make it point properly
|
||||
$oLinkedObject->Set($oAttDef->GetExtKeyToMe(), $this->m_iKey);
|
||||
}
|
||||
if ($oLinkedObject->IsModified())
|
||||
{
|
||||
// Objects can be modified because:
|
||||
// 1) They've just been added into the set, so their ExtKey is modified
|
||||
// 2) They are about to be removed from the set BUT NOT deleted, their ExtKey has been reset
|
||||
$oLinkedObject->DBWrite();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the objects that were initialy present and disappeared from the list
|
||||
// (if any)
|
||||
$oOriginalSet = $this->m_aOrigValues[$sAttCode];
|
||||
if ($oOriginalSet != null)
|
||||
if (count($aOriginalList) > 0)
|
||||
{
|
||||
$aOriginalList = $oOriginalSet->ToArray();
|
||||
$aNewSet = $oLinks->ToArray();
|
||||
|
||||
foreach($aOriginalList as $iId => $oObject)
|
||||
|
||||
@@ -108,28 +108,28 @@
|
||||
<field id="related_request_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>UserRequest</linked_class>
|
||||
<ext_key_to_me>parent_change_id</ext_key_to_me>
|
||||
<edit_mode>none</edit_mode>
|
||||
<edit_mode>add_remove</edit_mode>
|
||||
<count_min>0</count_min>
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
<field id="related_incident_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>Incident</linked_class>
|
||||
<ext_key_to_me>parent_change_id</ext_key_to_me>
|
||||
<edit_mode>none</edit_mode>
|
||||
<edit_mode>add_remove</edit_mode>
|
||||
<count_min>0</count_min>
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
<field id="related_problems_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>Problem</linked_class>
|
||||
<ext_key_to_me>related_change_id</ext_key_to_me>
|
||||
<edit_mode>none</edit_mode>
|
||||
<edit_mode>add_remove</edit_mode>
|
||||
<count_min>0</count_min>
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
<field id="child_changes_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>Change</linked_class>
|
||||
<ext_key_to_me>parent_id</ext_key_to_me>
|
||||
<edit_mode>none</edit_mode>
|
||||
<edit_mode>add_remove</edit_mode>
|
||||
<count_min>0</count_min>
|
||||
<count_max>0</count_max>
|
||||
</field>
|
||||
|
||||
@@ -1189,6 +1189,9 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:CSVImportCreated_items' => 'Created: %1$d',
|
||||
'UI:CSVImportModified_items' => 'Modified: %1$d',
|
||||
'UI:CSVImportUnchanged_items' => 'Unchanged: %1$d',
|
||||
|
||||
|
||||
'UI:Button:Remove' => 'Remove',
|
||||
'UI:AddAnExisting_Class' => 'Add objects of type %1$s...',
|
||||
'UI:SelectionOf_Class' => 'Selection of objects of type %1$s',
|
||||
));
|
||||
?>
|
||||
|
||||
@@ -1025,5 +1025,9 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:CSVImportCreated_items' => 'Créations: %1$d',
|
||||
'UI:CSVImportModified_items' => 'Modifications: %1$d',
|
||||
'UI:CSVImportUnchanged_items' => 'Inchangés: %1$d',
|
||||
|
||||
'UI:Button:Remove' => 'Enlever',
|
||||
'UI:AddAnExisting_Class' => 'Ajouter des objets de type %1$s...',
|
||||
'UI:SelectionOf_Class' => 'Sélection d\'objets de type %1$s',
|
||||
));
|
||||
?>
|
||||
|
||||
@@ -16,8 +16,13 @@ $(function()
|
||||
labels: { 'delete': 'Delete',
|
||||
modify: 'Modify...' ,
|
||||
creation_title: 'Creation of a new object...' ,
|
||||
create: 'Create...'
|
||||
}
|
||||
create: 'Create...',
|
||||
add: 'Add...',
|
||||
remove: 'Remove',
|
||||
selection_title: 'Objects selection'
|
||||
},
|
||||
buttons: ['create', 'delete'],
|
||||
oWizardHelper: null
|
||||
},
|
||||
|
||||
// the constructor
|
||||
@@ -31,34 +36,49 @@ $(function()
|
||||
|
||||
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>');
|
||||
var aButtonsTypes = ['delete', 'remove', 'modify', 'add', 'create'];
|
||||
this.oButtons = {};
|
||||
for(k in aButtonsTypes)
|
||||
{
|
||||
this.oButtons[aButtonsTypes[k]] = $('<button type="button">' + this.options.labels[aButtonsTypes[k]] + '</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.inputToBeAdded = $('<input type="hidden" name="'+this.options.input_name+'_tba" value="[]">');
|
||||
this.toBeAdded = [];
|
||||
this.inputToBeRemoved = $('<input type="hidden" name="'+this.options.input_name+'_tbr" value="[]">');
|
||||
this.toBeRemoved = [];
|
||||
|
||||
|
||||
this.element
|
||||
.after(this.inputToBeCreated)
|
||||
.after(this.inputToBeDeleted)
|
||||
.after(this.inputToBeAdded)
|
||||
.after(this.inputToBeRemoved)
|
||||
.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);
|
||||
.after(this.indicator);
|
||||
for(k in this.options.buttons)
|
||||
{
|
||||
this.element.after(this.oButtons[this.options.buttons[k]]).after(' ');
|
||||
}
|
||||
|
||||
this.element.find('.selectList'+this.id).bind('change', function() { me._updateButtons(); });
|
||||
this.deleteBtn.click(function() {
|
||||
this.oButtons['delete'].click(function() {
|
||||
$('.selectList'+me.id+':checked', me.element).each( function() { me._deleteRow($(this)); });
|
||||
});
|
||||
this.createBtn.click(function() {
|
||||
this.oButtons['create'].click(function() {
|
||||
me._createRow();
|
||||
});
|
||||
|
||||
this.modifyBtn.hide(); //hidden for now since it's not yet implemented
|
||||
|
||||
this.oButtons['remove'].click(function() {
|
||||
$('.selectList'+me.id+':checked', me.element).each( function() { me._removeRow($(this)); });
|
||||
});
|
||||
this.oButtons['add'].click(function() {
|
||||
me._selectToAdd();
|
||||
});
|
||||
|
||||
this._updateButtons();
|
||||
},
|
||||
|
||||
@@ -94,18 +114,21 @@ $(function()
|
||||
switch(oChecked.length)
|
||||
{
|
||||
case 0:
|
||||
this.deleteBtn.attr('disabled', 'disabled');
|
||||
this.modifyBtn.attr('disabled', 'disabled');
|
||||
this.oButtons['delete'].attr('disabled', 'disabled');
|
||||
this.oButtons['remove'].attr('disabled', 'disabled');
|
||||
this.oButtons['modify'].attr('disabled', 'disabled');
|
||||
break;
|
||||
|
||||
case 1:
|
||||
this.deleteBtn.removeAttr('disabled');
|
||||
this.modifyBtn.removeAttr('disabled');
|
||||
this.oButtons['delete'].removeAttr('disabled');
|
||||
this.oButtons['remove'].removeAttr('disabled');
|
||||
this.oButtons['modify'].removeAttr('disabled');
|
||||
break;
|
||||
|
||||
default:
|
||||
this.deleteBtn.removeAttr('disabled');
|
||||
this.modifyBtn.attr('disabled', 'disabled');
|
||||
this.oButtons['delete'].removeAttr('disabled');
|
||||
this.oButtons['remove'].removeAttr('disabled');
|
||||
this.oButtons['modify'].attr('disabled', 'disabled');
|
||||
break;
|
||||
}
|
||||
},
|
||||
@@ -122,7 +145,7 @@ $(function()
|
||||
},
|
||||
_createRow: function()
|
||||
{
|
||||
this.createBtn.attr('disabled', 'disabled');
|
||||
this.oButtons['create'].attr('disabled', 'disabled');
|
||||
this.indicator.html('<img src="../images/indicator.gif">');
|
||||
oParams = this.options.submit_parameters;
|
||||
oParams.operation = 'createObject';
|
||||
@@ -147,10 +170,184 @@ $(function()
|
||||
close: function() { me._onDlgClose(); }
|
||||
});
|
||||
me.indicator.html('');
|
||||
me.createBtn.removeAttr('disabled');
|
||||
me.oButtons['create'].removeAttr('disabled');
|
||||
me._updateDlgSize();
|
||||
});
|
||||
},
|
||||
_selectToAdd: function()
|
||||
{
|
||||
this.oButtons['add'].attr('disabled', 'disabled');
|
||||
this.indicator.html('<img src="../images/indicator.gif">');
|
||||
oParams = this.options.submit_parameters;
|
||||
oParams.operation = 'selectObjectsToAdd';
|
||||
oParams['class'] = this.options.class_name;
|
||||
oParams.real_class = '';
|
||||
oParams.att_code = this.options.att_code;
|
||||
oParams.iInputId = this.id;
|
||||
if (this.options.oWizardHelper)
|
||||
{
|
||||
this.options.oWizardHelper.UpdateWizard();
|
||||
oParams.json = this.options.oWizardHelper.ToJSON();
|
||||
}
|
||||
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._onSearchToAdd(); return false; } );
|
||||
me.oDlg.find('button.cancel').unbind('click').click( function() { me.oDlg.dialog('close'); } );
|
||||
me.oDlg.find('button.ok').unbind('click').click( function() { me._onDoAdd(); } );
|
||||
|
||||
me.oDlg.dialog({
|
||||
title: me.options.labels['selection_title'],
|
||||
modal: true,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
position: { my: "center", at: "center", of: window },
|
||||
close: function() { me._onDlgClose(); }
|
||||
});
|
||||
me.indicator.html('');
|
||||
me.oButtons['add'].removeAttr('disabled');
|
||||
me._onSearchToAdd();
|
||||
me._updateDlgSize();
|
||||
});
|
||||
},
|
||||
_onSearchToAdd: function()
|
||||
{
|
||||
var oParams = {};
|
||||
// Gather the parameters from the search form
|
||||
$('#SearchFormToAdd_'+this.id+' :input').each( function() {
|
||||
if (this.name != '')
|
||||
{
|
||||
var val = $(this).val(); // supports multiselect as well
|
||||
if (val !== null)
|
||||
{
|
||||
oParams[this.name] = val;
|
||||
}
|
||||
}
|
||||
});
|
||||
// Gather the already linked target objects
|
||||
oParams.aAlreadyLinked = new Array();
|
||||
$('#'+this.id+' .listResults td input:checkbox').each(function(){
|
||||
iKey = parseInt(this.value, 10); // Numbers are in base 10
|
||||
oParams.aAlreadyLinked.push(iKey);
|
||||
}
|
||||
); oParams.operation = 'searchObjectsToAdd2';
|
||||
oParams['class'] = this.options.class_name;
|
||||
oParams.real_class = '';
|
||||
oParams.att_code = this.options.att_code;
|
||||
oParams.iInputId = this.id;
|
||||
if (this.options.oWizardHelper)
|
||||
{
|
||||
this.options.oWizardHelper.UpdateWizard();
|
||||
oParams.json = this.options.oWizardHelper.ToJSON();
|
||||
}
|
||||
var me = this;
|
||||
$('#SearchResultsToAdd_'+me.id).block();
|
||||
$.post(this.options.submit_to, oParams, function(data) {
|
||||
|
||||
$('#SearchResultsToAdd_'+me.id).html(data);
|
||||
$('#SearchResultsToAdd_'+me.id+' .listResults').tableHover();
|
||||
$('#count_'+me.id).change(function() {
|
||||
var c = this.value;
|
||||
me._onUpdateDlgButtons(c);
|
||||
});
|
||||
$('#SearchResultsToAdd_'+me.id).unblock();
|
||||
});
|
||||
//alert("C'est parti mon kiki !");
|
||||
return false; // Stay on the page, no submit
|
||||
},
|
||||
_getSelection: function(sName)
|
||||
{
|
||||
// Gather the parameters from the search form
|
||||
var oMap = {};
|
||||
var oContext = $('#SearchResultsToAdd_'+this.id);
|
||||
var selectionMode = $(':input[name=selectionMode]', oContext);
|
||||
if (selectionMode.length > 0)
|
||||
{
|
||||
// Paginated table retrieve the mode and the exceptions
|
||||
var sMode = selectionMode.val();
|
||||
oMap['selectionMode'] = sMode;
|
||||
$('#fs_SearchFormToAdd_'+this.id+' :input').each(
|
||||
function(i)
|
||||
{
|
||||
oMap[this.name] = this.value;
|
||||
}
|
||||
);
|
||||
$(':input[name^=storedSelection]', oContext).each(function() {
|
||||
if (oMap[this.name] == undefined)
|
||||
{
|
||||
oMap[this.name] = new Array();
|
||||
}
|
||||
oMap[this.name].push(this.value);
|
||||
});
|
||||
// Retrieve the 'filter' definition
|
||||
var table = $('#ResultsToAdd_'+this.id).find('table.listResults')[0];
|
||||
oMap['filter'] = table.config.filter;
|
||||
oMap['extra_params'] = table.config.extra_params;
|
||||
}
|
||||
// Normal table, retrieve all the checked check-boxes
|
||||
$(':checked[name^=selectObject]', oContext).each(
|
||||
function(i)
|
||||
{
|
||||
if ( (this.name != '') && ((this.type != 'checkbox') || (this.checked)) )
|
||||
{
|
||||
arrayExpr = /\[\]$/;
|
||||
if (arrayExpr.test(this.name))
|
||||
{
|
||||
// Array
|
||||
if (oMap[this.name] == undefined)
|
||||
{
|
||||
oMap[this.name] = new Array();
|
||||
}
|
||||
oMap[this.name].push(this.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
oMap[this.name] = this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
return oMap;
|
||||
},
|
||||
_onUpdateDlgButtons: function(iCount)
|
||||
{
|
||||
if (iCount > 0)
|
||||
{
|
||||
this.oDlg.find('button.ok').removeAttr('disabled');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.oDlg.find('button.ok').attr('disabled', 'disabled');
|
||||
}
|
||||
},
|
||||
_onDoAdd:function()
|
||||
{
|
||||
var oParams = this._getSelection('selectObject');
|
||||
this.oDlg.dialog('close');
|
||||
oParams.operation = 'doAddObjects2';
|
||||
oParams['class'] = this.options.class_name;
|
||||
oParams.att_code = this.options.att_code;
|
||||
oParams.iInputId = this.id;
|
||||
var me = this;
|
||||
$.post(this.options.submit_to, oParams, function(data) {
|
||||
var oInserted = $(data);
|
||||
oInserted.find('input:checkbox').each(function() {
|
||||
var iKey = parseInt($(this).val(), 10); // Number in base 10
|
||||
me.toBeAdded.push(iKey);
|
||||
me.toBeRemoved = me._ArrayRemove(me.toBeRemoved, iKey);
|
||||
me.toBeDeleted = me._ArrayRemove(me.toBeDeleted, iKey);
|
||||
});
|
||||
me.inputToBeAdded.val(JSON.stringify(me.toBeAdded));
|
||||
me.inputToBeRemoved.val(JSON.stringify(me.toBeRemoved));
|
||||
me.inputToBeDeleted.val(JSON.stringify(me.toBeDeleted));
|
||||
me.datatable.find('tbody').append(data);
|
||||
me._updateTable();
|
||||
me.indicator.html('');
|
||||
me.oButtons['add'].removeAttr('disabled');
|
||||
});
|
||||
},
|
||||
subclassSelected: function()
|
||||
{
|
||||
var sRealClass = this.oDlg.find('select[name="class"]').val();
|
||||
@@ -204,14 +401,14 @@ $(function()
|
||||
oParams.tempId = nextIdx;
|
||||
var me = this;
|
||||
|
||||
this.createBtn.attr('disabled', 'disabled');
|
||||
this.oButtons['create'].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');
|
||||
me.oButtons['create'].removeAttr('disabled');
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -227,13 +424,22 @@ $(function()
|
||||
if (iObjKey > 0)
|
||||
{
|
||||
// Existing objet: add it to the "to be deleted" list
|
||||
this.toBeDeleted.push(iObjKey);
|
||||
this.inputToBeDeleted.val(JSON.stringify(this.toBeDeleted));
|
||||
// if it has not just been added now
|
||||
if (this._InArray(this.toBeAdded, iObjKey))
|
||||
{
|
||||
this.toBeAdded = this._ArrayRemove(this.toBeAdded, iObjKey);
|
||||
this.inputToBeAdded.val(JSON.stringify(this.toBeAdded));
|
||||
}
|
||||
else
|
||||
{
|
||||
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.toBeCreated = this._ArrayRemove(this.toBeCreated, iObjKey);
|
||||
this.inputToBeCreated.val(JSON.stringify(this.toBeCreated));
|
||||
}
|
||||
// Now remove the row from the table
|
||||
@@ -241,6 +447,61 @@ $(function()
|
||||
oRow.remove();
|
||||
this._updateButtons();
|
||||
this._updateTable();
|
||||
},
|
||||
_removeRow: function(oCheckbox)
|
||||
{
|
||||
var iObjKey = parseInt(oCheckbox.val(), 10); // Number in base 10
|
||||
|
||||
if (iObjKey > 0)
|
||||
{
|
||||
// Existing objet: add it to the "to be removed" list
|
||||
// if it has not just been added now
|
||||
if (this._InArray(this.toBeAdded, iObjKey))
|
||||
{
|
||||
this.toBeAdded = this._ArrayRemove(this.toBeAdded, iObjKey);
|
||||
this.inputToBeAdded.val(JSON.stringify(this.toBeAdded));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.toBeRemoved.push(iObjKey);
|
||||
this.inputToBeRemoved.val(JSON.stringify(this.toBeRemoved));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Object to be created, just remove it from the "to be created" list
|
||||
this.toBeCreated = this._ArrayRemove(this.toBeCreated, iObjKey);
|
||||
this.inputToBeCreated.val(JSON.stringify(this.toBeCreated));
|
||||
}
|
||||
// Now remove the row from the table
|
||||
oRow = oCheckbox.closest('tr');
|
||||
oRow.remove();
|
||||
this._updateButtons();
|
||||
this._updateTable();
|
||||
},
|
||||
_InArray: function(aArrayToSearch, needle)
|
||||
{
|
||||
aRes = [];
|
||||
for(k in aArrayToSearch)
|
||||
{
|
||||
if (aArrayToSearch[k] == needle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
_ArrayRemove: function(aArrayToFilter, needle)
|
||||
{
|
||||
aRes = [];
|
||||
for(k in aArrayToFilter)
|
||||
{
|
||||
if (aArrayToFilter[k] != needle)
|
||||
{
|
||||
aRes.push(aArrayToFilter[k]);
|
||||
}
|
||||
}
|
||||
return aRes;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -285,7 +285,68 @@ try
|
||||
$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));
|
||||
$oPage->add($oWidget->GetRow($oPage, $sRealClass, $aValues, -$iTempId));
|
||||
break;
|
||||
|
||||
// ui.linksdirectwidget
|
||||
case 'selectObjectsToAdd':
|
||||
$oPage->SetContentType('text/html');
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sJson = utils::ReadParam('json', '', false, 'raw_data');
|
||||
$oObj = null;
|
||||
if ($sJson != '')
|
||||
{
|
||||
$oWizardHelper = WizardHelper::FromJSON($sJson);
|
||||
$oObj = $oWizardHelper->GetTargetObject();
|
||||
}
|
||||
$sRealClass = utils::ReadParam('real_class', '', false, 'class');
|
||||
$sAttCode = utils::ReadParam('att_code', '');
|
||||
$iInputId = utils::ReadParam('iInputId', '');
|
||||
$iCurrObjectId = utils::ReadParam('iObjId', 0);
|
||||
$oPage->SetContentType('text/html');
|
||||
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
|
||||
$oWidget->GetObjectsSelectionDlg($oPage, $oObj);
|
||||
break;
|
||||
|
||||
// ui.linksdirectwidget
|
||||
case 'searchObjectsToAdd2':
|
||||
$oPage->SetContentType('text/html');
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sRealClass = utils::ReadParam('real_class', '', false, 'class');
|
||||
$sAttCode = utils::ReadParam('att_code', '');
|
||||
$iInputId = utils::ReadParam('iInputId', '');
|
||||
$aAlreadyLinked = utils::ReadParam('aAlreadyLinked', array());
|
||||
$sJson = utils::ReadParam('json', '', false, 'raw_data');
|
||||
$oObj = null;
|
||||
if ($sJson != '')
|
||||
{
|
||||
$oWizardHelper = WizardHelper::FromJSON($sJson);
|
||||
$oObj = $oWizardHelper->GetTargetObject();
|
||||
}
|
||||
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
|
||||
$oWidget->SearchObjectsToAdd($oPage, $sRealClass, $aAlreadyLinked, $oObj);
|
||||
break;
|
||||
|
||||
// ui.linksdirectwidget
|
||||
case 'doAddObjects2':
|
||||
$oPage->SetContentType('text/html');
|
||||
$oPage->SetContentType('text/html');
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sRealClass = utils::ReadParam('real_class', '', false, 'class');
|
||||
$sAttCode = utils::ReadParam('att_code', '');
|
||||
$iInputId = utils::ReadParam('iInputId', '');
|
||||
$iCurrObjectId = utils::ReadParam('iObjId', 0);
|
||||
$sFilter = utils::ReadParam('filter', '');
|
||||
if ($sFilter != '')
|
||||
{
|
||||
$oFullSetFilter = DBObjectSearch::unserialize($sFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oFullSetFilter = new DBObjectSearch($sRemoteClass);
|
||||
}
|
||||
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iInputId);
|
||||
$oWidget->DoAddObjects($oPage, $oFullSetFilter);
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -456,6 +517,8 @@ try
|
||||
$oWidget->DoAddObjects($oPage, $oFullSetFilter, $oObj);
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
case 'wizard_helper_preview':
|
||||
$oPage->SetContentType('text/html');
|
||||
$sJson = utils::ReadParam('json_obj', '', false, 'raw_data');
|
||||
|
||||
@@ -425,6 +425,7 @@ EOF;
|
||||
'add_only' => 'LINKSET_EDITMODE_ADDONLY',
|
||||
'actions' => 'LINKSET_EDITMODE_ACTIONS',
|
||||
'in_place' => 'LINKSET_EDITMODE_INPLACE',
|
||||
'add_remove' => 'LINKSET_EDITMODE_ADDREMOVE',
|
||||
);
|
||||
|
||||
if (!array_key_exists($sEditMode, $aXmlToPHP))
|
||||
|
||||
Reference in New Issue
Block a user