tarekraafat / autocomplete.js Goto Github PK
View Code? Open in Web Editor NEWSimple autocomplete pure vanilla Javascript library.
Home Page: https://tarekraafat.github.io/autoComplete.js
License: Apache License 2.0
Simple autocomplete pure vanilla Javascript library.
Home Page: https://tarekraafat.github.io/autoComplete.js
License: Apache License 2.0
Greetings,
Is there a way to use localeCompare instead of match in order to include accented characters into the search?
is it possible to show an "empty" state search, for instance i'd be putting "recent searches", then when they start typing it swaps them out.
or even better yet, have a persistent list so I can have Recent and Results in the same box.
if this was possible, i'd be ecstatic
Hello Tarek,
Not too sure if it's an issue, but it's a bit annoying.
I have a few products on my website called "BASIC", but they get returned like "basic", I am not too sure why that happens, I've ran through your code, and i think it has something to do with line 216-221, where you do this:
var match = _this.search(inputValue, record[_this.data.key] || record); if (match) { resList.push({ match: match, source: record }); }
But I am really not sure.
Hi @TarekRaafat,
I use your last release (4.0.0) on a large data set (5358 elements) and my browser totally freeze π
According to your browser support it'll be awesome if you can wrap your search logic in a Promise and resolve when it's done, it'll avoid that side effect.
What do you think about that ?
Thanks again for your plugin π
Hi,
Thanks for that awesome plugin !
I would like to know what do you think about adding multi key
s when we use an array of Objects.
For example:
const data = [
{ label: 'test', code: '0123456789' },
{ label: 'test2', code: '9876543210' },
]
and key would be: [ 'label', 'code' ]
I'm sorry if it's not clear but do not hesitate to ask me more details
All systems
All browsers
All OS
when you have two values that are identical in your JSON data, the first one is always selected, even if you click on match that appears after the first one. for example, in the Demo site:
https://tarekraafat.github.io/autoComplete.js/demo/
you have two "food" items that have a value of "Sauce - Caesar Dressing". the cities value for those two items are "Palestina de los Altos" and "Kelasuri":
{
"food": "Sauce - Caesar Dressing",
"cities": "Palestina de los Altos",
"animals": "Monkey, vervet"
},
{
"food": "Sauce - Caesar Dressing",
"cities": "Kelasuri",
"animals": "Alligator, american"
},
when you start typing "Sauce" and you select the second listing for "Sauce - Caesar Dressing", the selection value should be the one where "cities" is equal to "Kelasuri". but that is not the case. the selection value is always "Palestina de los Altos".
we use this most excellent autoComplete.js library for selecting students for various forms. when you start typing "Smith", for example, 30 or so items/students are displayed. no matter which student you click on, it always selects the first one in the result set.
Hi,
Your setup script in the index.js is not transpiled in the es5 format.
It makes our websites unusable on IE just because of this little thing. It brokes every script anyway.
If some one as a fix for that, it would be great to post it there.
I'm not an expert using gulp/babel to solve this problem.
Thank you :)
Trying to compile with rollup
import * as autoComplete from '@tarekraafat/autocomplete.js/dist/js/autoComplete';
I get a warning:
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en#error-this-is-undefined
node_modules/@tarekraafat/autocomplete.js/dist/js/autoComplete.js
3: typeof define === 'function' && define.amd ? define(factory) :
4: (global.autoComplete = factory());
5: }(this, (function () { 'use strict';
^
6:
7: function _classCallCheck(instance, Constructor) {
and then a runtime error from the global.autocomplete...
Cannot set property "autoComplete" of undefined
in this context (global.autocomplete... line
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.autoComplete = factory());
}(undefined, (function () {
Hello, and congratulation on the amazing job!
Is it possible to use a .xml file as a source data for autocompletion?
Luca
Hi.
I have been reading your source code, and came across this line.
Could you, please, explain what does it do?
Do you know some hidden JS knowledge, or not? Because it seems, that this line doesn't do anything.
The CSS uses a selector based on the id "autoComplete". It makes it difficult to have multiple auto-completes on the same page (as they have the same id) and have them both styles in the default way.
https://github.com/TarekRaafat/autoComplete.js/blob/master/dist/css/autoComplete.css#L6
I think it might be helpful to be able to apply the CSS via classes, rather than the id.
Please Describe alternatives you've considered
I'm considering downloading the CSS and hosting my own copy.
When filtering autocomplete options, often one gets down to a small number of matches, after which point further filter string typing becomes undersirable. Using the provided demo data set, an example of more usable input would be to type "red snapper" (down-arrow) (finalize selection key TBD) to select "Red Snapper - Fillet, Skin On".
Hi there,
I want to use a fuzzy logic search algorithm to get the results to display instead of the built in search functionality. The way I imagine this working is that in the config, the Autocomplete has a key customSearchEngine
(or whatever makes sense) and then the value is a JS function that takes the query as an argument. The function must return an array of object results to display via Autocomplete.js's rendering functionality.
Is this something that's possible with Autocomplete.js as is now or possibly in the future?
Thanks so much for your feedback.
Hello @TarekRaafat,
I just checked out v5 using the CDN you provided, but I still get the same issue with it returning the same result 8 times.
Take a look at the screenshot below:
Thanks,
Nick.
https://github.com/TarekRaafat/autoComplete.js/blob/master/src/models/autoComplete.js#L337-L346
The promise here is resolving to an actual value, lets say Array, then erroring because that code is trying to run [].then(...)
I'm not quite clear on what the intention was with some of that, like this.dataStream = this.dataStream;
, but I think you can solve what you were trying to do with:
Promise.resolve(this.dataStream)
.then(response => {
this.dataStream = response;
exec(event);
})
The .resolve() will wrap whatever value in a promise, including another promise, so you can safely execute .then without checking for type.
eg, these should both work:
Promise.resolve([])
Promise.resolve(Promise.resolve())
Hi all, thanks for this great little library. It has come in really useful in our latest project.
How about the idea of implementing a set of 'fieldProcessors' which are able to pre-process the content of particular fields before such time as the actual search is done?
As an example, in our particular use case, the data source coming via ajax was a list of people, including a Name & Date of birth field, both of which to be used as keys. We wanted the user to be able to type in either a name or a date of birth and for the matches to come back accordingly. See an example of the data here:
[{
"Name": "Bob Monkhouse",
"Area": "Live Case",
"DOB": "1932-02-19T00:00:00",
"URL": "/Individuals/Details/25"
},
{
"Name": "Barry Chuckle",
"Area": "Live Case",
"DOB": "1956-09-13T00:00:00",
"URL": "/Individuals/Details/27"
},
{
"Name": "Jon Snow",
"Area": "Live Case",
"DOB": "1988-08-22T00:00:00",
"URL": "/Individuals/Details/28"
}]
As you can see the DOB is a DateTime field as converted by the standard ASP.NET JsonConvert methods, it is not exactly how a user would want to search for that date, that is to say it's not a
particularly 'human readable' format, especially here in the UK where the standard date format is DD/MM/YYYY.
I could have changed my method in the solution returning this data to format the date in a human readable way, but I don't think that's the way to go as this data may eventually be consumed by other systems down the line which may require a more standard format.
The solution, I added a new object to the constructor of Autocomplete.js, which is a 'fieldProcessors' object. This object is keyed as per the keys of the data, with the value being a function or reference to a function which will process the content of that field in some way and return the result. Please see below a portion of updated instantiation of my autocomplete object:
const autoCompletejs = new autoComplete({
data: {
src: async () => {
// Loading placeholder text
document
.querySelector("#autoComplete")
.setAttribute("placeholder", "Loading...");
// Fetch External Data Source
const source = await fetch(
"@Url.Action("AllPermittedIndividualsByArea", "CLIndividuals")"
);
const data = await source.json();
// Post loading placeholder text
document
.querySelector("#autoComplete")
.setAttribute("placeholder", "Who are you looking for? Try typing a name or date of birth");
// Returns Fetched data
return data;
},
key: ["Name", "DOB"],
cache: false
},
customEngine: customSearch,
fieldProcessors: {
"DOB": function (fieldVal) {
return moment(fieldVal).format("DD/MM/YYYY");
}
},
threshold: 2,
debounce: 300,
selector: "#autoComplete",
Note that my field processor for the DOB field in this case, uses the moment.js library to convert my date field to the desired format, but I could have done anything here.
Here are my amendments to the autocomplete.js file itself:
pulling in the config to the internal object:
var autoComplete =
function () {
function autoComplete(config) {
_classCallCheck(this, autoComplete);
this.selector = config.selector || "#autoComplete";
this.data = {
src: function src() {
return typeof config.data.src === "function" ? config.data.src() : config.data.src;
},
key: config.data.key,
cache: typeof config.data.cache === "undefined" ? true : config.data.cache
};
// Get the collection of fieldProcessors from the config passed in (if relelvant)
this.fieldProcessors = config.fieldProcessors ? config.fieldProcessors : false;
this.query = config.query;
this.triggerEvent = config.triggerEvent || ["input"],
this.searchEngine = config.searchEngine === "loose" ? "loose" : "strict";
this.customEngine = config.customEngine ? config.customEngine : false;
this.threshold = config.threshold || 0;
Applying the function to the relevant field before doing the comparison against the user's query:
var search = function search(key) {
var recordValue = key ? record[key] : record;
recordValue = _this.fieldProcessors ? (_this.fieldProcessors[key] ? _this.fieldProcessors[key](recordValue) : recordValue) : recordValue;
if (recordValue) {
var match = _this.customEngine ? _this.customEngine(_this.queryValue, recordValue) : _this.search(_this.queryValue, recordValue);
if (match && key) {
resList.push({
key: key,
index: index,
match: match,
value: record
});
} else if (match && !key) {
resList.push({
index: index,
match: match,
value: record
});
}
}
};
Hopefully this is useful to someone. There may well be better ways to achieve what I was trying to do but this worked for me and was a nice learning experience in adapting a library for my particular needs.
Happy to hear your thoughts.
Cheers
When I type npm run dev
or npm start
I have some rollup error.
> [email protected] start /home/cubex/WebstormProjects/autoComplete.js
> rollup --watch "dev"
[!] TypeError: Cannot convert undefined or null to object
TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at Watcher.<anonymous> (/home/cubex/WebstormProjects/autoComplete.js/node_modules/rollup/bin/rollup:1783:42)
at Watcher.emit (events.js:182:13)
at Task.run (/home/cubex/WebstormProjects/autoComplete.js/node_modules/rollup/dist/rollup.js:26618:22)
at /home/cubex/WebstormProjects/autoComplete.js/node_modules/rollup/dist/rollup.js:26531:70
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:11)
at startup (internal/bootstrap/node.js:285:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)
1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `rollup --watch "dev"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/cubex/.npm/_logs/2018-11-28T07_20_40_991Z-debug.log
hii
first off, thanks for this tool, i finally got it working after running into multiple issues.
works now, lucky day :)
i found a bug, or rather missleading documentation:
TypeError: config.resultsList is undefined
you get that error, when you leave out the settings for resultsList
same goes for resultItem.
when you do not define those, it throws this error. not an issue after all, but it is stated in the docs, that these are mandatory.. guess the defaults are not populated..?
The css easily breaks if the input is not structured the same way you have in your example page. Flexbox is a nicer, simpler alternative for the autocomplete results IMO. Would you accept a PR making this change?
Nice job with the library thus far btw! I like its simplicity!
Hi there,
I'm using autoComplete on multiple website, I just saw than it's not working on Mozilla Firefox (65.0.1)
It gave me this error : TypeError: t.filter is not a function - autoComplete.min.js:1:2962
On Chrome everythings is ok. Any idea ?
Thanks for this awesome js librairie !
Hello.
Is there a way to setup a default-list, that is shown, when the user focuses the input? The list should be only visible, when there is no input. When input.length > threshold, the function behind data.src should be called.
Hi,
I'm looking to apply the new release to my differents projects but an error occured when searching, I mean by taping in the search bar, I get :
So, I've show the "record" var, and it's the full object of one product in the json file. It should be a string?
I really want to update this version to the v4 or the v5
Hello autoComplete.js
users,
Hope you're all doing well and enjoying using autoComplete.js
.
I'm always trying to do my best to improve and maintain autoComplete.js
as much as possible.
That's why I've thought about performing a monthly health checkpoint status, to see how autoComplete.js
is doing with you and what should be done in-terms of improvement next.
So, every month I'm going to open a new issue for 10 days with the above title, for you to contribute in with your valuable feedback on the library mentioning What's autoComplete.js greatest weaknesses?
out of your personal experience using it.
Based on your feedback, the most mentioned/voted weakness, it will take the first place on the Roadmap under the proper section with the highest priority, while the rest comes after to be placed next month.
Thank you so much for your support and contributions to make autoComplete.js
better!
Happy Development, Cheers! :)
Hi, i found an issue when querying in the input box. When i do a keypress, my api is called 2 times which is present in data.src async function. this makes the user experience slow since the search results are not rendered unless i get response from the second call. Please let me know how i can fix this.
Thanks
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Thoroughly Describe the solution you'd like
How do i use autocomplete in my own project, you describe how to use it in your cloned repo, which has all the necesary images and html markup needed however, if i want to use it in my own project, which is 99.99% of the people, there is no explanation on how to use it.
Please provide a few use cases for this feature
Please Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
It seems CustomEvent
& Element.prototype.closest
are not supported on IE11.
Should we implement CustomEvent
& Element.prototype.closest
, or, using polyfill (corejs, etc) with babel ?
Hi, your library looks, and works great! Thank you for putting the effort to make it.
The only thing I found not to work as expected was that the Arrow Up & Down keys would scroll the page when moving up and down the result list, which is indeed the default webpage behaviour.
I think the default behaviour needs somehow be prevented, and for the moment, I added this piece to capture the events at the wrapper element:
// prevent page scroll
document.querySelector('#autoComplete_wrapper').onkeydown = function(e) {
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
e.view.event.preventDefault()
}
}
I think the problem is not apparent in your demo, because there's no scrollable content on the page.
Thank you!
Great library, thank you so much for creating it!
I have a feature request: I would like to intercept the user input before a search is performed.
My initial use case is that I want to remove "The" from the start of a search string.
Setting an optional config method called "beforeSearch" that takes the user's input string and returns another string would be ideal.
beforeSearch: (userInput) => { // Modify the search string | (Optional)
// Do something with the user's input
// const searchValue = userInput.replace("The ", "");
// return searchValue;
}
So "The Eiffel Tower" becomes "Eiffel Tower" etc...
I guess you could also use it to log search strings to do analysis on what searches are popular etc...
Thanks!
Hi, thanks for the great library.
I am facing this issue when i use fetch("").then() instead of async/await inside data.src function
fetch("apicall?search="+query)
.then(r => r.json().then(data => ({status: r.status, body: data})))
.then(obj => {
return obj.results;
});
can you please tell me how can i use .then() without seeing the above mentioned error.
Thanks
Hello.
How can I set the first item in the result-list, when the user press enter, without selecting it?
inp.addEventListener('autoComplete', (e) => {
let detail = e.detail;
if (detail.event.key == 'Enter'
&& detail.matches == 1) {
// ???
// onSelection should be triggered with the first item
}
});
Most likely you need to implement touchstart event support
location table constracture
-id
-name
-parent_id
data in location table
{'id' => 1, 'name' => 'food', 'parent_id' => 1},
{'id' => 2, 'name' => 'carry', 'parent_id' => 1}
when input food in input field, display food carry in suggest list.
How can I achieve this?
Not always we have all gloccery right now on front-end side. Sometimes It's a big data, maybe stored into elasticsearch or some. Do you planning to add async loading chunk of result data?
I love this project & have been experimenting with it for the past few days!
I think, something that would benefit this project now & in the long term is if it used Typescript.
As the feature set of this library increases
the probability of bugs will too. We can reduce that number with help of TS.
Setting up configs & builds is a pain, but if we use TSDX - Zero-config CLI for TypeScript package development it literally would take only a few minutes to setup a typescript environment.
Then, it's just a matter of moving autocomplete.js's src
files into the src
directory that TSDX generates.
I've used TSDX in dozens of my projects and it's really smooth experience!
I wanted to submit a PR of just converting all the files to end with .ts
but realized it would be wise to check in with you on the direction of your project.
Key features of TSDX (has lots of gifs go check it out π )
Other benefits of adopting typescript:
@types
Thoughts, concerns?
I see there's a setting for placeholder. But it doesn't seem to do anything special. Why not just allow developers to set the placeholder text in their html?
Is your feature request related to a problem? Please describe.
I'm trying to hook up autocomplete to multiple input fields (user names) on the page.
Thoroughly describe the solution you'd like
selector: () => document.querySelectorAll("input.name")
Please provide a few use cases for this feature
Please Describe alternatives you've considered
Additional context
Currently throwing errors such as TypeError: l.addEventListener is not a function
I'm considering using autocompletejs instead of at.js but I'd like to know if it works with contenteditable divs instead of input forms? Thank you in advance !
Hi guys,
Did anyone implement this autocomplete js in angular 6.I'm trying it from last 2 days it not working, So please anyone help me?
So i have a pretty large dataset, around 2 000 000 entries, i wouldn't want that loaded into the browser. so i tried to do this :
data: {
src: function() {
// Loading placeholder text
document.querySelector("#searchBox").setAttribute("placeholder", "loading...");
let name = document.querySelector("#searchBox").nodeValue;
// Fetch External Data Source
if (name) {
const source = fetch("/AutoSuggest?name="+name);
const data = source.json();
// Returns Fetched data
return data;
} else {
return null;
}
},
key: ["food", "cities", "animals"]
}
However the data doesn't seem to load after the threshold is reached or after that, only at the begging.
Is this by design or a bug?
Hi
Here is a link to my fiddle:
https://jsfiddle.net/apasric4/x6w4trv9/1/
This was actually working for a few moments, but then later it stopped showing the drop-down menu after I would type something in. You're supposed to be able to type something and the default drop-down menu of food and drinks is supposed to show up, but now it is not. So I know something is wrong.
In my console, I keep getting a token is not defined error.
What could be the issue?
Hi, is it possible to set "if no result" on resultItem config?
EX:
if(data){
/* Do something /
}else{
/ Do something */
}
or just do:
if (data.length){}
My problem is, if use if(data) can do something, but "else" it doesn't work, return nothing. If use data.length, return undefined... Any idea?
Thanks!
Hi :)
I think, since autoComplete.js expose a class, it should be better to separate the search logics and the render logics.
It'll allow people to render the results in the way they want.
For example in my app, I would like to render the results in a <ion-list>
element with <ion-item>
inside, so the <ul>
and <li>
elements doesn't suits to me.
With that features I would be able to do that, by getting the search results and displayed them the way I want
I'm making some progress but still ask myself a lot of questions:
I would like to use autocomplete in a sort of manufacturers/products choice (like that but it's a small private project...)
First I thought I could use two autocomplete but I don't think, after what I understood that is possible.
Second I thought to modify the data source of the only one autocomplete .
Desired Process description:
Would you have any advice.
Virtualized lists only render a subset of a large data set, so they don't slow down the page by adding lots of DOM nodes. This a memory efficient method of allowing a user to scroll down a large list without rendering all the items on the DOM.
Example Use case 1: a developer allowing a users to scroll down a large list (any large size list) until the user reaches the end.
π€ To the community, thoughts, feedback? drawbacks?
Implementation details:
I would like to "refresh" the data when changes are brought to data coming from a database. Should I re instantiate the autoComplete or can I use some code to load the data src which updated data ?
Tried your 'Demo' with my browser, 'FireFox 63.0.3'(OSX Mojave),
selected item didn't appear in '.selection'.
It works well with Chrome.
What's wrong with this?
Hey Tarek,
Great work you've done here. I noticed an inline suggestion plugin is on the roadmap. I actually need that feature for my project so I've taken the liberty of implementing it myself, although my use-case is very different to a search engine dropdown (I'm creating a rich text editor in contenteditable (CE) with suggestions implemented as inline placeholders - similar to Gmail's smart compose feature).
I have a basic PoC: https://codepen.io/jkhaui/pen/eqBBaZ
But there are a number of issues (I realise this is outside the main scope of your library, so feel free to close the issue - I just thought that it could improve some of the library's core features, too):
For the inline suggestion, Tab
should complete (i.e select) the suggestion. Right now, all Tab
does (even for the typical search engine usage) is scroll through a list of items. I suggest exposing an API method to let users programmatically alter behaviour of certain keys.
Do you have any ideas how I can implement 'repeated' suggestions? With my use-case, you'd expect a word listed in the array/database to be suggested every time its leading characters were typed, e.g. typing "agr"... suggests "agreement", but the issue is this behaviour only fires on the first word. We need it firing every time a new word is typed (perhaps you know how to call autoComplete.js every time a new word is typed?)
Finally, the major issue is with CE formatting. CE inserts HTML tags for everything from bold, italic and underline text formatting to p, div, and br elements for linebreaks. autoComplete.js doesn't recognise anything within its selector that isn't a pure text node.
I'm really struggling to overcome this part, so would greatly appreciate if you have any insight.
Once again, I apologise if you think this is too far outside the scope of your library, but I thought it at least shows you potential use-cases for your engine π
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.