Pass value between tabs on onClick event in ReactJS - javascript

This is the component I am working on. I have three tab named newOrder, currentOrder and orderHistory.
How can I move a card in New Order tab, to Current Order tab when I press 'Accept' button on card.
export default class Driver extends Component {
constructor(props, context) {
super(props, context);
this.state = {
key: 'home',
};
}
render() {
return (
<Tabs id="controlled-tab-example" activeKey={this.state.key}
onSelect{key => this.setState({ key })}>
<Tab eventKey="newOrder" title="New Order">
//this is the card with Accept button.
<div class="card">
<div class="card-body">
<Button type="button>Accept</Button>
</div>
</div>
</Tab>
<Tab eventKey="currentOrder" title="Current Order"></Tab>
<Tab eventKey="orderHistory" title="OrderHistory"></Tab>
</Tabs>
);
}
}

This can be achieved by using the component state. You may refer this link: https://reactjs.org/docs/state-and-lifecycle.html

Related

How to make a button click another button from different components in React

I'm new to react and it is kinda hard to understand the one way data flow on it, i was making a simple app and i'm using mdbootstrap for some ready bootstrap components, I imported the component of a modal (which has a button when clicked it toggles a modal) so in my app i have cards, each one has a button that's supposed to toggle the button, but i couldn't figure out how to link the card's button with the mdbootstrap component's button.
The Card component:
import React, { Component } from 'react';
import ModalPage from './modal.jsx'
class Card extends Component {
render() {
return (
<div>
<div className="card m-5" style={{ width: '18rem' }}>
<img src={this.props.img} className="card-img-top" />
<div className="card-body">
<h5 className="card-title">{this.props.title}</h5>
<p className="card-text">{this.props.desc}</p>
<button onClick={/*I don't know what exactly i should put here */}></button>
</div>
</div>
</div>
)
}
}
export default Card;
The modal componant:
import React, { Component } from 'react';
import { MDBContainer, MDBBtn, MDBModal, MDBModalBody, MDBModalHeader, MDBModalFooter } from 'mdbreact';
class ModalPage extends Component {
state = {
modal13: false
}
toggle = nr => () => {
let modalNumber = 'modal' + nr
this.setState({
[modalNumber]: !this.state[modalNumber]
});
}
render() {
return (
<MDBContainer>
{/* This is the button I want to click when clicking the card's button */}
<MDBBtn color="primary" onClick={this.toggle(13)}>
Modal
</MDBBtn>
<MDBModal isOpen={this.state.modal13} toggle={this.toggle(13)}>
<MDBModalHeader toggle={this.toggle(13)}>
{this.props.title}
</MDBModalHeader>
<MDBModalBody>
{/* edit here */}
{this.props.content}
</MDBModalBody>
<MDBModalFooter>
<MDBBtn color="secondary" onClick={this.toggle(13)}>
Close
</MDBBtn>
<MDBBtn color="primary">Save changes</MDBBtn>
</MDBModalFooter>
</MDBModal>
</MDBContainer>
);
}
}
export default ModalPage;
Rather than having 2 click events you only need one on the child component. Instead of trying to send a click to the parent button in order to call toggle() just pass the toggle function to the child to be called:
Card:
import React, { Component } from 'react';
import ModalPage from './modal.jsx'
class Card extends Component {
render() {
return (
<div>
<div className="card m-5" style={{ width: '18rem' }}>
<img src={this.props.img} className="card-img-top" />
<div className="card-body">
<h5 className="card-title">{this.props.title}</h5>
<p className="card-text">{this.props.desc}</p>
//*****************************************
<button onClick={this.props.click}></button>
//*****************************************
</div>
</div>
</div>
)
}
}
export default Card;
Modal:
import React, { Component } from 'react';
import { MDBContainer, MDBBtn, MDBModal, MDBModalBody, MDBModalHeader, MDBModalFooter } from 'mdbreact';
class ModalPage extends Component {
state = {
modal13: false
}
toggle = nr => () => {
let modalNumber = 'modal' + nr
this.setState({
[modalNumber]: !this.state[modalNumber]
});
}
render() {
return (
<MDBContainer>
{/* I am assuming that this is a reference to <Card /> - simply pass in the onClick function as a parameter. You can even use onClick here and this.props.onClick in the child element */}
<MDBBtn color="primary" click={this.toggle(13)}>
Modal
</MDBBtn>
<MDBModal isOpen={this.state.modal13} toggle={this.toggle(13)}>
<MDBModalHeader toggle={this.toggle(13)}>
{this.props.title}
</MDBModalHeader>
<MDBModalBody>
{/* edit here */}
{this.props.content}
</MDBModalBody>
<MDBModalFooter>
<MDBBtn color="secondary" onClick={this.toggle(13)}>
Close
</MDBBtn>
<MDBBtn color="primary">Save changes</MDBBtn>
</MDBModalFooter>
</MDBModal>
</MDBContainer>
);
}
}
export default ModalPage;

Pass value from one tab to another tab in ReactJs

