aria-autocomplete icon indicating copy to clipboard operation
aria-autocomplete copied to clipboard

How to update or replace the list of values of an already created element?

Open AlChernova opened this issue 1 year ago • 8 comments

There is a changes, but the outer list does not. How to update everything?

AlChernova avatar Jun 02 '23 12:06 AlChernova

Hi @AlChernova could you please clarify what you mean? Are you using AriaAutocomplete to enhance a select element or a checkbox list? When enhancing pre-existing options in the DOM, the library assumes that the list is static. So if the underlying list in the DOM gets updated, you'd need to destroy and re-initialise the autocomplete.

If you're using the library to progressively enhance a select or checkboxlist that itself regularly gets updated, it might be better to just use AriaAutocomplete() on a regular input, and use a source function that returns available options.

mynamesleon avatar Jun 02 '23 21:06 mynamesleon

Here's an example. Say you have a store locator and are asking the user to first pick a state and then showing them a list of stores in that state. The state names can be a fixed select element, but the list of stores changes each time the state is changed. I've been able to make this work by calling input.ariaAutocomplete.destroy() and re-initializing with AriaAutocomplete(input, ...) but that seems heavy-handed when only the list of choices has changed.

dmethvin-gov avatar Feb 15 '24 22:02 dmethvin-gov

Hi @dmethvin-gov - sorry for my delayed reply.

This is why multiple source approaches are supported. The most versatile one for providing different lists of results is of course providing a function as the source. But in this case, you'd need to do the filtering yourself.

A pseudo-code example:

const sourceFunction = (inputQuery, render, isFirstCall) => {
  const baseSource = someCondition ? specificArrayOfConditions : defaultArrayOfOptions;
  const resultsToRender = filterMyOptions(baseSource, inputQuery);
  render(resultsToRender);
};

(Remember to also consider the UX of re-using the same field for multiple purposes though - e.g. is it clear to a screen-reader user).

mynamesleon avatar Feb 21 '24 14:02 mynamesleon

Thanks for the reply! The docs weren't clear to me and I thought the source function would only be called once. The function example doesn't say how often it's called, and something like a Promise can only resolve once. How often is the function called, and what triggers it?

dmethvin-gov avatar Feb 21 '24 14:02 dmethvin-gov

The source is referred to every time a query is made. So it will depend on options to some extent, but every time a list of options needs to be rendered, the source is used. So if it's a string, that string is queried as an endpoint. And if it's a function, that function will be called. I should maybe make that clearer in the docs, but that's also why the source function is provided with the query as its first argument - so that you can do your own filtering using the value in the input.

mynamesleon avatar Feb 21 '24 15:02 mynamesleon

Calling AriaAutocomplete on a select or checkbox list, or providing a static array, treats those as a static source. So that static list is stored internally, and the library then filters that static list each time the input value updates. It's only in those static cases that you'd need to destroy and re-initialise to update the list.

But if you use a function (or Promise), or a string endpoint, then the source is dynamic and is called every time a new list of options needs to be rendered. Because in those scenarios, the library is relying on you doing the filtering yourself. That's the main difference.

mynamesleon avatar Feb 21 '24 15:02 mynamesleon

Your explanation makes total sense. Since I do want the built-in filtering (it's great!) but need to change the list based on other form fields, it sounds like the approach I'm taking (destroy and re-initialize) is easiest one to use.

dmethvin-gov avatar Feb 27 '24 14:02 dmethvin-gov

At the moment, yes. Which is unfortunate. Definitely a missing feature there!

mynamesleon avatar Feb 27 '24 14:02 mynamesleon