Reputation: 2889
I have a Product Options "Color, Size, etc" And as we know user can select one thing from the option "selected just red color from Colors", in this time I ad the selected one the separate Array "All Option user selected" but the issue is the user can add duplicated options in the same filed "e.g. Color" So how can I solve this issue? The final Thing should be: One thing from separate Option For Example
SelectedOptions = [
{ name:"red",id:88,optionType:"Color"},
{ name:"XL",id:22,optionType:"Size"},
....
]
But What I go now
SelectedOptions = [
{ name:"red",id:88,optionType:"Color"},
{ name:"green",id:87,optionType:"Color"},
{ name:"XL",id:22,optionType:"Size"},
{ name:"M",id:22,optionType:"Size"},
....
];
I know that's because I push any selected one to the SelectedOptions Array,
I'm trying to solve it by checking the optionType
but I did not get any good idea
Code snippet
const [selectedIndexColor, setSelectedIndexColor] = useState<
number | undefined
>();
const [selectedIndexText, setSelectedIndexText] = useState<number | null>();
const [selectedIndexImage, setSelectedIndexImage] = useState<number | null>();
interface ManipulateValueOptionProp extends valueOptionProp {
optionType: string;
}
const [allOptions, setAllOptions] = useState<ManipulateValueOptionProp[]>([]);
const renderValue = (value: valueOptionProp, type: string) => {
const selectedColor = selectedIndexColor === value.id;
const selectedText = selectedIndexText === value.id;
const selectedImage = selectedIndexImage === value.id;
switch (type) {
case 'text': {
return (
<View
style={[
styles.selectedText,
{backgroundColor: selectedText ? 'black' : 'transparent'},
]}>
<Text
style={{
textAlign: 'center',
color: selectedText ? 'white' : 'black',
fontSize: 12,
}}>
{value.name_en}
</Text>
</View>
);
}
case 'Color': {
return (
<>
<View
// @ts-ignore
// eslint-disable-next-line react-native/no-inline-styles
style={{
width: 53,
height: 53,
backgroundColor: value.display_value,
}}
/>
{selectedColor ? (
<View style={styles.selectedColor}>
<CheckmarkIcon color="black" />
</View>
) : null}
</>
);
}
case 'images': {
return (
<>
<Image
// @ts-ignore
source={{uri: value.display_value}}
// eslint-disable-next-line react-native/no-inline-styles
style={{width: 53, height: 53, backgroundColor: '#0f4c7f'}}
/>
{selectedImage ? (
<View style={styles.selectedColor}>
<CheckmarkIcon />
</View>
) : null}
</>
);
}
default: {
return null;
}
}
};
{item.options.map((option) => {
return (
<View style={styles.optionsBox}>
<Text style={styles.optionTxt}>{option.label_en}</Text>
<View style={{flexDirection: 'row'}}>
{option.values.map((value: valueOptionProp) => {
return (
<ScalePressable
key={`${option.id}${value.id}`}
onPress={() => {
option.type === 'Color' &&
setSelectedIndexColor(value.id);
option.type === 'text' && setSelectedIndexText(value.id);
option.type === 'images' &&
setSelectedIndexImage(value.id);
if (
!allOptions.some(
(alreadyExist) => alreadyExist.id === value.id,
)
) {
setAllOptions((options) => [
...options,
{...value, optionType: option.type},
]);
}
}}>
<View style={styles.values}>
{renderValue(value, option.type)}
</View>
</ScalePressable>
);
})}
</View>
</View>
);
})}
Upvotes: 0
Views: 85
Reputation: 202854
Seems to me you just need to remove deselected options from allOptions
array when the user presses that same filter option.
onPress={() => {
option.type === 'Color' && setSelectedIndexColor(value.id);
option.type === 'text' && setSelectedIndexText(value.id);
option.type === 'images' && setSelectedIndexImage(value.id);
if (allOptions.some(option => option.type === value.type)) {
setAllOptions(options => options.filter(option => option.type !== value.type));
} else {
setAllOptions((options) => [
...options,
{ ...value, optionType: option.type },
]);
}
}}
Upvotes: 0
Reputation: 552
Here is one possible solution. You may consider creating a new array by removing all options with the same option type as the new option and then adding the new option into the new array.
let selectedOptions = [
{ name: 'red', id: 88, optionType: 'Color' },
{ name: 'XL', id: 22, optionType: 'Size' },
];
let newOption = { name: 'green', id: 87, optionType: 'Color' };
selectedOptions = [
...selectedOptions.filter(
option => option.optionType != newOption.optionType
),
newOption,
];
Upvotes: 1