Optimization: do not load the full set of items when it comes to displaying an autocomplete!

SVN:trunk[1275]
This commit is contained in:
Romain Quetiez
2011-06-08 13:30:56 +00:00
parent 64b4922499
commit a0900cd732
7 changed files with 123 additions and 71 deletions

View File

@@ -1156,47 +1156,49 @@ EOF
}
}
}
$aAllowedValues = MetaModel::GetAllowedValues_flt($sClassName, $sFilterCode, $aExtraParams);
if ($aAllowedValues != null)
{
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sFilterCode);
if ($oAttDef->IsExternalKey())
{
$iFieldSize = $oAttDef->GetMaxSize();
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
$oWidget = new UIExtKeyWidget($sFilterCode, $sClassName, $oAttDef->GetLabel(), $aAllowedValues, $sFilterValue, 'search_'.$sFilterCode, false, '', '', '');
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;";
$sHtml .= $oWidget->Display($oPage, $aExtraParams, true /* bSearchMode */);
}
else
{
//Enum field or external key, display a combo
$sValue = "<select name=\"$sFilterCode\">\n";
$sValue .= "<option value=\"\">".Dict::S('UI:SearchValue:Any')."</option>\n";
foreach($aAllowedValues as $key => $value)
{
if ($sFilterValue == $key)
{
$sSelected = ' selected';
}
else
{
$sSelected = '';
}
$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
}
$sValue .= "</select>\n";
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;$sValue\n";
}
unset($aExtraParams[$sFilterCode]);
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sFilterCode);
if ($oAttDef->IsExternalKey())
{
$sTargetClass = $oAttDef->GetTargetClass();
$oAllowedValues = new DBObjectSet(new DBObjectSearch($sTargetClass));
$iFieldSize = $oAttDef->GetMaxSize();
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
$oWidget = new UIExtKeyWidget($sFilterCode, $sClassName, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, 'search_'.$sFilterCode, false, '', '', '');
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;";
$sHtml .= $oWidget->Display($oPage, $aExtraParams, true /* bSearchMode */);
}
else
{
// Any value is possible, display an input box
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;<input class=\"textSearch\" name=\"$sFilterCode\" value=\"$sFilterValue\"/>\n";
unset($aExtraParams[$sFilterCode]);
$aAllowedValues = MetaModel::GetAllowedValues_flt($sClassName, $sFilterCode, $aExtraParams);
if (is_null($aAllowedValues))
{
// Any value is possible, display an input box
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;<input class=\"textSearch\" name=\"$sFilterCode\" value=\"$sFilterValue\"/>\n";
}
else
{
//Enum field, display a combo
$sValue = "<select name=\"$sFilterCode\">\n";
$sValue .= "<option value=\"\">".Dict::S('UI:SearchValue:Any')."</option>\n";
foreach($aAllowedValues as $key => $value)
{
if ($sFilterValue == $key)
{
$sSelected = ' selected';
}
else
{
$sSelected = '';
}
$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
}
$sValue .= "</select>\n";
$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;$sValue\n";
}
}
unset($aExtraParams[$sFilterCode]);
$index++;
$sHtml .= '</span> ';
}
@@ -1406,10 +1408,10 @@ EOF
$aEventsList[] ='validate';
$aEventsList[] ='change';
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
$iFieldSize = $oAttDef->GetMaxSize();
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, $oAttDef->GetLabel(), $aAllowedValues, $value, $iId, $bMandatory, $sNameSuffix, $sFieldPrefix, $sFormPrefix);
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $value, $iId, $bMandatory, $sNameSuffix, $sFieldPrefix, $sFormPrefix);
$sHTMLValue = $oWidget->Display($oPage, $aArgs);
$sHTMLValue .= "<!-- iFlags: $iFlags bMandatory: $bMandatory -->\n";
break;
@@ -1777,20 +1779,36 @@ EOF
// Now fill-in the fields with default/supplied values
foreach($aList as $sAttCode)
{
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
if (isset($aArgs['default'][$sAttCode]))
{
$oObj->Set($sAttCode, $aArgs['default'][$sAttCode]);
}
elseif (count($aAllowedValues) == 1)
else
{
// If the field is mandatory, set it to the only possible value
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
// If the field is mandatory, set it to the only possible value
$iFlags = $oObj->GetAttributeFlags($sAttCode);
if ( (!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY))
if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY))
{
$aValues = array_keys($aAllowedValues);
$oObj->Set($sAttCode, $aValues[0]);
if ($oAttDef->IsExternalKey())
{
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
if ($oAllowedValues->Count() == 1)
{
$oRemoteObj = $oAllowedValues->Fetch();
$oObj->Set($sAttCode, $oRemoteObj->GetKey());
}
}
else
{
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
if (count($aAllowedValues) == 1)
{
$aValues = array_keys($aAllowedValues);
$oObj->Set($sAttCode, $aValues[0]);
}
}
}
}
}

