grouping the data based on one property antd table - reactjs

I am trying to group the data currently its working for three, if i remove any one gender then i wont be able to get it the same design,
Basically if the state_name is same then it should be grouped into same even there is only one gender or more than one as shown below
Codesandbox

Figured out the issue, basically having a variable outside, when the sameKey repeats not setting the count making rowSpan as 0 so it will be hidden.
Logic
let sameKey;
const columns = [
{
title: "District",
dataIndex: "state_name",
key: "state_name",
render: (value, row, index) => {
const obj = {
children: value,
props: {}
};
if (!(sameKey !== value)) {
obj.props.rowSpan = 0;
return obj;
}
const count = data.filter(item => item.state_name === value).length;
sameKey = value;
obj.props.rowSpan = count;
return obj;
}
},
See the codesandbox

Related

DropDownPicker worked after clicking second time only

I have two dropdown picker. One is dependent on another one. If I click color on one dropdown another dropdown should show list of colors but its not working properly. If I click on first dropdown first time and select color second dropdown shows nothing but when I click on color again it shows the result in second dropdown.
Not sure why its happening
Here is my slack link:
https://snack.expo.dev/#anamika1593/carlist
I fixed your code. Your problem was that you set the state in function and then you used the variable from the state "selected" but when you set the state. The Variable doesn't change immediately and you used "old value" from the state.
if (item.label === "Color") {
const colorData = [...new Set(data.map((val) => val.car_color))];
var color = colorData.map(function (val, index) {
return {
id: index,
value: val,
label: val,
};
});
return setChildValue(color)
} else if (item.label === "Model") {
const modelData = [...new Set(data.map((val) => val.car_model))];
var model = modelData.map(function (val, index) {
return {
id: index,
value: val,
label: val,
};
});
return setChildValue(model)
} else if (item.label === "Year") {
const yearData = [...new Set(data.map((val) => val.car_model_year))];
var year = yearData.map(function (val, index) {
return {
id: index,
value: val,
label: val,
};
});
return setChildValue(year)
}
You have to do it like this and use item that you put in the function.
Fixed code

Semantic UI dropdown not setting value after selecting option

I am using React semantic ui. I am rendering a dropdown in Fieldset. I have written code such that, once a option is selected, the options is updated such that the selected option is removed from the list. But when I select an option from the dropdown, the selected value is not displayed, rather it shows empty.
Here is my code:
This is my dropdown code:
<Dropdown
name={`rows.${index}.mainField`}
className={"dropdown fieldDropdown"}
widths={2}
placeholder="Field"
fluid
selection
options={mainFieldOptions}
value={row.mainField}
onChange={(e, { value }) => {
setFieldValue(`rows.${index}.mainField`, value)
updateDropDownOptions(value)
}
}
/>
My options:
let mainField = [
{ key: "org", text: "org", value: "org" },
{ key: "role", text: "role", value: "role" },
{ key: "emailId", text: "emailId", value: "emailId" },
]
Also, I have:
const [mainFieldOptions, setMainFieldOptions] = useState(mainField)
And,
const updateDropDownOptions = (value:any) => {
let updatedOptions: { key: string; text: string; value: string }[] = []
mainFieldOptions.forEach(option => {
if(option.key != value){
updatedOptions.push({ key:option.key , text:option.key, value:option.key })
}
})
setMainFieldOptions(updatedOptions)
console.log("mainfield", mainField)
}
In onChange, if I dont call updateDropDownOptions() method, the dropdown value is set. But when I call the method, its giving blank value. Please help.
There are few changes required in your code,
You are pushing the entire initialValues when you are adding a row which is an [{}] but you need to push only {} so change your code to initialValues[0] in your push method.
Its not needed to maintain a additional state for the options. You can filter the options based on the selected option in other rows which is available in the values.rows .
Util for filtering the options
const getMainFieldOptions = (rows, index) => {
const selectedOptions = rows.filter((row, rowIndex) => rowIndex !== index);
const filteredOptions = mainField.filter(mainFieldOption => !selectedOptions.find(selectedOption => mainFieldOption.value === selectedOption.mainField));
return filteredOptions;
}
Call this util when rendering each row
values.rows.length > 0 &&
values.rows.map((row, index) => {
const mainFieldOptions = getMainFieldOptions(values.rows, index);
Working Sandbox

Delete an array item from an array in reactjs [duplicate]

I am trying to remove a (semi) deeply nested item from an array using setState but it doesn't seem to be working. My state is structured as follows:
state = {
currentSeries: null,
currentRowIndex: null,
rows: [
{
id: shortid.generate(),
nodes: [],
series: [], // array with item I want to remove
},
],
};
and my remove item call:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const index = prevState.rows.findIndex(x => x.id === rowId);
const series = prevState.rows[index].series.filter(s => s.id !== modelElementId);
return series;
});
};
I tried spreading the remaining state is several ways but it does not seem to update properly. I the rowId and modelElementId are correct and I can verify they do filter the correct item out. I am just having trouble on what to return. I know it is something simple but for the life of me I can't see it.
My recommendation would be to use .map to make things are bit easier to digest. You can then write it like so:
onRemoveModelElementClick = (rowId, modelElementId) => {
const updatedRowsState = this.state.rows.map(row => {
// this is not the row you're looking for so return the original row
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
// spread properties (id, node, series)
...row,
// overwrite series with item filtered out
series: filteredSeries,
};
});
// since rest of the state doesn't change, we only need to update rows property
this.setState('rows', updatedRowsState);
}
Hope this helps and let me know if you have any questions.
I think the issue here is how your code uses setState. The setState function must return an object. Assuming your filtering functions are correct as you describe, return an object to update the state:
return { series };
setState documentation
Here is what I did to get it working in case it can help someone else:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const updatedRowState = prevState.rows.map((row) => {
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
...row,
series: filteredSeries,
};
});
return {
rows: updatedRowState,
};
});
};
All credit to Dom for the great idea and logic!

