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>
);
}
}
Related
I have created a component which basically generates a card which includes card title,card description and a button. Now when I map through an array on a different component to generate those cards I want the button to be different on different components. Like on home page the button should say Update, on other page the button should say Delete. How can I acheive that? Here is the component which generates card.
import React from 'react';
import { Card } from 'react-bootstrap';
const InventoryItem = ({ product }) => {
const { productName, productImage, productPrice, productQuantity, productSupplier, productDetails } = product;
return (
<div className='col-12 col-md-6 col-lg-6'>
<Card className='h-100 items-card d-block d-md-block d-lg-flex flex-row align-items-center border border-0'>
<div className='text-center card-image-container'>
<Card.Img variant="top" src={productImage} className='card-image img-fluid' />
</div>
<Card.Body className='card-details'>
<Card.Title>{productName}</Card.Title>
<Card.Text>{productDetails}</Card.Text>
<div className='d-lg-flex align-items-center justify-content-between mb-3'>
<p className='mb-0'>Price: ${productPrice}</p>
<p className='me-2 mb-0'>Stock: {productQuantity}</p>
</div>
<div className='d-flex align-items-center justify-content-between'>
<p className='mb-0'>Supplier:{productSupplier}</p>
<button className='btn btn-dark'>Update</button>
</div>
</Card.Body>
</Card>
</div>
);
};
export default InventoryItem;
Pass the button text as a prop to the component, so consuming code can speficy the text for the button.
Add it as a prop:
const InventoryItem = ({ product, buttonText }) => {
And use it in the button:
<button className='btn btn-dark'>{buttonText}</button>
Then when using the component, pass the prop:
<InventoryItem product={someProductObject} buttonText="Update" />
or with a conditional value:
<InventoryItem product={someProductObject} buttonText={someCondition ? "Update" : "Delete"} />
You can define a condition for the button basaed on the page you are:
window.location.href return the string href.
const MyButton= window.location.href=='Home'
? <button> HOME</button>
: <button> UPDATE</button>
Hope that answer your question,
Mauro
i want to make a button toggle on each div i click in map function but the buttons toggle in
whole dives on one click (i want to make each click toggle abutton on only the div that i clicked not all of them) ...................................................................................................
import React,{Component} from 'react'
import './course.css'
import Downloadcourse from './../download/down.js'
import {Transition,animated} from 'react-spring/renderprops'
class Course extends Component{
constructor(){
super();
this.state={
search:'',
showcomponent:false,
};
}
updatesearch=(e)=>{
this.setState({search:e.target.value.substr(0,20)});
}
downtoggle=(index)=>{
this.setState({showcomponent:!this.state.showcomponent})
}
render(){
let filteredcontacts= this.props.corses.filter(
(item)=>{
return item.name.toLowerCase().indexOf(
this.state.search.toLowerCase()) !== -1 ;
}) ;
let length= this.props.corses.length;
const courselist=length ?(
filteredcontacts.map((item,index)=>{
return (
<div className="col-sm-3 cat" key={item.id}>
<div className="maincover" >
<div className="mainimg" onClick={this.downtoggle}>
</div>
<div className="maincorse">
<div className="row course-title">
<h1 className="course-Name">{item.name}</h1>
</div>
<div className="row course-title">
<button className="removeing" onClick={()=>{this.props.deleteing(index)}}>Remove
Course</button>
</div>
<div className="row download">
<Transition
native
items={this.state.showcomponent}
from={{ position: 'absolute', overflow: 'hidden', height: 0 }}
enter={[{ height: 'auto' }]}
leave={{ height: 0 }}>
{show=>show &&(props=>(
<animated.div style={props}>
<Downloadcourse />
</animated.div>
))}
</Transition>
</div>
</div>
</div>
</div>
)}
)) :(
<div className="no-content">
<h2>no content to show</h2>
</div>
)
return(
<div className="course">
<input type="text" className="input-search" onChange={this.updatesearch}/>
<span className="magnficant"> 🔍</span>
<div className="row category">
{courselist}
</div>
</div>
)
}
}
export default Course;
To make multiple elements toggleable you need to store each element's toggled state in some data structure. A javascript object ({}) comes in handy for this.
Convert this.state.showComponent from boolean to object
this.state={
search: '',
showComponent: {},
};
Use the index passed to toggle handler to update toggled state
downtoggle = (index) => {
this.setState(prevState => ({
showComponent: {
...prevState.showComponent, // <-- spread existing state
[index]: !prevState.showComponent[index], // <-- toggle value
},
}));
}
Ensure index is passed to the toggle handler
onClick={() => this.downtoggle(index)}
Check the toggled state for the transition component
<Transition
// ... other props
items={this.state.showComponent[index]} // <-- truthy/falsey
/>
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;
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
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>