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

Element added in resultsList.container is removed on second input #206

Closed
6 tasks
folknor opened this issue Apr 26, 2021 · 9 comments
Closed
6 tasks

Element added in resultsList.container is removed on second input #206

folknor opened this issue Apr 26, 2021 · 9 comments
Labels
bug Something isn't working

Comments

@folknor
Copy link

folknor commented Apr 26, 2021

  • System Information

    • Firefox nightly 26. april
    • Linux
  • Describe the bug

Here's the code for one of my autocompletes (work in progress)

		new autoComplete({
			data: {
				src: async () => fetchBedriftsInfo(v("bedrift")),
				key: ["navn", "organisasjonsnummer"],
				cache: false,
				results: list => {
					const q = v("bedrift").toLowerCase()
					return list.sort((first, second) => {
						let fs = diceCoefficient(
							q,
							first.value.navn.toLowerCase()
						)
						let ss = diceCoefficient(
							q,
							second.value.navn.toLowerCase()
						)
						return ss > fs
					})
				}
			},
			query: {
				manipulate: query => {
					let nr = /^\d+$/.test(query.replace(/\s/g, ""))
					if (nr === true) {
						return query.replace(/\s/g, "")
					}
					return query
				}
			},
			selector: "#bedrift",
			threshold: 3,
			debounce: 300,
			resultItem: {
				content: (data, element) => {
					if (
						data.value.forretningsadresse instanceof Object &&
						typeof data.value.forretningsadresse.poststed ===
							"string"
					) {
						element.innerHTML = `<span>${data.value.navn}</span><span class="text-muted">${data.value.forretningsadresse.poststed}</span>`
					} else if (
						data.value.postadresse instanceof Object &&
						typeof data.value.postadresse.poststed === "string"
					) {
						element.innerHTML = `<span>${data.value.navn}</span><span class="text-muted">${data.value.postadresse.poststed}</span>`
					} else {
						element.innerHTML = `<span>${data.value.navn}</span>`
					}
				}
			},
			resultsList: {
				container: (element) => {
					const result = document.createElement("p")
					result.setAttribute("class", "no_result")
					result.setAttribute("tabindex", "1")
					result.innerHTML = `Skriv inn hele organisasjonsnummeret, uten mellomrom.`
					element.appendChild(result)
				},
				maxResults: 8,
				idName: "bedrift-liste",
				noResults: (list, query) => {
					const result = document.createElement("li")
					result.setAttribute("class", "no_result")
					result.setAttribute("tabindex", "1")
					let nr = /^\d+$/.test(query)
					if (nr === true) {
						result.innerHTML = `Skriv inn hele organisasjonsnummeret, uten mellomrom.`
					} else {
						result.innerHTML = `Fant ingen resultat for "${query}".`
					}
					list.appendChild(result)
				}
			},
			onSelection: feedback => {
				settBedrift(feedback.selection.value)
				setTimeout(() => {
					$("epost").focus()
				}, 100)
			}
		})

In resultsList.container I add a p element at the top of the list that I want to use to give helpful information to the user. Here's a screenshot:
dropdown
(the text in the p is currently wrong, also the element is not styled properly - I just started implementing it, but that's not relevant to the bug)

  • To Reproduce
    Steps to reproduce the behavior: <!-- Example below-!>
  1. Add element to the container in resultsList.container
  2. Type something in the input
  3. Wait for autocomplete to open
  4. See the element added in step 1 is there
  5. Type one more character (make the autocomplete refresh itself), and the element is gone
  • Expected behavior
    I want the element to be there every time :-)

I think the "problem" is in your function generateList you do list.innerHTML = ""; if list is non-null.

Perhaps it would be possible to add an attribute to my element that makes autoComplete.js not nuke it?

Or maybe you have an alternative solution for me :-)
Thank you!

@folknor folknor added the bug Something isn't working label Apr 26, 2021
@folknor
Copy link
Author

folknor commented Apr 26, 2021

For example a new property on resultsList like append and prepend where we can return HTMLElement that is always inserted before or after the result elements.

Would probably need to have config for if to add them when results are 0. Would be nice to have that information in resultsList.container as well.

@TarekRaafat
Copy link
Owner

Hello @folknor,

Good catch!

The issue has been fixed in v9.0.4

Check it and let me know how it goes.

Have a nice day! :)

@folknor
Copy link
Author

folknor commented Apr 26, 2021

Thank you it works great! 👍

I changed my code to also make sure clicking the node doesn't close the list like this

container: element => {
	const result = document.createElement("p")
	result.setAttribute("class", "no_result")
	result.setAttribute("tabindex", "1")
	result.innerHTML = `Skriv inn hele organisasjonsnummeret, uten mellomrom.`
	result.addEventListener("click", (ev) => { ev.stopPropagation() } )
	element.appendChild(result)
},

@TarekRaafat
Copy link
Owner

Glad to hear that! :)

For example a new property on resultsList like append and prepend where we can return HTMLElement that is always inserted before or after the result elements.

Would probably need to have config for if to add them when results are 0. Would be nice to have that information in resultsList.container as well.

Since the element parameter contains the entire list element you can check it if empty to make conditional changes

@folknor
Copy link
Author

folknor commented Apr 26, 2021

Since the element parameter contains the entire list element you can check it if empty to make conditional changes

Can you explain how? Because you invoke resultsList.container before adding the child elements at https://github.com/TarekRaafat/autoComplete.js/blob/master/dist/js/autoComplete.js#L204

I think I am misunderstanding something.

@folknor
Copy link
Author

folknor commented Apr 26, 2021

Wait you just changed it :-D

@TarekRaafat
Copy link
Owner

You're right I've just noticed that after my reply and I've just changed it in v9.0.5

Check it and let me know :)

@TarekRaafat
Copy link
Owner

Wait you just changed it :-D

Yes, my bad 😅

@folknor
Copy link
Author

folknor commented Apr 26, 2021

Great work thanks again! 💯 👍

helpworks
noresults

resultsList: {
	container: element => {
		if (element.children.length === 1 && element.children[0].classList.contains("autoComplete_ingen-resultat")) {
			return
		}
		const result = document.createElement("p")
		result.setAttribute("class", "autoComplete_info")
		result.setAttribute("tabindex", "-1")
		result.innerHTML = `<span class="iconify-inline" data-icon="fa-solid:exclamation-triangle"></span>Du må velge en bedrift fra denne listen. Det er ikke nok å skrive inn navnet eller organisasjonsnummeret.`
		result.addEventListener("click", ev => {
			ev.stopPropagation()
		})
		element.prepend(result)
	},
	maxResults: 8,
	idName: "bedrift-liste",
	noResults: (list, query) => {
		const result = document.createElement("li")
		result.setAttribute("class", "autoComplete_ingen-resultat")
		let nr = /^\d+$/.test(query)
		if (nr === true) {
			result.innerHTML = `<span class="iconify-inline" data-icon="fa-solid:exclamation-triangle"></span>Skriv inn hele organisasjonsnummeret, uten mellomrom.`
		} else {
			result.innerHTML = `<span class="iconify-inline" data-icon="fa-solid:exclamation-triangle"></span>Fant ingen resultat for "${query}".`
		}
		list.appendChild(result)
	}
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants