How to mark options as selected - reactjs

How can i set selected atribute to options inside of <SelectArrayInput> component? I have not realized how to set selected atribute yet.
I have already tried to put there a attribute selected, but it doesnt seem to work.
const tec = [
{ name: "Apple", id: 1, selected: true},
{ name: "Facebook", id: 2 },
{ name: "Netflix", id: 3 },
{ name: "Tesla", id: 4 },
];
const ReferrenceSelectBox = ({ source, record = {} }) => <SelectArrayInput choices={ tec } />;
ReferrenceSelectBox.propTypes = {
label: PropTypes.string,
record: PropTypes.object,
source: PropTypes.string.isRequired,
};
export default ReferrenceSelectBox;
I expect the output of <SelectArrayInput> with already selected options.

I am not able to get a code sandbox working with react-admin, but from the documentation it looks like it is using the Select from Material-ui as the base.
In Material-UI you can pass the values to be selected as a prop: value which takes an array of the ids that you want.
So, in your case, instead of having selected attribute, you can create another array which captures the selectedIds and pass it as value prop and it should work.
const tec = [
{ name: "Apple", id: 1},
{ name: "Facebook", id: 2 },
{ name: "Netflix", id: 3 },
{ name: "Tesla", id: 4 },
];
const selectedTec = [1];
const ReferrenceSelectBox = ({ source, record = {} }) => <SelectArrayInput value={ selectedTec } choices={ tec } />;
ReferrenceSelectBox.propTypes = {
label: PropTypes.string,
record: PropTypes.object,
source: PropTypes.string.isRequired,
};
export default ReferrenceSelectBox;

Related

How to update nested state in redux

I'm a bit stuck with redux. I want to create reducer that can update state onClick with data that provided in each button.
Here's my TabSlice.ts
interface ITabContext {
tabIndex: number,
posterUrlFetch: string,
tabData: {
fetchUrl: string;
title: string;
}[]
}
const initialState = {
tabIndex: 0,
posterUrlFetch: 'movie/popular',
tabData: [
{ fetchUrl: 'movie/popular', title: 'Trending' },
{ fetchUrl: 'movie/upcoming', title: 'Upcoming' },
{ fetchUrl: 'tv/popular', title: 'TV Series' },
]
}
const tabSlice = createSlice({
name: 'tab',
initialState: initialState as ITabContext,
reducers: {
changeTab(state, action: PayloadAction<ITab>) {
const newItem = action.payload;
return state = {
tabIndex: newItem.tabIndex,
posterUrlFetch: newItem.posterUrlFetch,
tabData: [
{ fetchUrl: newItem.posterUrlFetch, title: newItem.posterUrlFetch },
]
}
}
}
})
Then I dispatch changeTab in my component and create function onClick:
const click = () => dispatch(changeTab({
tabIndex: 1,
posterUrlFetch: 'movie/popular',
tabData: [
{
fetchUrl: 'tv/latest',
title: 'TV Latest'
},
{
fetchUrl: 'movie/popular',
title: 'Popular'
},
{
fetchUrl: 'movie/latest',
title: 'Latest'
},
]
}));
As i click some info updates, but in tabData I have only first object. How to make it to push all data to tabData, not only first one? Thanks!
Remove return state = {} from your reducer function and instead return the object as a whole.
return {
tabIndex: newItem.tabIndex,
posterUrlFetch: newItem.posterUrlFetch,
tabData: newItem.tabData,
};
For the payload's tabData you can pass newItem.tabData

TableRow: Unexpected any. Specify a different type