I am working on ReactJS and was wondering on how can I pass value between tabs.
Below is the component I am working on. I have three tab and want to pass the card from one tab to another on clicking accept button.
import React, { Component } from 'react'
import DriverPlacedOrder from './DriverPlacedOrder';
import {Link }from 'react-router-dom';
import {Tabs,Tab} from 'react-bootstrap';
export default class Driver extends Component {
constructor(props, context) {
super(props, context);
this.state = {
key: 'home',
};
}
render() {
return (
<Tabs
id="controlled-tab-example"
activeKey={this.state.key}
onSelect={key => this.setState({ key })}
>
<Tab eventKey="newOrder" title="New Order">
<div class="container">
<div class="card" style={{width:'100%',borderRadius:'2%', border: '4px solid lightgreen'}}>
<div class="card-body" style={{textAlign:'center'}}>
<h4 class="card-title">{CID}</h4>
<p class="card-text"><h5>{RID}</h5></p>
<Button variant="outline-success"onClick={} style={{width:'33%'}}><i class="fas fa-check-circle fa-lg"></i><br/>Accept</Button>
<Button variant="outline-primary" style={{width:'33%'}}><i class="fas fa-book-open fa-lg" fa-lg></i><br/>View</Button>
</div>
</div>
</div>
</Tab>
<Tab eventKey="currentOrder" title="Current Order">
</Tab>
<Tab eventKey="orderHistory" title="OrderHistory">
</Tab>
</Tabs>
);
}
}
Onclicking accept button how can I pass card from NewOrder tab to currentOrder tab?
I am working on ReactJS and was wondering on how can I pass value
between tabs.
<Tab my_data={my_data_value} eventKey="orderHistory" title="OrderHistory">
</Tab>
If I understand your question correctly, you want to re-use the card markup for each tab, and also allow navigation between tabs via that same card markup.
One way to achieve that would be to define a method such as renderCard() that renders that common markup. You'd then call that method when rendering the contents of each <Tab> component. Something to keep in mind also is that renderCard() may need a parameter to specify which tab the "Accept" button navigates to:
export default class Driver extends Component {
constructor(props, context) {
super(props, context);
this.state = { key: 'newOrder' };
}
/* Define render card function. Takes nextKey parameter that controls what tab the Accept button will navigate to */
renderCard(nextKey) {
return (<div class="card" style={{width:'100%',borderRadius:'2%', border: '4px solid lightgreen'}}>
<div class="card-body" style={{textAlign:'center'}}>
<h4 class="card-title">{'CID'}</h4>
<p class="card-text"><h5>{'RID'}</h5></p>
<Button variant="outline-success"onClick={ () => {
this.setState({ key : nextKey })
}} style={{width:'33%'}}><i class="fas fa-check-circle fa-lg"></i><br/>Accept</Button>
<Button variant="outline-primary" style={{width:'33%'}}><i class="fas fa-book-open fa-lg" fa-lg></i><br/>View</Button>
</div>
</div>)
}
render() {
return (
<Tabs
id="controlled-tab-example"
activeKey={this.state.key}
onSelect={key => this.setState({ key })}>
<Tab eventKey="newOrder" title="New Order">
<div class="container">
{ /* Render card, and specify which tab the card's accept button will navigate to */ }
{ this.renderCard('currentOrder') }
</div>
</Tab>
<Tab eventKey="currentOrder" title="Current Order">
<div class="container">
{ /* Render card if this tab visible */ }
{ this.renderCard('orderHistory') }
</div>
</Tab>
<Tab eventKey="orderHistory" title="OrderHistory">
<div class="container">
{ /* Render card if this tab visible */ }
{ this.renderCard('newOrder') }
</div>
</Tab>
</Tabs>
);
}
}

How to change Modal state from outside the React class?

I am trying to call my modal by changing the state from outside the react class. But so far no luck. I tried the following:
I have a method named Portfolio which needs to activate the modal once user click on the Image
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={this.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>
Here is the Class that contain the state and the modal. But I cannot change state to activate the modal.
class Project extends React.Component
{
constructor(props, context) {
super(props, context);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
});
}
render(){
return (
<div className="row portfolioWrap">
// here resides our modal which activate once modal state changed
<div>
<Modal
isOpen={this.state.modal}
toggle={this.toggle}
className={this.props.className}>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>
{this.state.gallery.map(gallery =>
<img
className="card-img-top"
src={"/assets/imgs/project/"+gallery} alt="" />)
}
</ModalBody>
<ModalFooter></ModalFooter>
</Modal>
</div>
// calling portfolio method inside the loop
{currentTodos.map(item => <Portfolio key={item.title} portfolio={item} />)}
</div>
)
}
}
I am trying to activate the modal from Portfolio function. But since its outside the class scope i cannot access the state. Is there any way to accomplish this?
You can pass the toggle method to your Portfolio component then use it from the props.
<Portfolio key={item.title} toggle={this.toggle} portfolio={item} />
Then in Portfolio:
const Portfolio = (props) =>
<div className="col-sm-4">
<div className="mb-2">
<img
onClick={props.toggle}
className="card-img-top"
src={"/assets/imgs/project/"+props.portfolio.img_thumb}
alt="" />
</div>
</div>

Just refresh a tab or not the page

