Bug fix: apply the AllowedValues constraints(as default values) when selecting elements via the "magnifier" button or creating an new element via the "plus" button.

SVN:trunk[1714]
This commit is contained in:
Denis Flaven
2011-12-13 14:37:31 +00:00
parent 487aa95ae2
commit ec19ef982e
8 changed files with 222 additions and 22 deletions

View File

@@ -1445,12 +1445,14 @@ EOF
$aMapCriteria[$aCriteria['filtercode']][] = array('value' => $aCriteria['value'], 'opcode' => $aCriteria['opcode']);
}
$aList = MetaModel::GetZListItems($sClassName, 'standard_search');
$aConsts = $oSet->ListConstantFields(); // Some fields are constants based on the query/context
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
foreach($aList as $sFilterCode)
{
//$oAppContext->Reset($sFilterCode); // Make sure the same parameter will not be passed twice
$sHtml .= '<span style="white-space: nowrap;padding:5px;display:inline-block;">';
$sFilterValue = '';
$sFilterValue = utils::ReadParam($sFilterCode, '', false, 'raw_data');
$sFilterValue = isset($aConsts[$sClassAlias][$sFilterCode]) ? $aConsts[$sClassAlias][$sFilterCode] : '';
$sFilterValue = utils::ReadParam($sFilterCode, $sFilterValue, false, 'raw_data');
$sFilterOpCode = null; // Use the default 'loose' OpCode
if (empty($sFilterValue))
{

View File

@@ -65,6 +65,7 @@ class UIExtKeyWidget
{
protected $iId;
protected $sTargetClass;
protected $sAttCode;
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
static public function DisplayFromAttCode($oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '', $aArgs, $bSearchMode = false)
@@ -81,14 +82,15 @@ class UIExtKeyWidget
{
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
}
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId);
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode);
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, $bSearchMode, $sDisplayStyle);
}
public function __construct($sTargetClass, $iInputId)
public function __construct($sTargetClass, $iInputId, $sAttCode = '')
{
$this->sTargetClass = $sTargetClass;
$this->iId = $iInputId;
$this->sAttCode = $sAttCode;
}
/**
@@ -182,7 +184,7 @@ class UIExtKeyWidget
$sHTMLValue .= "</select>\n";
$oPage->add_ready_script(
<<<EOF
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper);
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}');
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
@@ -217,7 +219,7 @@ EOF
// Scripts to start the autocomplete and bind some events to it
$oPage->add_ready_script(
<<<EOF
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper);
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}');
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
$('#label_$this->iId').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'$sFilter', json: function() { return $sWizHelperJSON; } }});
$('#label_$this->iId').keyup(function() { if ($(this).val() == '') { $('#$this->iId').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly !
@@ -262,13 +264,24 @@ EOF
return $sHTMLValue;
}
public function GetSearchDialog(WebPage $oPage, $sTitle)
public function GetSearchDialog(WebPage $oPage, $sTitle, $oCurrObject = null)
{
$sHTML = '<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">';
$oFilter = new DBObjectSearch($this->sTargetClass);
$oSet = new CMDBObjectSet($oFilter);
$oBlock = new DisplayBlock($oFilter, 'search', false);
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
$aParams = array('query_params' => array('this' => $oCurrObject));
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
$oFilter = $oSet->GetFilter();
}
else
{
$aParam = array();
$oFilter = new DBObjectSearch($this->sTargetClass);
$oSet = new CMDBObjectSet($oFilter);
}
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
$sHTML .= $oBlock->GetDisplay($oPage, $this->iId, array('open' => true, 'currentId' => $this->iId));
$sHTML .= "<form id=\"fr_{$this->iId}\" OnSubmit=\"return oACWidget_{$this->iId}.DoOk();\">\n";
$sHTML .= "<div id=\"dr_{$this->iId}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
@@ -353,7 +366,7 @@ EOF
/**
* Get the form to create a new object of the 'target' class
*/
public function GetObjectCreationForm(WebPage $oPage)
public function GetObjectCreationForm(WebPage $oPage, $oCurrObject)
{
// Set all the default values in an object and clone this "default" object
$oNewObj = MetaModel::NewObject($this->sTargetClass);
@@ -362,7 +375,24 @@ EOF
$oAppContext = new ApplicationContext();
$oAppContext->InitObjectFromContext($oNewObj);
// 2nd - set values from the page argument 'default'
// 2nd set the default values from the constraint on the external key... if any
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
$aParams = array('this' => $oCurrObject);
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aParams);
$aConsts = $oSet->ListConstantFields();
$sClassAlias = $oSet->GetFilter()->GetClassAlias();
if (isset($aConsts[$sClassAlias]))
{
foreach($aConsts[$sClassAlias] as $sAttCode => $value)
{
$oNewObj->Set($sAttCode, $value);
}
}
}
// 3rd - set values from the page argument 'default'
$oNewObj->UpdateObjectFromArg('default');
$sDialogTitle = addslashes($this->sTitle);

View File

@@ -742,6 +742,11 @@ class DBObjectSearch
return $this->m_aParams;
}
public function ListConstantFields()
{
return $this->m_oSearchCondition->ListConstantFields();
}
public function RenderCondition()
{
return $this->m_oSearchCondition->Render($this->m_aParams, false);

View File

@@ -687,6 +687,45 @@ class DBObjectSet
$this->Rewind();
return $oCommonObj;
}
/**
* List the constant fields (and their value) in the given query
* @return Hash [Alias][AttCode] => value
*/
public function ListConstantFields()
{
$aScalarArgs = array();
foreach($this->m_aArgs as $sArgName => $value)
{
if (MetaModel::IsValidObject($value))
{
$aScalarArgs = array_merge($aScalarArgs, $value->ToArgs($sArgName));
}
else
{
$aScalarArgs[$sArgName] = (string) $value;
}
}
$aScalarArgs['current_contact_id'] = UserRights::GetContactId();
$aConst = $this->m_oFilter->ListConstantFields();
foreach($aConst as $sClassAlias => $aVals)
{
foreach($aVals as $sCode => $oExpr)
{
if ($oExpr instanceof ScalarExpression)
{
$aConst[$sClassAlias][$sCode] = $oExpr->GetValue();
}
else //Variable
{
$aConst[$sClassAlias][$sCode] = $aScalarArgs[$oExpr->GetName()];
}
}
}
return $aConst;
}
}
/**

View File

@@ -40,7 +40,10 @@ abstract class Expression
abstract public function ListRequiredFields();
abstract public function IsTrue();
// recursively builds an array of [classAlias][fieldName] => value
abstract public function ListConstantFields();
public function RequiresField($sClass, $sFieldName)
{
// #@# todo - optimize : this is called quite often when building a single query !
@@ -122,6 +125,11 @@ class SQLExpression extends Expression
return array();
}
public function ListConstantFields()
{
return array();
}
public function RenameParam($sOldName, $sNewName)
{
// Do nothing, since there is nothing to rename
@@ -164,11 +172,11 @@ class BinaryExpression extends Expression
// return true if we are certain that it will be true
if ($this->m_sOperator == 'AND')
{
if ($this->m_oLeftExpr->IsTrue() && $this->m_oLeftExpr->IsTrue()) return true;
if ($this->m_oLeftExpr->IsTrue() && $this->m_oRightExpr->IsTrue()) return true;
}
return false;
}
public function GetLeftExpr()
{
return $this->m_oLeftExpr;
@@ -213,6 +221,36 @@ class BinaryExpression extends Expression
return array_merge($aLeft, $aRight);
}
/**
* List all constant expression of the form <field> = <scalar> or <field> = :<variable>
* Could be extended to support <field> = <function><constant_expression>
*/
public function ListConstantFields()
{
$aResult = array();
if ($this->m_sOperator == '=')
{
if (($this->m_oLeftExpr instanceof FieldExpression) && ($this->m_oRightExpr instanceof ScalarExpression))
{
$aResult[$this->m_oLeftExpr->GetParent()][$this->m_oLeftExpr->GetName()] = $this->m_oRightExpr;
}
else if (($this->m_oRightExpr instanceof FieldExpression) && ($this->m_oLeftExpr instanceof ScalarExpression))
{
$aResult[$this->m_oRightExpr->GetParent()][$this->m_oRightExpr->GetName()] = $this->m_oLeftExpr;
}
else if (($this->m_oLeftExpr instanceof FieldExpression) && ($this->m_oRightExpr instanceof VariableExpression))
{
$aResult[$this->m_oLeftExpr->GetParent()][$this->m_oLeftExpr->GetName()] = $this->m_oRightExpr;
}
else if (($this->m_oRightExpr instanceof FieldExpression) && ($this->m_oLeftExpr instanceof VariableExpression))
{
$aResult[$this->m_oRightExpr->GetParent()][$this->m_oRightExpr->GetName()] = $this->m_oLeftExpr;
}
}
return $aResult;
}
public function RenameParam($sOldName, $sNewName)
{
$this->GetLeftExpr()->RenameParam($sOldName, $sNewName);
@@ -269,6 +307,11 @@ class UnaryExpression extends Expression
{
return array();
}
public function ListConstantFields()
{
return array();
}
public function RenameParam($sOldName, $sNewName)
{
@@ -529,6 +572,16 @@ class ListExpression extends Expression
return $aRes;
}
public function ListConstantFields()
{
$aRes = array();
foreach ($this->m_aExpressions as $oExpr)
{
$aRes = array_merge($aRes, $oExpr->ListConstantFields());
}
return $aRes;
}
public function RenameParam($sOldName, $sNewName)
{
$aRes = array();
@@ -606,6 +659,16 @@ class FunctionExpression extends Expression
return $aRes;
}
public function ListConstantFields()
{
$aRes = array();
foreach ($this->m_aArgs as $oExpr)
{
$aRes = array_merge($aRes, $oExpr->ListConstantFields());
}
return $aRes;
}
public function RenameParam($sOldName, $sNewName)
{
foreach ($this->m_aArgs as $key => $oExpr)
@@ -662,6 +725,11 @@ class IntervalExpression extends Expression
{
return array();
}
public function ListConstantFields()
{
return array();
}
public function RenameParam($sOldName, $sNewName)
{
@@ -730,6 +798,16 @@ class CharConcatExpression extends Expression
return $aRes;
}
public function ListConstantFields()
{
$aRes = array();
foreach ($this->m_aExpressions as $oExpr)
{
$aRes = array_merge($aRes, $oExpr->ListConstantFields());
}
return $aRes;
}
public function RenameParam($sOldName, $sNewName)
{
foreach ($this->m_aExpressions as $key => $oExpr)

View File

@@ -716,6 +716,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:DisplayThisMessageAtStartup' => 'Afficher ce message au démarrage',
'UI:RelationshipGraph' => 'Vue graphique',
'UI:RelationshipList' => 'Liste',
'UI:ElementsDisplayed' => 'Eléments Affichés',
'UI:OperationCancelled' => 'Opération Annulée',
'Portal:Title' => 'Portail utilisateur iTop',
'Portal:Refresh' => 'Rafraîchir',

View File

@@ -13,12 +13,13 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper)
function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper, sAttCode)
{
this.id = id;
this.sTargetClass = sTargetClass;
this.sFilter = sFilter;
this.sTitle = sTitle;
this.sAttCode = sAttCode;
this.emptyHtml = ''; // content to be displayed when the search results are empty (when opening the dialog)
this.emptyOnClose = true; // Workaround for the JQuery dialog being very slow when opening and closing if the content contains many INPUT tags
this.oWizardHelper = oWizHelper;
@@ -61,10 +62,22 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
var theMap = { sAttCode: me.sAttCode,
iInputId: me.id,
sTitle: me.sTitle,
sAttCode: me.sAttCode,
sTargetClass: me.sTargetClass,
operation: 'objectSearchForm'
}
if (me.oWizardHelper == null)
{
theMap['json'] = '';
}
else
{
// Not inside a "search form", updating a real object
me.oWizardHelper.UpdateWizard();
theMap['json'] = me.oWizardHelper.ToJSON();
}
// Make sure that we cancel any pending request before issuing another
// since responses may arrive in arbitrary order
me.StopPendingRequest();
@@ -152,6 +165,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
theMap['sRemoteClass'] = theMap['class']; // swap 'class' (defined in the form) and 'remoteClass'
theMap.operation = 'searchObjectsToSelect'; // Override what is defined in the form itself
theMap.sAttCode = me.sAttCode,
sSearchAreaId = '#dr_'+me.id;
//$(sSearchAreaId).html('<div style="text-align:center;width:100%;height:24px;vertical-align:middle;"><img src="../images/indicator.gif" /></div>');
@@ -200,6 +214,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
var theMap = { sTargetClass: me.sTargetClass,
iInputId: me.id,
iObjectId: iObjectId,
sAttCode: me.sAttCode,
operation: 'getObjectName'
}
@@ -262,6 +277,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
me.oWizardHelper.UpdateWizard();
var theMap = { sTargetClass: me.sTargetClass,
iInputId: me.id,
sAttCode: me.sAttCode,
'json': me.oWizardHelper.ToJSON(),
operation: 'objectCreationForm'
}
@@ -323,6 +339,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
$('#'+sFormId).block();
var theMap = { sTargetClass: me.sTargetClass,
iInputId: me.id,
sAttCode: me.sAttCode,
'json': me.oWizardHelper.ToJSON()
}
@@ -403,6 +420,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
var theMap = { sTargetClass: me.sTargetClass,
sInputId: me.id,
sFilter: me.sFilter,
sAttCode: me.sAttCode,
value: $('#'+me.id).val()
};
@@ -484,6 +502,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
var theMap = { sTargetClass: me.sTargetClass,
iInputId: me.id,
iObjectId: iObjectId,
sAttCode: me.sAttCode,
operation: 'getObjectName'
}

View File

@@ -192,6 +192,7 @@ try
$sRemoteClass = utils::ReadParam('sRemoteClass', '', false, 'class');
$sFilter = utils::ReadParam('sFilter', '', false, 'raw_data');
$sJson = utils::ReadParam('json', '', false, 'raw_data');
$sAttCode = utils::ReadParam('sAttCode', '');
if (!empty($sJson))
{
$oWizardHelper = WizardHelper::FromJSON($sJson);
@@ -202,7 +203,7 @@ try
// Search form: no current object
$oObj = null;
}
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId);
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode);
$oWidget->SearchObjectsToSelect($oPage, $sFilter, $sRemoteClass, $oObj);
break;
@@ -233,16 +234,40 @@ try
$sTargetClass = utils::ReadParam('sTargetClass', '', false, 'class');
$iInputId = utils::ReadParam('iInputId', '');
$sTitle = utils::ReadParam('sTitle', '', false, 'raw_data');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId);
$oWidget->GetSearchDialog($oPage, $sTitle);
$sAttCode = utils::ReadParam('sAttCode', '');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode);
$sJson = utils::ReadParam('json', '', false, 'raw_data');
if (!empty($sJson))
{
$oWizardHelper = WizardHelper::FromJSON($sJson);
$oObj = $oWizardHelper->GetTargetObject();
}
else
{
// Search form: no current object
$oObj = null;
}
$oWidget->GetSearchDialog($oPage, $sTitle, $oObj);
break;
// ui.extkeywidget
case 'objectCreationForm':
$sTargetClass = utils::ReadParam('sTargetClass', '', false, 'class');
$iInputId = utils::ReadParam('iInputId', '');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId);
$oWidget->GetObjectCreationForm($oPage);
$sAttCode = utils::ReadParam('sAttCode', '');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode);
$sJson = utils::ReadParam('json', '', false, 'raw_data');
if (!empty($sJson))
{
$oWizardHelper = WizardHelper::FromJSON($sJson);
$oObj = $oWizardHelper->GetTargetObject();
}
else
{
// Search form: no current object
$oObj = null;
}
$oWidget->GetObjectCreationForm($oPage, $oObj);
break;
// ui.extkeywidget
@@ -250,7 +275,8 @@ try
$sTargetClass = utils::ReadParam('sTargetClass', '', false, 'class');
$iInputId = utils::ReadParam('iInputId', '');
$sFormPrefix = utils::ReadParam('sFormPrefix', '');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId);
$sAttCode = utils::ReadParam('sAttCode', '');
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode);
$aResult = $oWidget->DoCreateObject($oPage);
echo json_encode($aResult);
break;