'Format Numberfield in percentages

We have a NumberField which we want to use for a percentage value and used this:

<NumberField source="fee"  options={{ style: 'percent' }} sortable={false} />

However, our API sends the value as a string because it is not represented as a float. This seems to break the NumberField as the options are not picked up and the value is displayed as we receive it in the API response.

Is there a way to change the string "0.05" into 5% in react-admin fields?



Solution 1:[1]

NumberField uses Intl.NumberFormat() to format a number. Intl.NumberFormat() accepts 2 inputs: locales and options. Now look how Intl.NumberFormat() works:

const number = "0.05";

// without locales
console.log(new Intl.NumberFormat({ style: 'percent' }).format(number)); // result 0,05

// with locales
console.log(new Intl.NumberFormat('en-IN', { style: 'percent' }).format(number)); // result 5%

As you can see, if you don't use locales, the output is equal to the input. But if you use 'en-IN' locales, Intl.NumberFormat() returns 5%.

So you have to modify your code in this way:

<NumberField source="fee" locales="en-IN" options={{ style: 'percent' }} sortable={false} />

Solution 2:[2]

The easiest solution was to build a custom field component:

const PercentageField = ({source}) => {
    const record = useRecordContext();
    const absoluteValue = get(record, source);
    const options ={style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 6}
    const relativeValue = Intl.NumberFormat('de-CH', options).format(absoluteValue)
    
    return record ? 
    <Typography component="span" variant="body2">
        {relativeValue}
    </Typography> : null;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Giovanni Esposito
Solution 2 Heikkisorsa