I'm having a little problem with ReactJs. I have a page with several tabs and in each tabs I have a button that refresh the page so when I click on the refresh button it goes back to tab 1 while the refresh happens in tab 2 while I want tab 2 to remain open after refresh.
I want after the refresh tab 2 stays open
Example photo:
Before refresh:
After refresh:
I want after the refresh tab 2 stays open...
Here is my code:
import React, { Component } from 'react';
import { render } from 'react-dom';
import { TabProvider, Tab, TabPanel, TabList } from 'react-web-tabs';
import 'react-web-tabs/dist/react-web-tabs.css';
import { Button } from 'semantic-ui-react'
import 'semantic-ui-css/semantic.min.css';
import './App.css';
class App extends Component {
render() {
return (
<TabProvider defaultTab="vertical-tab-one" vertical>
<section className="my-tabs">
<TabList className="my-tablist">
<Tab tabFor="vertical-tab-one">Tab 1</Tab>
<span className="divider"></span>
<Tab tabFor="vertical-tab-two">Tab 2</Tab>
<span className="divider"></span>
<Tab tabFor="vertical-tab-three" className="my-tab">Tab 3</Tab>
</TabList>
<div className="wrapper">
<TabPanel tabId="vertical-tab-one">
<center>
<Button className="buttonPosition" onClick={myClick}>Refresh tab 1</Button>
</center>
</TabPanel>
<TabPanel tabId="vertical-tab-two">
<center>
<Button className="buttonPosition" onClick={myClick}>Refresh tab 2</Button>
</center>
</TabPanel>
<TabPanel tabId="vertical-tab-three">
<center>
<Button className="buttonPosition" onClick={myClick}>Refresh tab 3</Button>
</center>
</TabPanel>
</div>
</section>
</TabProvider>
);
}
}
function myClick(){
window.location.reload();
}
export default App;
I thank you in advance. I continue my research.
Sincerely Valentine
On a page reload the state will reset to it's initial state. You either have to store the last tab in the browsers localStorage or on the server side.
You also need to update your component to retrieve the last state when loading. In the life cycle of React this probably means inside componentDidMount().
You can add the state object in your class, and set its default every time the component is mount, to save the state in a browser refresh you can use localstorage...
class App extends Component {
constructor(props){
super(props);
this.state={
defaultTab: 'vertical-tab-one'
}
}
componentDidMount(){
let default = localStorage.getItem('default');
this.setState(()=>({
defaultTab:default
})
);
}
render(){
return (
<TabProvider
defaultTab={this.state.defaultTab} vertical>
<section className="my-tabs">
<TabList className="my-tablist">
<Tab tabFor="vertical-tab-one">Tab 1</Tab>
<span className="divider"></span>
<Tab tabFor="vertical-tab-two">Tab 2</Tab>
<span className="divider"></span>
<Tab tabFor="vertical-tab-three" className="my-tab">Tab 3</Tab>
</TabList>

Material-UI Tabs inside AutoComplete popover

Is it possible to render the matching data in the AutoComplete popover in the form of Tabs? I may have upto three categories of data matching the input value, that I'd like to display as tabs. Can I combine the Material-UI AutoComplete and Tabs components to achieve this?
The AutoComplete component creates a Menu component for the suggested items. So each suggestion is a component of type MenuItem.
MenuItem component could have dynamic children, and therefore you could add a tabs as the children of the MenuItem. The problem is that any click inside the suggestion popover closes the popover.
If you want to try it out, or maybe hack it somehow (like preventing the click event for tunneling to the popover, and handling the open state manually(?)), here is reproduction code (start typing the word "test" in the input to see suggestions):
import React from 'react';
import AutoComplete from 'material-ui/AutoComplete';
import {Tabs, Tab} from 'material-ui/Tabs';
import MenuItem from 'material-ui/MenuItem';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {deepOrange500} from 'material-ui/styles/colors';
const muiTheme = getMuiTheme({
palette: {
accent1Color: deepOrange500,
},
});
export default class AutoCompleteExampleSimple extends React.Component {
constructor(props) {
super(props);
this.state = {
dataSource: [],
};
}
getTabs() {
return <MenuItem>
<Tabs>
<Tab label="Item One" >
<div>
<h2>Tab One</h2>
<p>
This is an example tab.
</p>
<p>
You can put any sort of HTML or react component in here. It even keeps the component state!
</p>
</div>
</Tab>
<Tab label="Item Two" >
<div>
<h2>Tab Two</h2>
<p>
This is another example tab.
</p>
</div>
</Tab>
<Tab
label="onActive"
route="/home">
<div>
<h2 >Tab Three</h2>
<p>
This is a third example tab.
</p>
</div>
</Tab>
</Tabs>
</MenuItem>
}
handleUpdateInput(value) {
this.setState({
dataSource: [
{text: 'test', value: this.getTabs()}
],
});
};
render() {
return (
<MuiThemeProvider muiTheme={muiTheme}>
<div>
<AutoComplete
hintText="Type anything"
dataSource={this.state.dataSource}
onUpdateInput={this.handleUpdateInput.bind(this)}
/>
</div>
</MuiThemeProvider>
);
}
}

Categories

Resources