The code below is a form in my react app which shows up when a user edits a record from a data table - datatable and edit part is not shown here as it's not relevant.
Explanation of Tab Mismatch issue :
As soon as the below page loads, I see the following tabs (image below) on the UI with Tab1
highlighted:
The network tab of my browser shows the following web service call:
First webservice call for Tab1
:
https://myserver.com/MyServices/api/assets/search/getAssetCategories?requestId=100&assetCategoryId=0
Similarly, when I click Tab 2
, the web service call is :
Second webservice call for Tab2
:
https://myserver.com/MyServices/api/assets/search/getAssetCategories?requestId=100&assetCategoryId=1
And with Tab 3
, it's :
Third webservice call for Tab3
:
https://myserver.com/MyServices/api/assets/search/getAssetCategories?requestId=100&assetCategoryId=2
As you can see, since I am sending the value of selectedTabIndex
for the parameter assetCategoryId
in my webservice call in the useEffect
function and value of event.index
for the parameter assetCategoryId
inside onTabSelected
function. , the Tab1
is highlighted because of 0
value of selectedTabIndex
inside useEffect
function and hence the
//Inside useEffect function
params: { assetCategoryId: selectedTabIndex }
//Inside onTabSelected function
params: {assetCategoryId: event.index}
However, since I have the following available:
const assetCategories = JSON.parse('[{"id":1,"value":"Tab 1"},{"id":2,"value":"Tab 2"},{"id":3,"value":"Tab 3"}]');
Question 1.
Inside useEffect
function, I want to send first value of the id
field to the assetCategoryId
parameter instead of the selectedTabIndex while calling the webservice call. Is it possible to do this? I mean I did like this assetCategores[0].id
and it worked but is this a good way to achieve this?
Question 2.
I want to keep the activeIndex
value based on the first id parameter, which is 1
in my case and not based on selectedTabIndex
like it is in my code now:
<TabView id='AssetsTabView' activeIndex={selectedTabIndex}
One another issue which could arise is when the values of id
could be like this and I would still want to display Tab1
, Tab2
and Tab3
properly:
const assetCategories = JSON.parse('[{"id":34,"value":"Tab 1"},{"id":66,"value":"Tab 2"},{"id":999,"value":"Tab 3"}]');
My complete code below:
import React, { useState, useEffect } from 'react';
import { Form, withFormik} from 'formik';
import {Button} from '@material-ui/core'
import axios from 'axios'
import {TabPanel, TabView} from "primereact/tabview";
const RequestForm = (props) => {
const {values, setFieldValue, touched, errors, isSubmitting, handleReset, handleChange} = props;
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
useEffect(() => {
if(props.dataRequest){
let editeddataRequestId = props.dataRequest.requestId;
axios
.get('api/assets/search/getAssetCategories?requestId='+editeddataRequestId, {
params: {
assetCategoryId: selectedTabIndex
}
}).then(response => {
}).catch(err => console.log(err));
}//end if of props.dataRequest
}, []);
var onTabSelected = (event) => {
(event.index) ? setSelectedTabIndex(event.index) : null
if(props.dataRequest){
let editeddataRequestId = props.dataRequest.requestId;
axios
.get('api/assets/search/getAssetCategories?requestId='+editeddataRequestId, {
params: {
assetCategoryId: event.index
}
}).then(response => {
}).catch(err => console.log(err));
}
};
const assetCategories = JSON.parse('[{"id":1,"value":"Tab 1"},{"id":2,"value":"Tab 2"},{"id":3,"value":"Tab 3"}]');
const DynamicTabView = ({ activeIndex, onTabChange }) => (
<div style={{width: 'max-content', whiteSpace: 'nowrap', marginLeft: 'auto', marginRight: 'auto'}}>
<TabView id='AssetsTabView' activeIndex={selectedTabIndex}
onTabChange={(e) => setSelectedTabIndex(e.index), (e) => onTabSelected(e)}>
{assetCategories.map((item, i) =>
<TabPanel key={i} header={item.value}></TabPanel>
)}
</TabView>
</div>
);
return (
<div>
<Form className="form-column-3">
<DynamicTabView activeIndex={selectedTabIndex} onTabChange={(e) => {setSelectedTabIndex(e.index), () => { this.onTabSelected(e) }}}/>
<Button size="large" variant="contained" color="primary" onClick={props.onCancel} style={{marginLeft: '5px'}} type="button">Cancel</Button>
</Form>
</div>
)
};
export const DataRequestEnhancedFormEdw = withFormik({
mapPropsToValues: props => {
return {}
},
})(RequestForm)