Building a Table component using TS followed this to type everything as needed.
But as I broke down the row in it's separate component i am unable to type it properly.
export interface ITableRow<DataType> {
rowData: any; // The Issue is with this line
columnKeys: Array<DataType>;
}
function getTableRow<T>({ rowData, columnKeys }: ITableRow<T>) {
return columnKeys.map((columnKey, index) => (
<td key={index}>{rowData[columnKey]}</td>
));
}
export function TableRow<T>({ rowData, columnKeys }: ITableRow<T>) {
const tableRow = getTableRow({ rowData, columnKeys });
return <tr>{tableRow}</tr>;
}
The rowData prop is an object that can have any number of keys as specified in the headers object
for example:
const heads = [
{
id: 'company',
label: 'Company'
},
{
id: 'nb_employees',
label: 'Number of employees'
},
{
id: 'country',
label: 'Country'
}
];
const rows = [
{
company: 'Vody aho',
nb_employees: 1590,
country: 'Hong Kong'
},
{
company: 'Royal spirit',
nb_employees: 15,
country: 'USA'
},
];
How do I type the rowData dynamically in this case?
I tried any and it worked but then it's useless to use TS at all,
I tried extends as well but i don't think i understand it well so that failed as well

How to set state in nested array of objects in ReactJs?

I have this object as a state in reactjs. I want to add another object inside the "childoptions: []" array which is nested inside the options array on button click.
How can I achieve this, pls help...
const [select1, setSelect1] = useState({
id: uuid(),
type: 'select',
properties: {
label: 'Select1',
options: [
// {
// id: uuid(),
// optionName: 'red 🔴',
// value: '',
// childOptions: [],
// },
// {
// id: uuid(),
// optionName: 'green 🟢',
// value: '',
// childOptions: [],
// },
// {
// id: uuid(),
// optionName: 'blue 🔵',
// value: '',
// childOptions: [],
// },
],
},
parentId: null,
});
This is achievable by copy the prevState in the new state with the new object inserted inside the options array.
A more detailed explanation could be found at https://stackoverflow.com/a/26254086/9095807
setSelect1((prevState) => {
return {
...prevState,
properties: {
label: 'Select1',
options: prevState.properties.options.map(obj => obj.id === id ? { ...obj, childOptions: [...obj.childOptions, newChildOptions] } : obj),
}
}
})

How can I treat an array of values to be a tuple that is inferred based on what's passed to it

I have a React component like this:
interface Props<T> {
data: {
items: T[]
}[]
}
const MyComponent = <T,>(props: Props<T>) => {
return ...
}
<MyComponent data={[
{
items: [{ name: 'A', age: 10 }, { name: 'B', age: 20 }]
},
{
items: [{ label: 'A', value: 25 }, { label: 'C', value: 50 }
}
]} />
In this example, I want the first data item to have T = {name: string, age: number} and the second data item to have T = { label: string, value: number }
I know that this is possible with tuples but I want to infer the tuple from the props that are passed to it.
Here you go
interface Props<T1, T2> {
data: [{ items: T1[] }, { items: T2[] }]
}
const MyComponent = <T1,T2>(props: Props<T1, T2>) => {
return null;
}
Which could be further optimized if needed.

Antd: set default value / setFieldsValue for Cascader when opening Modal

I have Antd's Cascader like this:
When I click on Edit button it open modal as below.
const showModal = (record) => {
console.log('record', record); // this is current record which has existing value to be displayed in cascader
form.setFieldsValue(record);
setVisible(true);
};
how do I feed initial values or existing values to Cascader?
<Cascader
defaultValue={['zhejiang', 'hangzhou', 'xihu']}
options={propertyOptions}
loadData={loadCompanies}
onChange={onChange}
changeOnSelect
/>
using defaultValue prop like does not seem to work.
When I load propertyOptions, it loads with values like
property1,
property2
When I click on property1 it loads children dynamically.
so selected value is e.g. property1 > company1
but When I click on Edit modal it has only parent values. (children won't be there as I load them on parent click).
When I click on modal it has the whole item data so maybe I can use it to show like hardcoded value or something?
UPDATE:
This is how I fill propertyOptions
function setPropertiesAsOptions(propertiesQuerySnapshot) {
propertiesQuerySnapshot.forEach((doc) => {
options.push({
value: doc.id,
label: doc.data().propertyName,
isLeaf: false,
});
});
setPropertyOptions(options);
}
Is there propertyOptions has value names like zhejiang or other?
In your case this data should work properly as options
const options = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
So it's mean that value name should be the same as params in defaultValue

Resources