-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Autocomplete improvement - replacing data (AJAX), arrows keys usage and more #3694
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good and work well. Tested on a local project.
Works well; adapted this in a commercial project. |
Also, I wanted a 'select' event for when the user clicks an entry in the autocomplete or presses enter. ('change' fires for every key) What are your thoughts on a 'select' event? See #3729 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good overall. I don't have time to test the code right now, but here are a few things I noticed scanning the code on GitHub.
js/forms.js
Outdated
}); | ||
|
||
// updating input value | ||
setIputValue($autocomplete, $input); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo. should be setInputValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
js/forms.js
Outdated
var data = options.data, | ||
$inputDiv = $input.closest('.input-field'); // Div to append on | ||
// Set input value | ||
function setIputValue(ulElement, inputElement) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why setIputValue instead of setInputValue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right I changed that.
var $input = $(this); | ||
var data = options.data, | ||
$inputDiv = $input.closest('.input-field'); // Div to append on | ||
// Set input value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JavaDoc doesn't give more information than already hinted by the name of the function.
Is inputElement the main $input? Why is the parameter needed? Can't you just use $input captured in the closure?
Why is this function needed? It's only used once in the code. I think just remove the function and put its body where the call on line 450 is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment maybe doesn't bring so much, but I do that because it's easier for me to read a code. Comments have different color and for me when I looking through the code it's like headers.
I separated that intentionally. First and less important I think right now it's just more readable. In one section you define functions - in different section you fired that.
But more important thing: if you move everything to one loop and have for example 100 autocomplete inputs, when you run this loop you will define all this function 100 times. Right now you will define functions only once and you can fire that 100 times. It's just about performance.
And you cannot move this code to line 450 because this function just will not work.
js/forms.js
Outdated
// highlight elements | ||
function highlight(string, $el) { | ||
var img = $el.find('img'); | ||
var matchStart = $el.text().toLowerCase().indexOf("" + string.toLowerCase() + ""), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason to add empty strings, it doesn't do anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a legacy after old code. I changed that and I'm hope so it's not a some kind of hack for old IE or something.
// prevent refreshing list on pressing ctrl, shif, alt, arrow, f1-f12, etc | ||
// helpful if we selected something using arrow and we press ctrl for example | ||
if( | ||
[9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 45, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123].indexOf(e.which) < 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphanumeric codes are probably in the same range. So probably better to do if(e.which > X && e.which < Y)
But I have no idea what X and Y should be. I started looking into the docs, but they don't mention numerical codes.
https://api.jquery.com/event.which/
https://www.w3.org/TR/uievents-code/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure about that, but if you could provide solution like that and it will work we can use that.
if (data.hasOwnProperty(key) && | ||
key.toLowerCase().indexOf(val) !== -1 && | ||
key.toLowerCase() !== val) { | ||
if (maxElementsAmount !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the code should establish that maxElementsAmount is a number before starting the for loop rather than checking if it is null here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... If you do that you can change:
if (maxElementsAmount !== null)
On something like this:
if (maxElementsAmountIsNumber === true)
I don't think it's a big change
js/forms.js
Outdated
function arrowUsage(e, $autocomplete) { | ||
// Capture up and down key | ||
if ( | ||
e.which === 38 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe save e.which in var since it's used a few times.
var keyCode = e.which;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
js/forms.js
Outdated
// arrow usage - on key down | ||
function arrowUsage(e, $autocomplete) { | ||
// Capture up and down key | ||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if statement line breaks and indenting look weird. (Not normal JavaScript style)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed that, but all programmers has own style and there isn't "the style" which you can use in each situation. It's about preferences. If we want to have the same style in each file we should configure task in "gulp watch" which will be reformating code after save. That's the only way to have the same style in the whole project if you have more than 2 programmers ;)
js/forms.js
Outdated
} | ||
|
||
// Check if data isn't empty and append autocomplete element if doesn't exist yet - run only once | ||
if( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if statement line breaks and indenting look weird. (Not normal JavaScript style)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
look above
position: static; | ||
position: absolute; | ||
|
||
& ~ .autocomplete-content, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CSS changes should be reviewed, but I don't have time to look at them now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just found one surplus line and deleted it but it doesn't change so much.
@arlowhite I added callback onSelect which you described in #3729 |
…wn event. It generated some issues for validation in some cases.
📢 📢 📢 Why things in this project never get merged? |
Hi,
aoutocomplete in official version doesn't have a lot of crucial features so I decided to add:
-up and down arrows usage
-replacing data for autocomplete list - for instance for AJAX request
-if auto complete list is visible and you will make focusout action from input field, whole list disapper. I think in most cases we don't want to display this list if we do something else. It's rather bug than feature.
-when you write something in auto complete field and press "Esc" button whole list will disappear
-whole content after autocomplete list go down when list is visible. I changed list position on absolute and now it doesn't affect other elements
-in my opinion this list is sometimes too long - for example if we have 100 elements. Because of that, I decided to extend default object and add "maxElementsAmount" option. If you set that for example on 5 during initialization, you will see only 5 elements from the top of this list. If you skip that, you will see all matching elements.
Please check that, if you have any questions or comments just write. I'm hope so we can marge that soon because I use that in my project ;)
Cheers,
Adam