Tamjid
Tamjid

Reputation: 5506

MUI autocomplete onchange not triggering on chip delete

I'm using the material ui autocomplete component but I noticed that when the chips (tags) are deleted directly from the (x) button on the chip the autocomplete's onchange function is not triggered. Any ideas how I can get the onchange to trigger when a tag is deleted directly from the chip component?

Bellow is my code:

My component which uses autocomplete

export default function FormSearchInput( props ) {
  const classes = FormStyle();
  const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
  const checkedIcon = <CheckBoxIcon fontSize="small" />;
  return (
    <Grid item xs = {props.xs} className = {classes.formItem}>
    <Autocomplete
      className = {props.className}
      size = {props.size}
      limitTags = {4}
      multiple
      options = {props.options}
      disableCloseOnSelect
      getOptionLabel = {( option ) => option}
      defaultValue = {props.selectedOptions}
      renderOption = {( option, {selected} ) => (
      <React.Fragment>
      <Checkbox
        icon = {icon}
        checkedIcon = {checkedIcon}
        style = {{ marginRight: 8 }}
        checked = {selected}
        onChange = {props.onChange( option, selected )}
      />
        {option}
      </React.Fragment>
    )}
    renderInput = {( params ) => (
      <TextField {...params} variant = "outlined" label = {props.label}/>
    )}
    />
  </Grid>
  )
}

My onchange handler which i pass to my formsearchcomponent:

function handleCollaboratorsChange( option, selected ) {
    console.log("triggering")
    let tempCollaborators = collaborators
    if( selected && !tempCollaborators.includes(option) ) {
      // If collaborator not in list add to list
      tempCollaborators.push( option )
    } else if( !selected && tempCollaborators.includes(option) ) {
      // If collaborator in list remove from list
      tempCollaborators.splice( tempCollaborators.indexOf(option), 1 );
    }
    setCollaborators( tempCollaborators )
  }

Upvotes: 2

Views: 4227

Answers (2)

chispitaos
chispitaos

Reputation: 937

Capture the "reason" in the onchange. In the following example, I've an autocomplete that allows the user to add new options and display them as chips.

  // HANDLE: ON CHANGE
  const on_change = (
    event: React.SyntheticEvent,
    newValue: any,
    reason: string,
    details: any,
  ) => {
    const selected_item = newValue[newValue.length - 1]

    switch (reason) {
      case 'removeOption':
      case 'remove-option':
        if (details.option.name) {
          // remove an existing option
          remove_tag(details.option.name)
        } else {
          // remove a new created option 
          remove_tag(details.option.inputValue)
        }

        break
      case 'createOption':
      case 'selectOption':
        if (typeof selected_item === 'string') {
          if (can_add()) create_tag(newValue)
        } else if (selected_item && selected_item.inputValue) {
          // Create a new value from the user input
          if (can_add()) create_tag(selected_item.inputValue)
        } else {
          if (can_add()) {
            if (!tags.includes(selected_item)) set_tag([...tags, selected_item])
          }
        }
        break
    }
  }

And define the component like this:

<Autocomplete
            multiple={true}
            autoHighlight={true}
            limitTags={tags_limit}
            id="cmb_tags"
            options={full_tags}
            getOptionLabel={on_get_option_label}
            defaultValue={tags}
            freeSolo
            filterOptions={on_filter}
            selectOnFocus
            noOptionsText={i18n.t('sinopciones')}
            onChange={on_change}
            renderInput={(params) => (
              <TextField
                {...params}
                variant="standard"
                placeholder={placeholder}
              />
            )}
            renderOption={(props, option, { selected }) => (
              <li {...props}>
                <Checkbox
                  icon={icon}
                  checkedIcon={checkedIcon}
                  style={{ marginRight: 8 }}
                  checked={selected}
                />
                {option.name}
              </li>
            )}
          />

Let me know if this helps you.

Upvotes: 2

Koji Ikehara
Koji Ikehara

Reputation: 33

Add the onChange property...

 <Autocomplete
      className = {props.className}
      size = {props.size}
      limitTags = {4}
      multiple
      options = {props.options}
      disableCloseOnSelect
      getOptionLabel = {( option ) => option}
      defaultValue = {props.selectedOptions}
      **onChange = {(event, newValue) => { handleCollaboratorsChange(newValue); }}**
      renderOption = {( option, {selected} ) => (

Upvotes: 1

Related Questions