View File

@@ -68,8 +68,10 @@ class UIExtKeyWidget
protected $sNameSuffix;
protected $iId;
protected $sTitle;
protected $oAllowedValues = null;
public function __construct($sAttCode, $sClass, $sTitle, $aAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
{
self::$iWidgetIndex++;
$this->sAttCode = $sAttCode;
@@ -77,7 +79,7 @@ class UIExtKeyWidget
$this->oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$this->sNameSuffix = $sNameSuffix;
$this->iId = $iInputId;
$this->aAllowedValues = $aAllowedValues;
$this->oAllowedValues = $oAllowedValues;
$this->value = $value;
$this->sFieldPrefix = $sFieldPrefix;
$this->sTargetClass = $this->oAttDef->GetTargetClass();
@@ -110,7 +112,11 @@ class UIExtKeyWidget
{
$sWizHelper = 'oWizardHelper'.$this->sFormPrefix;
}
if (count($this->aAllowedValues) < $this->oAttDef->GetMaximumComboLength())
if (is_null($this->oAllowedValues))
{
throw new Exception('Implementation: null value for allowed values definition');
}
elseif ($this->oAllowedValues->Count() < $this->oAttDef->GetMaximumComboLength())
{
// Few choices, use a normal 'select'
$sSelectMode = 'true';
@@ -127,9 +133,13 @@ class UIExtKeyWidget
{
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
}
foreach($this->aAllowedValues as $key => $display_value)
$this->oAllowedValues->Rewind();
while($oObj = $this->oAllowedValues->Fetch())
{
if ((count($this->aAllowedValues) == 1) && ($this->bMandatory == 'true') )
$key = $oObj->GetKey();
$display_value = $oObj->Get('friendlyname');
if (($this->oAllowedValues->Count() == 1) && ($this->bMandatory == 'true') )
{
// When there is only once choice, select it by default
$sSelected = ' selected';
@@ -168,7 +178,7 @@ EOF
$iFieldSize = $this->oAttDef->GetMaxSize();
// the input for the auto-complete
$sHTMLValue = "<input count=\"".count($this->aAllowedValues)."\" type=\"text\" id=\"label_$this->iId\" size=\"30\" maxlength=\"$iFieldSize\" value=\"$sDisplayValue\"/>&nbsp;";
$sHTMLValue = "<input count=\"".$this->oAllowedValues->Count()."\" type=\"text\" id=\"label_$this->iId\" size=\"30\" maxlength=\"$iFieldSize\" value=\"$sDisplayValue\"/>&nbsp;";
$sHTMLValue .= "<a class=\"no-arrow\" href=\"javascript:oACWidget_{$this->iId}.Search();\"><img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;\" src=\"../images/mini_search.gif\" /></a>&nbsp;";
// another hidden input to store & pass the object's Id
@@ -236,19 +246,11 @@ EOF
*/
public function SearchObjectsToSelect(WebPage $oP, $sTargetClass = '')
{
if ($sTargetClass != '')
if (is_null($this->oAllowedValues))
{
// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
$oFilter = new DBObjectSearch($sTargetClass);
throw new Exception('Implementation: null value for allowed values definition');
}
else
{
// No remote class specified use the one defined in the linkedset
$oFilter = new DBObjectSearch($this->sTargetClass);
}
$oFilter->AddCondition('id', array_keys($this->aAllowedValues), 'IN');
$oSet = new CMDBObjectSet($oFilter);
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock = new DisplayBlock($this->oAllowedValues->GetFilter(), 'list', false);
$oBlock->Display($oP, $this->iId, array('menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results
}

View File

@@ -2339,6 +2339,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
public function GetAllowedValues($aArgs = array(), $sContains = '')
{
//throw new Exception("GetAllowedValues on ext key has been deprecated");
try
{
return parent::GetAllowedValues($aArgs, $sContains);
@@ -2351,6 +2352,13 @@ class AttributeExternalKey extends AttributeDBFieldVoid
}
}
public function GetAllowedValuesAsObjectSet($aArgs = array(), $sContains = '')
{
$oValSetDef = $this->GetValuesDef();
$oSet = $oValSetDef->ToObjectSet($aArgs, $sContains);
return $oSet;
}
public function GetDeletionPropagationOption()
{
return $this->Get("on_target_delete");

View File

@@ -353,7 +353,10 @@ class DBObjectSet
public function Rewind()
{
$this->Seek(0);
if ($this->m_bLoaded)
{
$this->Seek(0);
}
}
public function Seek($iRow)

View File

@@ -1024,6 +1024,11 @@ abstract class MetaModel
return $oFltDef->GetAllowedValues($aArgs, $sContains);
}
public static function GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs = array(), $sContains = '')
{
$oAttDef = self::GetAttributeDef($sClass, $sAttCode);
return $oAttDef->GetAllowedValuesAsObjectSet($aArgs, $sContains);
}
//
// Businezz model declaration verbs (should be static)
//

View File

@@ -101,6 +101,22 @@ class ValueSetObjects extends ValueSetDefinition
$this->m_bAllowAllData = $bAllowAllData;
}
public function ToObjectSet($aArgs = array(), $sContains = '')
{
if ($this->m_bAllowAllData)
{
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
}
else
{
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
}
return new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
}
protected function LoadValues($aArgs)
{
$this->m_aValues = array();

View File

@@ -91,8 +91,8 @@ try
$oObj = null;
$currentValue = '';
}
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $currentValue, $iInputId, false, $sSuffix, '');
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $currentValue, $iInputId, false, $sSuffix, '');
$oWidget->SearchObjectsToSelect($oPage, $sTargetClass);
break;
@@ -105,8 +105,8 @@ try
$sValue = utils::ReadParam('sValue', '');
//$oWizardHelper = WizardHelper::FromJSON($sJson);
//$oObj = $oWizardHelper->GetTargetObject();
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array() /*array('this' => $oObj)*/);
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $sValue, $iInputId, false, $sSuffix, '');
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array() /*array('this' => $oObj)*/);
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $sValue, $iInputId, false, $sSuffix, '');
$oWidget->GetSearchDialog($oPage);
break;
@@ -119,8 +119,8 @@ try
$sJson = utils::ReadParam('json', '');
$oWizardHelper = WizardHelper::FromJSON($sJson);
$oObj = $oWizardHelper->GetTargetObject();
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $oObj->Get($sAttCode), $iInputId, false, $sSuffix, '');
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $oObj->Get($sAttCode), $iInputId, false, $sSuffix, '');
$oWidget->GetObjectCreationForm($oPage);
break;
@@ -133,9 +133,9 @@ try
$sJson = utils::ReadParam('json', '');
$oWizardHelper = WizardHelper::FromJSON($sJson);
$oObj = $oWizardHelper->GetTargetObject();
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
// The iInputId of the autocomplete is the prefix for the form used to create the target object
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, null, $iInputId, false, $sSuffix, $oWizardHelper->GetFormPrefix());
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, null, $iInputId, false, $sSuffix, $oWizardHelper->GetFormPrefix());
$aResult = $oWidget->DoCreateObject($oPage);
echo json_encode($aResult);
break;
@@ -147,7 +147,7 @@ try
$iInputId = utils::ReadParam('iInputId', '');
$iObjectId = utils::ReadParam('iObjectId', '');
$sSuffix = utils::ReadParam('sSuffix', '');
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', array(), '', $iInputId, $sSuffix, '');
$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', null, '', $iInputId, $sSuffix, '');
$sName = $oWidget->GetObjectName($iObjectId);
echo json_encode(array('name' => $sName));
break;