Reputation: 3272
I am using the Material UI library, and used the button toggle widget as a picker.
Here is my codesandbox - https://codesandbox.io/s/50pl0jy3xk
There are a few interactions going on, but basically a user can click a membership type for an adult, child or infant. There are 3 options of yes, no and maybe. Once a user selects one or multiple options this gets submitted to api.
I have added a default values from my receiving prop, so if a user has already got a membership it has them highlighted.
const selected = [
{
personId: "0001657",
fullName: "Joe Bloggs",
seniorStatus: "Yes",
defaultStatus: [
{ membership: "Seniors", defaultvalue: "Yes" },
{ membership: "Juniors", defaultvalue: "No" }
]
}
];
As you can see the defaultStatus field(above) has been added for the users current memberships. All this needs to do is highlight the relevant toggle, the data if not changed does not need submission to api.(below) - I would guess that the value needs to be interrogated but the value is already being used in my case.
<ToggleButtonGroup
className={classes.toggleButtonGroup}
value={value[rowIdx][cellIdx.value]}
exclusive
onChange={(event, val) =>
this.handleValue(event, val, rowIdx, cellIdx.value)
}
>
<ToggleButton
className={`w-100 ${classes.toggleButton}`}
value="yes"
>
Yes
</ToggleButton>
<ToggleButton
className={`w-100 ${classes.toggleButton}`}
value="no"
>
No
</ToggleButton>
<ToggleButton
className={`w-100 ${classes.toggleButton}`}
value="maybe"
>
Maybe
</ToggleButton>
</ToggleButtonGroup>
Any help or assistance would be fantastic!
Upvotes: 1
Views: 3612
Reputation: 5732
ToggleButton
group, but using "Yes", "No" etc in default value. I guess that is a typo, both need to match. value={ value[rowIdx]["defaultStatus"] && // check if defaultStatus exists value[rowIdx]["defaultStatus"].filter( // filter the defaultStatus ds => ds.membership === cellIdx.label // and look for the specific membership type )[0] // check if that exists ? value[rowIdx]["defaultStatus"].filter( ds => ds.membership === cellIdx.label )[0].defaultvalue // set the value : null // otherwise null }
Here is your forked example: https://codesandbox.io/s/mjk9zy5rqp?fontsize=14
PS:
handleValue
will not work anymore. Looks like it was a 2D array previously and now you have defined it according to a new schema. May be you are in the middle of an edit. But so you know.defaultStatus
like this, instead of an array:
defaultStatus: { Seniors: "yes", Juniors: "no" }
This way you won't have to filter the array like I did in the example. You could simply use value[rowIdx]["defaultStatus"][cellIdx.label]
as value.
Update:
Your handleValue
function is not working because you are setting the state in wrong place (probably from your old state design). You need to modify it to incorporate you new state design:
handleValue = (event, val, rowIdx, cellIdx) => { ... if (!newValue[rowIdx]["defaultStatus"]) { // check if you have defaultStatus for that row newValue[rowIdx]["defaultStatus"] = []; // create empty array if that doesn't exist } const updatable = newValue[rowIdx]["defaultStatus"].filter( // find the column corresponding to the membership ds => ds.membership === cellIdx ); if (updatable[0]) { // if such column exists updatable[0]["defaultvalue"] = val; // update the defaultvalue } else { newValue[rowIdx]["defaultStatus"].push({ // otherwise create a new defaultvalue membership: cellIdx, defaultvalue: val }); } this.setState({ value: newValue }); };
See my updated code in the same sandbox url. Again, the logic could be much simplified with a plain object instead of an array.
Upvotes: 1