diff --git a/application/ui.extkeywidget.class.inc.php b/application/ui.extkeywidget.class.inc.php index a162cc8c5..ad396c032 100644 --- a/application/ui.extkeywidget.class.inc.php +++ b/application/ui.extkeywidget.class.inc.php @@ -272,7 +272,7 @@ EOF $iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars(); // the input for the auto-complete - $sHTMLValue .= "iId\" value=\"$sDisplayValue\"/>"; + $sHTMLValue .= "iId\" value=\"$sDisplayValue\"/>"; $sHTMLValue .= "
iId}\" onClick=\"oACWidget_{$this->iId}.Search();\">
"; // another hidden input to store & pass the object's Id @@ -281,18 +281,53 @@ EOF $JSSearchMode = $this->bSearchMode ? 'true' : 'false'; // Scripts to start the autocomplete and bind some events to it $oPage->add_ready_script( -<<iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch); - oACWidget_{$this->iId}.emptyHtml = "

$sMessage

"; - $('#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',bSearchMode:$JSSearchMode, 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 ! - $('#label_$this->iId').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } ); - $('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } ); +<<iId').autocomplete({ + source: function( request, response ) { + $.post( { + url: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', + dataType: "json", + data: { + q:request.term, + operation:'ac_extkey', + sTargetClass:'{$this->sTargetClass}', + sFilter:'$sFilter', + bSearchMode:$JSSearchMode, + sOutputFormat:'json', + json: function() { return $sWizHelperJSON; } + }, + success: function( data ) { + response( data ); + } + } ); + }, + autoFocus: true, + minLength:{$iMinChars}, + select: function( event, ui ) { + $('#$this->iId').val( ui.item.value ); + $('#label_$this->iId').val( ui.item.label ); + $('#$this->iId').trigger('validate'); + $('#$this->iId').trigger('extkeychange'); + $('#$this->iId').trigger('change'); + return false; + } + }) + .autocomplete( "instance" )._renderItem = function( ul, item ) { + var term = this.term.replace("/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi", "\\$1"); + var val = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); + if (item.obsolete == 'yes'){ + val = val + ' old'; + } + return $( "
  • " ) + .append( val ) + .appendTo( ul ); + }; + if ($('#ac_dlg_{$this->iId}').length == 0) { $('body').append('
    '); } -EOF +JS ); } if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) @@ -441,10 +476,12 @@ EOF $iMax = 150; $oValuesSet->SetLimit($iMax); $oValuesSet->SetSort(false); + $aOrder = array('friendlyname'=>true); + $oValuesSet->SetOrderBy($aOrder); + $oValuesSet->SetSort(true); $oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode); $oValuesSet->SetLimit($iMax); - $aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains'); - asort($aValuesContains); + $aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with'); $aValues = array(); foreach($aValuesContains as $sKey => $sFriendlyName) { @@ -453,6 +490,24 @@ EOF $aValues[$sKey] = $sFriendlyName; } } + if (sizeof($aValuesContains) < $iMax) + { + $aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, + 'contains'); + //asort($aValuesContains); + $iSize=sizeof($aValuesContains); + foreach($aValuesContains as $sKey => $sFriendlyName) + { + if (!isset($aValues[$sKey])) + { + $aValues[$sKey] = $sFriendlyName; + if (++$iSize >= $iMax) + { + break; + } + } + } + } switch($sOutputFormat) { diff --git a/core/valuesetdef.class.inc.php b/core/valuesetdef.class.inc.php index 4e73d84c1..0299f5c1e 100644 --- a/core/valuesetdef.class.inc.php +++ b/core/valuesetdef.class.inc.php @@ -141,7 +141,10 @@ class ValueSetObjects extends ValueSetDefinition $this->m_oExtraCondition = $oFilter; $this->m_bIsLoaded = false; } - + public function SetOrderBy(array $aOrderBy) + { + $this->m_aOrderBy = $aOrderBy; + } public function ToObjectSet($aArgs = array(), $sContains = '', $iAdditionalValue = null) { if ($this->m_bAllowAllData) @@ -243,7 +246,7 @@ class ValueSetObjects extends ValueSetDefinition $oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname'); $aFields = $oExpression->ListRequiredFields(); $sClass = $oFilter->GetClass(); - foreach($aFields as $sField) + /*foreach($aFields as $sField) { $aFieldItems = explode('.', $sField); if ($aFieldItems[0] != $sClass) @@ -251,7 +254,7 @@ class ValueSetObjects extends ValueSetDefinition $sOperation = 'contains'; break; } - } + }*/ switch ($sOperation) { diff --git a/css/light-grey.scss b/css/light-grey.scss index ebfd7e7fd..c8e20e629 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -3903,4 +3903,52 @@ input:checked + .slider:before { } .ui-dialog .ui-dialog-content .treecontrol a { font-size: small; -} \ No newline at end of file +} +/*for autocomplete*/ +.ui-autocomplete { + padding: 0px; + border: 1px solid black; + background-color: white; + overflow: hidden; + z-index: 99999; + + ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; + } + + li.ui-menu-item { + margin: 0px; + padding: 2px 5px; + white-space: nowrap; + padding-right: 20px; /* Space for the scrollbar */ + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; + + &:nth-child(odd) { + background-color: #eee; + } + + &.ui-state-focus { + background-color: #0A246A; + border-color: #0A246A; + color: white; + } + } +}