mui-downshift icon indicating copy to clipboard operation
mui-downshift copied to clipboard

initialSelectedItem doesnt work

Open stragz opened this issue 5 years ago • 14 comments

Im trying to use your searchable dropdowns to create a form, it works fine on a new form but if you load one that saved partially filled I cannot seem to load the dropdown from a pre-determined value.

What I'm trying to do: Load form with dropdown initial value set to Block.

How I'm trying to do it: By using initialSelectedItem as described in Downshift documentation.

<MuiDownshift
   items={dataOptions}
  variant={"outlined"}
  onStateChange={handleStateChange}
  getInputProps={({ openMenu }) => ({
    label: "Storage Type",
    placeholder: "Select Storage Type"
  })}
  // initialSelectedItem={0}
  // initialSelectedItem={"0"}
  initialSelectedItem={"Block"}
  margin="normal"
/>

Expected result: Form loads with with the the "Block" entry already selected in the dropdown

Result: I've tried different ways to specify the value but none seem to work, I always end up with the Label.

Code Sandbox: https://codesandbox.io/embed/vigorous-kalam-jzq4o

stragz avatar Jul 15 '19 18:07 stragz

@stragz How about this?

getInputProps={({ openMenu }) => ({
   value: "Block",
   label: "Storage Type",
   placeholder: "Select Storage Type"
})}

cvanem avatar Jul 15 '19 21:07 cvanem

@cvanem Thanks for the tip, that helped get me to a good workaround. Its not quite the full solution to the problem, but its gonna do for now.

I'm now passing the desired value as a prop from the main App to the dropdown component and use that as the value in getInputProps.

const [selectedValue, setSelectedValue] = useState(props.value);

[...]

const handleStateChange = (changes: any) => {
  props.onChange(this, {
    name: props.name,
    value: changes.inputValue
  });
  setSelectedValue(changes.inputValue);
};

return (
  <FormControl fullWidth={true}>
    <Typography variant="subtitle1" color="textSecondary">
      <MuiDownshift
        items={dataOptions}
        variant={"outlined"}
        onStateChange={handleStateChange}
        getInputProps={({ openMenu }) => ({
          label: "Storage Type",
          placeholder: "Select Storage Type",
          value: selectedValue
        })}
        margin="normal"
      />
    </Typography>
  </FormControl>
);

This is the new version of the code with the workaround: https://codesandbox.io/embed/kind-dust-zlh5r

Its not ideal as it forces a value in the Input as opposed to forcing an item selection from the dropdown itself. If you open the dropdown and close it without selecting anything, both the input value and the dropdown placeholder will be overlapped.

The real solution would still be to have an initial value from the dropdown.

stragz avatar Jul 16 '19 14:07 stragz

@stragz That is similar to how I have been using it. I also bind the onChange event to handleStateChange and any external onChange needed. I think part of the problem is the package is still using old code. See the previous issue here for more info: https://github.com/techniq/mui-downshift/issues/79. We should probably update to 3.x.

cvanem avatar Jul 16 '19 17:07 cvanem

@stragz Here is some code I extracted/adpated from one of my redux applications. It is a little messy but might give you some direction. https://codesandbox.io/s/hardcore-curie-pxcll?fontsize=14

cvanem avatar Jul 16 '19 18:07 cvanem

@cvanem Thanks alot for that, didnt initially realize that mine although allowing me to set an initial value, it broke the ability to make a search for a result.

Your help is greatly appreciated.

stragz avatar Jul 17 '19 16:07 stragz

@cvanem quick question: in your code example, where does this come from?

import { SelectItem } from "../../general/input/SingleSelect/SingleSelect";

which package is it imported from?

stragz avatar Jul 17 '19 17:07 stragz

@stragz Ooops. That is just a typescript interface

export interface SelectItem {
  value: any;
  label: string;
  type?: any;
  item?: any;
}

Also take some of the comments with a grain of salt as I had to modify some of the redux compatible code to work for the code example. I.E the onChange passing the item instead of the selected value changed.

cvanem avatar Jul 17 '19 18:07 cvanem

@cvanem I have another question for you, if you have a few minutes. Ive done some modification to your code in order to do a few things.

First of all I use a useQuery to get my inital data from my saved Form, then I pass my initial value to my dropdown, which was also modified to use a GraphQL query as its content list.

My issue is that when my dropdown initially loads, it doesnt yet have it's props.value initiated so it loads the dropdown as if it didnt have one. It value then gets passed as props and it is displayed as the input value but for some reason because of the timing it the label remains inside the input instead of moving in the outline. So i have 2 strings of text overlapping.

I've tried a bunch of things to try and get it to behave properly but to no avail so far. I wonder if you'd have any ideas as to how to fix my problem.

Thanks again for you help.

stragz avatar Jul 23 '19 19:07 stragz

@stragz If you can make a code sandbox reproduction I could take a look. The label state should be handled by the underlying MUI component, so you may need to take a look at that to see why it isn't updating. Are you sure you are updating the underlying input value? Maybe try executing blur or focus on the input ref when the value changes.

cvanem avatar Jul 23 '19 20:07 cvanem

Sorry about the long delay, I've had to deal with a defective laptop and setting up my environment all over again. In the meantime one of my colleagues has managed to get something working. I'll try to setup a codesandbox in the next few days to share with everyone.

stragz avatar Jul 31 '19 16:07 stragz

initialInputValue does not work either. This is a major issue which makes component unusable. Any expectation to fix?

kirill-konshin avatar Oct 01 '19 18:10 kirill-konshin

@stragz in your example https://codesandbox.io/embed/kind-dust-zlh5r some errors appear in console.

image

Also if you focus the dropdown and then click out of it (without selecting anything new) it will result in this:

image

Looks like there's some state disconnect...

kirill-konshin avatar Oct 02 '19 19:10 kirill-konshin

Warning: this is most likely overkill for most use case out there but this is what we've come up with at work (by "we" I mostly mean my colleague, the BearManGod (see code comment)).

It's a generic search dropdown using MUI-downshift which can accept a GraphQL query along with the name of the data table and the query variables to create a searchable dropdown using that queries output to feed the dropdown list.

But it can also be used with a simple array of strings as displays in the following CodeSandbox, you only need to pass the array through a function format it to what the component is expecting.

So obvisouly if you dont use GraphQL, theres alot of unnecessary code in there for you but you can always just strip it back to have it take basic arrays only. But it's a fully functionnal searchable dropdown to which you can set initial value.

https://codesandbox.io/s/vigorous-robinson-d4c5j

Hope this helps.

stragz avatar Oct 02 '19 22:10 stragz

Thank you for the example, it will take time to dig through it :) in the mean time why not downshift's prop initialInputValue?

Any chance to boil down the example to something more reasonable for a project that just needs default value? It's hard to dig through all nuances...

Also, are there any plans to add some solution to library to address the initial value problem?

kirill-konshin avatar Oct 02 '19 22:10 kirill-konshin