Ant design table row merge based on data instead of index value

{
title: 'Home phone',
colSpan: 2,
dataIndex: 'tel',
render: (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index === 2) {
obj.props.rowSpan = 2;
}
// These two are merged into above cell
if (index === 3) {
obj.props.rowSpan = 0;
}
if (index === 4) {
obj.props.colSpan = 0;
}
return obj;
},
},
In dis example based on index value rowsspan size is decided, can we do that based on previous column data (if there are two John Brown's then row span should be 2)?. So basically we need to decide row span size by sorting rows and comparing row value.
https://stackblitz.com/edit/react-bubauz?file=index.js
I can give you an idea with name column, mb it helps you.
If you want to merge Name column:
First of all you need to sort your table data.Then create Set(). And you need clear Set in useEffect().
const names = new Set();
{
title: 'Name',
rowSpan: 1,
dataIndex: 'name',
render: (value, row, index) => {
const obj = {
children: value,
props: {}
};
if (names.has(value)) {
obj.props.rowSpan = 0;
} else {
const occurCount = tableData.filter((data) => data.name === value).length;
obj.props.rowSpan = count;
names.add(value);
}
return obj;
}
}

React - remove nested array item using setState function call

I am trying to remove a (semi) deeply nested item from an array using setState but it doesn't seem to be working. My state is structured as follows:
state = {
currentSeries: null,
currentRowIndex: null,
rows: [
{
id: shortid.generate(),
nodes: [],
series: [], // array with item I want to remove
},
],
};
and my remove item call:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const index = prevState.rows.findIndex(x => x.id === rowId);
const series = prevState.rows[index].series.filter(s => s.id !== modelElementId);
return series;
});
};
I tried spreading the remaining state is several ways but it does not seem to update properly. I the rowId and modelElementId are correct and I can verify they do filter the correct item out. I am just having trouble on what to return. I know it is something simple but for the life of me I can't see it.
My recommendation would be to use .map to make things are bit easier to digest. You can then write it like so:
onRemoveModelElementClick = (rowId, modelElementId) => {
const updatedRowsState = this.state.rows.map(row => {
// this is not the row you're looking for so return the original row
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
// spread properties (id, node, series)
...row,
// overwrite series with item filtered out
series: filteredSeries,
};
});
// since rest of the state doesn't change, we only need to update rows property
this.setState('rows', updatedRowsState);
}
Hope this helps and let me know if you have any questions.
I think the issue here is how your code uses setState. The setState function must return an object. Assuming your filtering functions are correct as you describe, return an object to update the state:
return { series };
setState documentation
Here is what I did to get it working in case it can help someone else:
onRemoveModelElementClick = (rowId, modelElementId) => {
this.setState((prevState) => {
const updatedRowState = prevState.rows.map((row) => {
if (row.id !== rowId) {
return row;
}
const filteredSeries = row.series.filter(s => s.id !== modelElementId);
return {
...row,
series: filteredSeries,
};
});
return {
rows: updatedRowState,
};
});
};
All credit to Dom for the great idea and logic!

Resources