2284 - Replace JQuery Autocompleter plugin by JQuery UI Autocomplete widget - fix autocomplete on short lists, tab and autoselect item when there is only one option

This commit is contained in:
acognet
2021-01-26 17:20:42 +01:00
parent c65a760de7
commit d39d634aba
3 changed files with 117 additions and 69 deletions

View File

@@ -138,7 +138,7 @@ class UIExtKeyWidget
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper\" data-validation=\"untouched\">";
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey ibo-input-wrapper ibo-input-select-wrapper\" data-validation=\"untouched\" tabindex=0>";
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
if($this->bSearchMode)
{
@@ -257,6 +257,7 @@ $('#$this->iId').attr('data-validate','dependencies');
EOF
);
}
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
}
else
{
@@ -282,8 +283,6 @@ EOF
// the input for the auto-complete
$sHTMLValue .= "<input class=\"field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div>";
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--clear\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\"><i class=\"fas fa-times\"></i></div>";
// another hidden input to store & pass the object's Id
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
@@ -301,10 +300,15 @@ EOF
}
EOF
);
$sHTMLValue .= "<div class=\"ibo-input-select--action-buttons\">";
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--search\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div>";
$sHTMLValue .= " <div class=\"ibo-input-select--action-button ibo-input-select--action-button--clear\" id=\"mini_clear_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Clear();\"><i class=\"fas fa-times\"></i></div>";
}
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
{
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div>";
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--hierarchy\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div>";
$oPage->add_ready_script(
<<<JS
if ($('#ac_tree_{$this->iId}').length == 0)
@@ -318,7 +322,7 @@ JS
{
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
$sHTMLValue .= "<div class=\"field_input_btn ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div>";
$sHTMLValue .= "<div class=\"ibo-input-select--action-button ibo-input-select--action-button--create\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div>";
$oPage->add_ready_script(
<<<JS
if ($('#ajax_{$this->iId}').length == 0)
@@ -329,6 +333,7 @@ JS
);
}
$sHTMLValue .= "</div>";
$sHTMLValue .= "</div>";
$sHTMLValue .= "<span class=\"form_validation ibo-field-validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
return $sHTMLValue;

View File

@@ -13,29 +13,30 @@ $ibo-input-select-wrapper--after--color: $ibo-color-grey-900 !default;
$ibo-input-select--action-button--height: 28px !default;
$ibo-input-select--action-button--width: 23px !default;
$ibo-input-select--action-button--margin-top: 1px !default;
$ibo-input-select--action-button--margin-right: 20px !default;
$ibo-input-select--action-button--background-color: inherit !default;
$ibo-input-select--action-button--color: $ibo-color-grey-800 !default;
$ibo-input-select--action-button--padding-x: 4px !default;
$ibo-input-select--action-button--padding-y: 5px !default;
$ibo-input-select--action-button--padding-x: 2px !default;
$ibo-input-select--action-button--padding-y: 6px !default;
$ibo-input-select--action-button--hierarchy--margin-left: -60px !default;
$ibo-input-select--action-button--create--margin-left: -38px !default;
$ibo-input-select--action-button--search--margin-left: -60px !default;
$ibo-input-select--action-button--clear--margin-left: -72px !default;
$ibo-input-select-autocomplete-action-button--hierarchy--margin-left: -92px !default;
$ibo-input-select--action-button--padding-left: 5px !default;
.ibo-input-select{
appearance: none;
display: inline-block;
&.ibo-input-selectize{
padding-right:0;
padding-left:0;
input{
display: none;
border-width: 0px;
border-color: white;
padding-left:$ibo-input--padding-x;
}
>[data-value]
{
height: $ibo-input-select-selectize--value--height;
line-height: $ibo-input-select-selectize--value--line-height;
padding-left:$ibo-input--padding-x;
}
}
}
@@ -63,33 +64,24 @@ $ibo-input-select-autocomplete-action-button--hierarchy--margin-left: -92px !def
color: $ibo-input-select-wrapper--after--color;
pointer-events: none;
}
.ibo-input-select--action-button{
position: absolute;
display: inline-block;
height: $ibo-input-select--action-button--height;
width: $ibo-input-select--action-button--width;
margin-top: $ibo-input-select--action-button--margin-top;
font-size: $ibo-font-size-100;
background-color: $ibo-input-select--action-button--background-color;
color: $ibo-input-select--action-button--color;
padding: $ibo-input-select--action-button--padding-y $ibo-input-select--action-button--padding-x;
&.ibo-input-select--action-button--hierarchy{
margin-left: $ibo-input-select--action-button--hierarchy--margin-left;
}
&.ibo-input-select--action-button--create{
margin-left: $ibo-input-select--action-button--create--margin-left;
}
&.ibo-input-select--action-button--search{
margin-left: $ibo-input-select--action-button--search--margin-left;
}
&.ibo-input-select--action-button--clear{
margin-left: $ibo-input-select--action-button--clear--margin-left;
}
.ibo-input-select--action-buttons{
position: absolute;
display: initial;
height: $ibo-input-select--action-button--height;
margin-top: $ibo-input-select--action-button--margin-top;
margin-right: $ibo-input-select--action-button--margin-right;
font-size: $ibo-font-size-100;
background-color: $ibo-input-select--action-button--background-color;
color: $ibo-input-select--action-button--color;
padding: $ibo-input-select--action-button--padding-y $ibo-input-select--action-button--padding-x;
text-align: right;
right:0;
}
.ibo-input-select-autocomplete ~ .ibo-input-select--action-button--hierarchy{
margin-left: $ibo-input-select-autocomplete-action-button--hierarchy--margin-left;
.ibo-input-select--action-button{
padding-left: $ibo-input-select--action-button--padding-left;
float:right;
}
.selectize-dropdown{
@@ -100,3 +92,14 @@ $ibo-input-select-autocomplete-action-button--hierarchy--margin-left: -92px !def
background-color: #f5fafd;
color: #495c68;
}
//from jqueryui.css
.ui-helper-hidden-accessible {
// border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}

View File

@@ -15,6 +15,46 @@
*
* You should have received a copy of the GNU Affero General Public License
*/
var KEY_BACKSPACE = 8;
var KEY_RETURN = 13;
Selectize.define('custom_itop', function(options) {
var self = this;
options.text = options.text || function(option) {
return option[this.settings.labelField];
};
this.onKeyDown = (function() {
var original = self.onKeyDown;
return function(e) {
var index, option;
switch (e.keyCode) {
case KEY_BACKSPACE:
if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) {
index = this.caretPos-1;
if (index >= 0 && index < this.items.length) {
this.clear(true);
e.preventDefault();
return;
}
}
case KEY_RETURN:
if (self.isOpen) {
//case nothing selected ->delete selection
if (!self.$activeOption || self.currentResults.query == "") {
self.deleteSelection(e);
//if(self.getOption("") != "undefined"){
self.setValue("");
//}
return;
}
}
}
return original.apply(this, arguments);
};
})();
});
function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper, sAttCode, bSearchMode, bDoSearch, sFormAttCode) {
this.id = id;
@@ -40,43 +80,43 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
$('#'+this.id+'_linksToRemove').val('');
}
this.AddSelectize = function (options, initValue) {
$('#'+me.id).selectize({
let $select = $('#'+me.id).selectize({
plugins:['custom_itop'],
render: {
item: function (item) {
if (item.obsolescence_flag == 1) {
val = '<span class="object-ref-icon fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>'+item.label;
} else {
val = item.label;
}
return $("<div>")
.append(val);
},
option: function(item) {
if ( item.obsolescence_flag == 1)
{
val = '<span class="object-ref-icon fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>'+item.label;
}
else
{
val = item.label;
}
if (item.additional_field != undefined )
{
val = val+'<br><i>'+item.additional_field+'</i>';
}
return $("<div>")
.append(val);
}
return $("<div>").append(val);
},
items:[initValue],
valueField: 'value',
labelField: 'label',
searchField: ['value'],
options:JSON.parse(options),
maxItems: 1,
copyClassesToDropdown: false,
inputClass: 'ibo-input ibo-input-select ibo-input-selectize'
});
option: function(item) {
if ( item.obsolescence_flag == 1)
{
val = '<span class="object-ref-icon fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>'+item.label;
}
else
{
val = item.label;
}
if (item.additional_field != undefined )
{
val = val+'<br><i>'+item.additional_field+'</i>';
}
return $("<div>").append(val);
}
},
valueField: 'value',
labelField: 'label',
searchField: 'label',
options:JSON.parse(options),
maxItems: 1,
copyClassesToDropdown: false,
inputClass: 'ibo-input ibo-input-select ibo-input-selectize',
});
let $selectize = $select[0].selectize; // This stores the selectize object to a variable (with name 'selectize')
$selectize.setValue(initValue, true);
}
this.AddAutocomplete = function(iMinChars, sWizHelperJSON)
{