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

[Autocomplete] Validate freeSolo input (with multiple) #18656

Closed
1 task done
andreasheim opened this issue Dec 2, 2019 · 3 comments · Fixed by #18897
Closed
1 task done

[Autocomplete] Validate freeSolo input (with multiple) #18656

andreasheim opened this issue Dec 2, 2019 · 3 comments · Fixed by #18897
Labels
component: autocomplete This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.

Comments

@andreasheim
Copy link
Contributor

andreasheim commented Dec 2, 2019

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

Right now, freeSolo esp. in combination with multiple, is a complete freeform input.

I would like to be able to run a validator before a value is added as a tag.

Examples:

  • add an email to a list
  • add a url to a list
  • input needs to be a partial match to the options provided

This can currently achieved by

  • make inputValue controlled
  • onChange
    • examine last tag added
    • if invalid, do not accept the changed value
    • reset input value to the last tag added after a 0 timeout.

The 0 timeout makes me uncomfortable, but is necessary, since onInputChange will fire right after onChange, and will otherwise reset the input to an empty string.

I'm not sure if calling event.preventDefault() within onChange should prevent onInputChange from being triggered?

Examples 🌈

Implementation of a partial match validation - keyword is included in several options:
Screen Shot 2019-12-02 at 11 50 32 AM
Screen Shot 2019-12-02 at 11 50 53 AM

wat is not in the list, and thus rejected
Screen Shot 2019-12-02 at 11 51 15 AM

The autocomplete is used as a filter here. Adding a value that doesn't at least partially match would yield no results.

This is my current implementation

export default function PartialMatchAutocomplete({ partialMatchErrorText, ...autocompleteProps }) {
  const [partialMatchError, setPartialMatchError] = useState(false);
  const [inputValue, setInputValue] = useState('');
  const hasMatch = hasPartialMatch(autocompleteProps.options);

  const onChange = (e, value) => {
    if (fp.size(value) < fp.size(autocompleteProps.value)) {
      setPartialMatchError(false);
      return autocompleteProps.onChange(e, value);
    }

    const newTag = fp.last(value);

    if (hasMatch(newTag)) {
      setPartialMatchError(false);
      return autocompleteProps.onChange(e, value);
    }

    e.preventDefault();
    setPartialMatchError(true);

    // onInputChange will fire right after onChange with an empty value.
    // Delay re-setting inputValue until after that
    fp.defer(() => setInputValue(newTag));
  };

  const onInputChange = (_, value) => {
    setInputValue(value);
    if (hasMatch(value) && partialMatchError) {
      setPartialMatchError(false);
    }
  };

  return (
    <Autocomplete
      {...autocompleteProps}
      error={partialMatchError ? partialMatchErrorText : undefined}
      freeSolo
      inputValue={inputValue}
      multiple
      onChange={onChange}
      onInputChange={onInputChange}
    />
  );
}

Motivation 🔦

Adding validation to freeSolo multiple input.

Validation is usually not the concern of material-ui, though enabling it is by being a controlled input. I'm mostly wondering what the proper approach would be to accomplish this.

@oliviertassinari oliviertassinari added the component: autocomplete This is the name of the generic UI component, not the React module! label Dec 2, 2019
@oliviertassinari
Copy link
Member

oliviertassinari commented Dec 2, 2019

@andreasheim What if we swap the call order? To:

  1. onInputChange
  2. onChange

I suspect your use case is more common.

@andreasheim
Copy link
Contributor Author

Swapping the order should cover my case for sure.

Trying to think of a case where this could cause trouble, but I don't think it should

@oliviertassinari
Copy link
Member

oliviertassinari commented Dec 2, 2019

Me neither, I could think of the automatic tokenization support (e.g. using , to split values), but that should probably be covered. All clear ✅.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: autocomplete This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants