Tabs in react not displaying appropriate content - node.js

I am using the Tab from semantic-ui-react. I need to display a list of days and their corresponding events for that day. However, an event created in one day shows up in the other day too.
As seen, I created an event in day 1, but it shows up in day 2, which is incorrect. Here's how I generate the tab data:
const panes = selectedDays.map((day, index) => {
const count = index + 1;
return {
menuItem: `Day ${count}`,
render: () => <Tab.Pane><Agenda day={day} index={count} /></Tab.Pane>
};
});
this.setState({ panes });
Component Code
{
currentIndex === 3 &&
<Fragment>
<Tab
menu={{ pointing: true }}
panes={this.state.panes}
/>
<Button className='formnext' onClick={this.handlePrevious}>
<FontAwesome name='angle-left' style={{ color: 'white', fontSize: '2.2rem' }} className='logout' />
</Button>
<Button className='formnext' onClick={this.handleNext}>
<FontAwesome name='angle-right' style={{ color: 'white', fontSize: '2.2rem' }} className='logout' />
</Button>
</Fragment>
}
If I add a key attribute to the Tab.Pane or Agenda component, clicking on a tab header, just clears my state and I am left with no data. Any idea how to solve this one?

Related

How Can I Test an MUI ToggleButtonGroup with a userEvent?

I am using MUI ToggleButtonGroup component like so:
<ToggleButtonGroup
color="primary"
value={mode}
exclusive
onChange={changeHandler}
fullWidth
className="mt-4"
>
<ToggleButton value="login">Login</ToggleButton>
<ToggleButton value="register">Register</ToggleButton>
</ToggleButtonGroup>
When clicking the 'Register' button, it works fine in the UI. I'd like to get a proper test written with React Testing Library.
Here's what I have:
setup();
heading = screen.getByRole("heading", { level: 2 });
const registerButton = screen.getByRole("button", { name: /register/i });
userEvent.click(registerButton);
expect(heading).toHaveTextContent("Register");
The crux of the issue seems to be that userEvent.click somehow doesn't call the changeHandler. Is there some type of bubbling or something that I need to concern myself with?
Here's a prettyDOM log of the relevant components:
<button
aria-pressed="false"
class="MuiButtonBase-root MuiToggleButton-root MuiToggleButton-fullWidth MuiToggleButton-sizeMedium MuiToggleButton-primary MuiToggleButtonGroup-grouped MuiToggleButtonGroup-groupedHorizontal css-j4p6el-MuiButtonBase-root-MuiToggleButton-root"
tabindex="0"
type="button"
value="register"
>
Register
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button> <h2
class="MuiTypography-root MuiTypography-h5 css-ag7rrr-MuiTypography-root"
>
Login
</h2>
Add an id to the component:
<ToggleButton id={${data.value}}> {data.label}
test case:
describe("ToggleButtonGroupComponent onChange Testing", () => {
const onChange = vi.fn();
it("toggle group change value and new value updated and last value no more checked", () => {
const { container } = render(<ToggleButtonGroupComponent {...props} onChange={onChange} />);
// Before change selection
const allValueToggleButton = QueryAttributeById(container, "ssh") as HTMLInputElement;
expect(allValueToggleButton.value).toEqual("ssh");
// Change selection
const withValueToggleButton = QueryAttributeById(container, "http") as HTMLInputElement;
fireEvent.click(withValueToggleButton);
expect(withValueToggleButton.value).toEqual("http");
// Old value is no more checked
expect(allValueToggleButton.value).toEqual("ssh");
});
});

Reserving seats system in react

I am trying to make a reserving seats for my airline website. I have done a reserve seats button, when pressed, a page pops up, where it has the array of current available seats and checkboxes besides it in-order to choose your seats. All of these are going fine, but the thing is that when I checkboxes or remove the checkboxes, I need to save the values that I've checked in another array to send them back to the backend and in the backend, I am going to compare it to the previous array and remove the seats that have been chosen.
function Row(props){
const [AvailableFSeats, setfs] = useState();
const [fList,setfList]= useState([]);
const checkf= [];
useEffect(() => {
setfList(props.row.AvailableFSeats);
},[])
const handleChange = (event) => {
setState({
...state,
[event.target.name]: event.target.checked,
});
//checkf should be the array that contains the chosen seats in the current action.
if(event.target.name==="AvailableFSeats"&&event.target.checked===true){
checkf.push(event.target.label);}
}
const {AvailableFFSeats, AvailableEESeats, AvailableBBSeats} = state;
return(
<Box sx={{ display: 'flex' }}>
<FormControl sx={{ m: 3 }} component="fieldset" variant="standard">
<FormLabel component="legend">First Class Seats</FormLabel>
<FormGroup>
{fList.map(AvailableFSeats => (
<FormControlLabel
control={
<Checkbox checked={AvailableFFSeats} onChange={handleChange} name="AvailableFSeats" />
}
label={AvailableFSeats}
/>)
)}
</FormGroup>
</FormControl>
</Box>
)
}

How Do I Correctly use CellMeasurer to set Table Column Width Based on the Content Length?

I'm trying to dynamically set the column width using CellMeasurer in a dynamic created Columns.
// hoping that CellMeasurer is what I needed to adjust
// width of my table columns, but not working.
const cellRenderer = ({ columnIndex, key, parent, rowIndex, style }) => {
const content = list[rowIndex][columnHeader[columnIndex].columnName];
return (
<CellMeasurer
cache={cache}
columnIndex={columnIndex}
key={key}
parent={parent}
rowIndex={rowIndex}
>
<div
style={{
...style,
height: 35,
whiteSpace: "nowrap"
}}
>
{content}
</div>
</CellMeasurer>
);
};
const cache = new CellMeasurerCache({
defaultWidth: 100,
minWidth: 75,
fixedHeight: true
});
return (
<AutoSizer>
{({ height, width }) => (
<div width={width}>
<Table
width={width}
height={500} // why can't i use {height} here?
headerHeight={40}
rowHeight={30}
rowCount={list.length}
rowGetter={({ index }) => list[index]}
>
// Dynamically create Column
{columnHeader.map((columnData, i) => (
<Column
width={800}
onClick={this.onHeaderClick}
label={columnData.displayName}
dataKey={columnData.columnName}
cellRenderer={cellRenderer}
{...this.props}
key={i}
/>
))}
</Table>
</div>
)}
</AutoSizer>
);
Here is the example code: https://codesandbox.io/s/mzj5y255kj
I want to set the column 'News' to as long as the length in the text.
Result would be that no matter what the content length is, the column will grow.

Adding checkbox in between text description in react native

I have a view where I display a Heading and details which I get from server as below.
Now, in the question description there is a tag __CB__ which I need to replace with the checkbox, so, instead of that tag there will be a checkbox and rest of the text will continue as usual. I have separated the text based on tag and placed a checkbox in between but I haven't been able to align the view, either it gets arranged columnwise or if I try to arrange in row the text doesn't continue. Here is what I've tried.
Try 1:
<ScrollView
style={styles.scrollStyle}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<View style={styles.checkBoxTextContainer}>
<Text style={styles.questionText}>{questionText1}</Text>
<CheckBox
style={styles.checkboxStyle}
onClick={this.checkboxClick}
isChecked={this.state.isChecked}
checkedImage={<Image source={Images.checkBoxTick} />}
unCheckedImage={<Image source={Images.checkBoxEmpty} />}
// leftText={questionText1}
// rightText={questionText2}
/>
<Text style={styles.questionText}>{questionText2}</Text>
</View>
</ScrollView>
Styles
checkBoxTextContainer: {
flex: 1,
flexDirection: "row"
},
checkBoxStyle: {
width: 20,
height: 20
}
Result:
Try 2:
<ScrollView
style={styles.scrollStyle}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<Text style={styles.questionText}>{questionText1}</Text>
<CheckBox
style={styles.checkboxStyle}
onClick={this.checkboxClick}
isChecked={this.state.isChecked}
checkedImage={<Image source={Images.checkBoxTick} />}
unCheckedImage={<Image source={Images.checkBoxEmpty} />}
// leftText={questionText1}
// rightText={questionText2}
/>
<Text style={styles.questionText}>{questionText2}</Text>
</ScrollView>
Result:
I need the checkbox to continue in between text like the tag in my original image. Any help is appreciated.
Below is sample working code for your scenario.
import React, { Component } from 'react'
import { View, Text, StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap'
},
cb: {
width: 10,
height: 10,
borderWidth: 2,
borderRadius: 2,
borderColor: 'red',
marginTop: 4,
marginHorizontal: 3,
}
})
const sampleData = [ 'Lorem', 'ipsum', 'dolor', 'sit', 'amet',
'CB',
'consectetur', 'adipiscing', 'elit.', 'Curabitur',
'CB',
' nunc', 'vel', 'scelerisque', 'tempus.', 'CB', 'Morbi', 'luc', 'abcd', 'xyzw'
]
const CheckBox = () => (
<View style={styles.cb} />
)
export default class CheckText extends Component {
renderData = (data) => {
const views = data.map((item) => {
if (item === 'CB') { return <CheckBox />}
return (<Text>{item}</Text>)
})
return views
}
render() {
return (
<View style={styles.container}>
{this.renderData(sampleData)}
</View>
)
}
}
And this is snapshot of output
Note:
I have parsed the text into array of strings. This is the key logic here. The way you decide to tokenize your input text will affect the rendering of your component. When I tried long strings as token, flexWrap: 'wrap' didn't work properly. See this issue for more details. Tokenizing into single words may do the job.
try to wrap the Text and Checkbox into <Text> tag.
Please try below solution. It may help you.
<ScrollView
style={styles.scrollStyle}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<View style={{
width:'100%',
flexDirection: "row"
}}>
// wrap into text tag
<Text>
// add space after first text
<Text style={styles.questionText}>{questionText1+" "}</Text>
<CheckBox
style={styles.checkboxStyle}
onClick={this.checkboxClick}
isChecked={this.state.isChecked}
checkedImage={<Image source={Images.checkBoxTick} />}
unCheckedImage={<Image source={Images.checkBoxEmpty} />}
/>
// add space before second text
<Text style={styles.questionText}>{" "+questionText2}</Text>
</Text>
</View>
</ScrollView>

Implemeting drawer in React native application

I just created my first interface in my React native app. I created a navbar in which there is a menu button to click, so the drawer opens and i can navigate from one screen to another. I intend to use this https://github.com/root-two/react-native-drawer.
I know i need to call open drawer in the menu button when click and here is the code i used, that displays an alert for now
openDrawer(){
this.drawer.open()
}
render() {
return (
<Container>
<Navbar
bgColor={'#C0C0C0'}
title={"Det globale flyktningbildet"}
titleColor="white"
left={{
icon: "ios-menu",
iconColor: "#FFFFFF",
// onPress: () => {alert('Toggle menu ')}
onPress: () => {this.props.openDrawer}
}}
/>
<Drawer
type="static"
// content={<ControlPanel />}
openDrawerOffset={100}
styles={{main: {shadowColor: "#000000", shadowOpacity: 0.4, shadowRadius: 3}}}
tweenHandler={Drawer.tweenPresets.parallax}>
</Drawer>
<View>
<Image
source = { require('./../images/image1_2.png')}
style={[styles.image1, {resizeMode: 'contain'}]}
/>
</View>
</Container>
);
}
So can you please help me implemet the drawer and navigate between different screens
Go through example code in github you will get the idea or you can refer https://stackoverflow.com/a/42748086/6423570
EDIT
You should wrap root container of the screen with Drawer component. The <ControlPanel /> component is the content that should be displayed in the drawer. You could use Touchable Components in the <ControlPanel /> and navigator to navigate between screens. And the openDrawer function is not a prop, call it as this.openDrawer
render() {
return (
<Drawer
type="static"
// content={<ControlPanel />}
openDrawerOffset={100}
styles={{
main: {
shadowColor: "#000000",
shadowOpacity: 0.4,
shadowRadius: 3
}
}}
tweenHandler={Drawer.tweenPresets.parallax}
>
<Container>
<Navbar
bgColor={'#C0C0C0'}
title={"Det globale flyktningbildet"}
titleColor="white"
left={{
icon: "ios-menu",
iconColor: "#FFFFFF",
// onPress: () => {alert('Toggle menu ')}
onPress: () => {this.openDrawer}
}}
/>
<View>
<Image
source = { require('./../images/image1_2.png')}
style={[styles.image1, {resizeMode: 'contain'}]}
/>
</View>
</Container>
</Drawer>
);
}

Resources