Skip to content
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

Introduce a new option: data.key_display (defines whose key's value appears in the result list) #334

Closed
john-999 opened this issue Apr 9, 2022 · 5 comments
Labels
enhancement New feature or request

Comments

@john-999
Copy link

john-999 commented Apr 9, 2022

Intro
data.keys: is currently the option which defines the keys that are used to create matches (with the query string).
But whenever a match happens, the key's value is then also shown as the result in the result list. (The 2 things are linked.)

The issue
What if you have objects with multiple keys, and you want the match to happen in the value of key A, but it's the value of key B that should be displayed in the result list?

Solution
It would thus be great to have a new option data.key_display: which would let us define the key whose value should be displayed.

Example use case
Being able to search for a city name in various languages, but to always have the English version show up in the result list (not the French name, for example, with which the match was made):

Example:
Type in "Genève" (the French name, used locally in Switzerland) [= value of key A], but have "Geneva, Switzerland" [= value of key B] come up in the result list.

EDIT:
This new option should probably be able to receive multiple keys as well (just like data.keys:), thus it could be named: data.keys_display:

@john-999 john-999 added the enhancement New feature or request label Apr 9, 2022
@folknor
Copy link

folknor commented Apr 10, 2022

Using resultItem.element you can customize what is shown as much as you want.

new autoComplete({
	resultItem: {
		element: (element, data) => {
			if (foo) {
				element.innerHTML = `<span>${data.value.foo}</span>`
			} else {
				element.innerHTML = `<span>${data.value.bar}</span>`
			}
		}
	},
}

@john-999
Copy link
Author

john-999 commented Apr 10, 2022

Thank you @folknor !

The only thing this doesn't do yet is getting the <mark>...</mark> HTML tag back in there again (so that the matched substring remains highlighted). So here's what I suggest to remedy this:

const autoCompleteJS = new autoComplete({
    resultItem: {
        element: (element, data) => {
            // get the search term
            const query_string = autoCompleteJS.input.value;
            // define the case-insensitive Regexp
            const mark_text_regexp = new RegExp(`${query_string}`, "i");

            if (foo) {
                // Display value of key "foo":

                // get the text to mark (keeping upper/lower case intact)
                const mark_text = data.value.foo.match(mark_text_regexp);
                // populate the element with its text (now having the HTML tag highlight the search term)
                element.innerHTML = data.value.foo.replace(mark_text, `<mark>${mark_text}</mark>`);

            } else if (bar) {
                // Display value of key "bar":

                // get the text to mark (keeping upper/lower case intact)
                const mark_text = data.value.bar.match(mark_text_regexp);
                // populate the element with its text (now having the HTML tag highlight the search term)
                element.innerHTML = data.value.bar.replace(mark_text, `<mark>${mark_text}</mark>`);

            }
        }
    },
}

I think this maybe useful for others.

Could you include the example somewhere in the documentation, maybe at:

https://tarekraafat.github.io/autoComplete.js/#/configuration?id=example-12

@folknor
Copy link

folknor commented Apr 10, 2022

You can get the query in that function from the data argument instead of through autoCompleteJS.input.value, like so

const { query, matches, results } = data

The highlighted parts won't be lost unless you directly write over innerHTML like I did in my example. You can modify the DOM instead of overwriting it.

@folknor
Copy link

folknor commented Apr 10, 2022

There's more discussion about the mark/highlight feature in #306 and #264 but I don't remember if any of it is useful here. Probably not.

@john-999
Copy link
Author

Thank you for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants