Search code examples
reactjsautocompletelabel

React Auto Complete value propblem


So the autocomplete work displays option of diffrent countries and their flag icons as well ,saving data to a database also work ,the problem im having is when I want to display the value (on edit mode) it dowant show except when I remove the "getOptionLabel" from the autoComplete also whould like to add a flag Icon to the value as well

<Autocomplete
            /*value={values.country+ 
                 <Avatar
                style={{ height: 42, width: 42 }}
                src={`data:image/jpeg;base64,${values.flag}`}
            ></Avatar>}*/
                name="country"

                options={countryData}
                getOptionLabel={option => option.listDescription}
                onChange={(e, value) => {
                    setFieldValue(
                        'country',
                        value !== null ? value.listDescription : 'country'
                    );

                    setFieldValue('region', value !== null ? value.region : 'region');
                    setFieldValue('flag', value !== null ? value.image.data : 'flag');
            //console.log( value.image.data)
                }}
                renderInput={params => (
                    <TextField
                        {...params}
                        error={Boolean(touched.country && errors.country)}
                        helperText={touched.country && errors.country}
                        name="country"
                        label="Select Country"
                        variant="outlined"
                        onChange={(e, value) => setFieldValue('country', value)} 
                        onBlur={() => setFieldTouched('country', true)}
                        fullWidth
                        value={values.country+
                         <Avatar
                            style={{ height: 42, width: 42 }}
                            src={`data:image/jpeg;base64,${values.flag}`}
                        ></Avatar>}
                    />
                )}
                renderOption={option => (
                    <React.Fragment>
                        <img
                            style={{ height: 30, width: 30 }}
                            src={`data:image/jpeg;base64,${option.image.data}`}
                        ></img>{' '}
                        &nbsp;&nbsp;&nbsp;
                        {option.listDescription}
                    </React.Fragment>
                )}
            />

Solution

  • const CountryComponent = (props) =>
    {
        const countrySelected = useRef(null);
        const [externalData, setExternalData] = useState(null);
        const [foundCountry, setFoundCountry] = useState(null);
    
    
        let captureForm = useFormikContext();
    
        // check if the form value has changed
        if (captureForm.values != null && captureForm.values.country != null && captureForm.values.country != '')
            countrySelected.current = captureForm.values.country;
    
        let findCountry = function(data)
        {
            // routine to set the country when the list initialized or the value changes
            if (data != null && countrySelected.current != null)
            {
                setFoundCountry(data.find(element => element.listCode === countrySelected.current));
            }
        };
    
        useEffect(() => {
            // make the request to get the country data (this only happens once)
            let asyncRequest = null;
            function getData() {
                asyncRequest = Api('country/all', 'Get').then(
                    externalData => {
                        asyncRequest = null;
    
                        // force the render
                        setExternalData(externalData);
                        findCountry(externalData);
                    }
                );
            }
    
            getData();
            return function cleanup() {
                // cleanup the async request as on component deallocation - this will be run by useEffect as its the returning function
                if (asyncRequest) {
                    asyncRequest.cancel();
                }
            }
        }, []);
    
        useEffect(() => {
            // determine the selected country once the form is re-rendered (this will only be called if the value changes)
            findCountry(externalData);
        }, [countrySelected.current]);
    
        return externalData ?
            (
                <div>
                    <Autocomplete
                        name="country"
                        options={externalData}
                        getOptionLabel={option => option.listDescription}
                        value={foundCountry}
                        getOptionSelected={(option, value) => option.listCode === value.listCode}
                 
                        onChange={(e, value) => {
                            if (value != null)
                            {
                                captureForm.setFieldValue('country', value.listCode);
                                captureForm.setFieldValue('region', value.region);
                                captureForm.setFieldValue('flag', value.image.data);
                                
                            }
                        }}
                        renderInput={params => (
                            <TextField
                                {...params}
                                error={Boolean(captureForm.touched.country && captureForm.errors.country)}
                                helperText={captureForm.touched.country && captureForm.errors.country}
                                name="country"
                                label="Select Country"
                                variant="outlined"
                                onChange={(e, value) => captureForm.setFieldValue('country', value)} /**/
                                onBlur={() => captureForm.setFieldTouched('country', true)}
                                fullWidth
                            />
                        )}
                        renderOption={option => (
                            <React.Fragment>
                                <img
                                    style={{height: 30, width: 30}}
                                    src={`data:image/jpeg;base64,${option.image.data}`}
                                ></img>{' '}
                                &nbsp;&nbsp;&nbsp;
                                {option.listDescription}
                            </React.Fragment>
                        )}
                    />
                </div>
            ) :
            (
                <div>Loading...</div>
            );