llioor
llioor

Reputation: 6238

BooleanField with FunctionField change number to Boolean

I have question and I'm sure it will help other developers. I have field "is_active" which is Boolean in my API side but it return 0 or 1 and not TRUE or FALSE. I want to use <FunctionField/> to wrap the <BooleanField/> but it didn't work. Someone can help please.

This is my code:

<FunctionField source="is_active" label="is_active" render={(record) => record.is_active ? true : false}>
  <BooleanField/>
</FunctionField>

The column is still blank.

Thanks.

Upvotes: 1

Views: 2043

Answers (3)

rafahoro
rafahoro

Reputation: 1267

I had an issue where the in a DB table there was a field called disabled but in the Admin was a bit confusing setting disabled to false to actually enable something.

Based on 'Dennie de Lange' answer, I have created a Typescript generic BooleanOppositeField and BooleanOppositeInput. Putting here hoping may help someone:

import { BooleanField, BooleanInput, FunctionField } from 'react-admin';


interface IProps {
  label: string;
  source: string;
}

/**
 * Usually called using:
 *   <BooleanOppositeField label="Enabled" source="disabled"/>
 */
export const BooleanOppositeField = (props: IProps) => {
  return (
    <FunctionField {...props} render={(record: any | undefined, source: string | undefined) =>
      <BooleanField source="enabled" record={{ ...record, enabled: !(record![source!]) }} />}
    />
  );
};


/**
 * Usually called using:
 *   <BooleanOppositeInput label="Enabled" source="disabled" />
 */
export const BooleanOppositeInput = (props: IProps) => {
  return (
    <BooleanInput format={(v: boolean) => !v} parse={(v: boolean) => !v} {...props} />
  )
}

And you can use it by:

<BooleanOppositeField label="Enabled" source="disabled"/>

or

<BooleanOppositeInput label="Enabled" source="disabled" />

Note: I liked more this solution, than the recommended by Dennie

Upvotes: 0

Oleg K
Oleg K

Reputation: 61

Here is my solution: (you can import it and use instead of BooleanField)

import React from 'react';
import { BooleanField } from "react-admin";

export const BooleanNumField = ({ record = {}, source}) => {
  let theRecord = {...record};

  theRecord[source + 'Num'] = !!parseInt(record[source]);

  return <BooleanField record={theRecord} source={source + 'Num'} />
}

Upvotes: 1

Dennie de Lange
Dennie de Lange

Reputation: 2934

I think you misunderstood the FunctionField component. It renders the result of the render prop. What you are trying to achieve is:

<FunctionField source="is_active" label="is_active" render={(record,source) => 
    <BooleanField record={{...record,is_active:!!record.is_active}} source={source}/>}/>

But this is not very nice. Better is to wrap your dataProvider/restClient and ensure the data is a boolean.

// In FixMyDataFeature.js
export default restClient => (type, resource, params) => restClient(type,resource,params).then(response=>
   if(resource === 'Resource_with_numeric_is_active_field`){
      return {
         data: mutateIsActiveFieldToBoolean(response.data)
      }
   }
   else{
      return response;
   }
);

And call it with Admin:

<Admin dataProvider={FixMyDataFeature(dataProvider)}... />

Upvotes: 8

Related Questions