add item to cart page with react ( only with this.state ) - reactjs

its a long explaition it will be easier if you see screenshots first!
i'm trying to make a website, which inside 3 divs, with 3 different backgrounds. under those 3 divs there are 3 rows of buttons with different colors
you click on a color, it changes the background of one of the main divs. it will be more clear with the image/codesandbox i give here
each click you make changes "this.state.color1" or "color2" to the color you clicked on.
what i wanna do is add a "saved selection page", which you can see color combinations you saved by clicking another buttons called "save".
each click on this save button should return the 3 current colors, send them over to "Saved" page, and they should stay there and never change.
and if you click the save button again, it keeps the previous selections, and add the new one under the previous one.
kinda the same way we click on "add to cart" on websites.
i tried over a week to figure it out by many different ways, like putting a new state called "savedColors" and stuff like that but i didnt figure it out.
here it is on codesandbox
main page:
import React from "react";
import "./main.style.css";
import Buttons1 from "../buttons/buttons1-component";
import Buttons2 from "../buttons/buttons2-component";
import Buttons3 from "../buttons/buttons3-component";
import Saved from "../saved/saved.component";
class Main extends React.Component {
constructor(props) {
super(props);
this.changeColor1 = this.changeColor1.bind(this);
this.changeColor2 = this.changeColor2.bind(this);
this.changeColor3 = this.changeColor3.bind(this);
this.changeToSavedPage = this.changeToSavedPage.bind(this);
this.goToMainPage = this.goToMainPage.bind(this);
this.saveScheme = this.saveScheme.bind(this);
this.state = {
color1: "#fff285",
color2: "#38306b",
color3: "#c4cc90",
page: "main"
};
}
changeToSavedPage() {
this.setState({ page: "saved" });
}
goToMainPage() {
this.setState({ page: "main" });
}
changeColor1(id) {
this.setState({
color1: id
});
}
changeColor2(id) {
this.setState({
color2: id
});
}
changeColor3(id) {
this.setState({
color3: id
});
}
saveScheme() {
alert("see notes in the function");
// hey guys thanks for looking at my code,
// so what im trying to, is to get all 3
// current colors thats been seleceted.
// pass them over to "saved page", and show them there,
// each time you click "save selection" button,
// it will show the NEW CURRENT selection in the saved page.
// but will NOT delete the previos selection, just add a new one
// kind a like Add To Cart button!
}
render() {
return (
<div className="container">
{this.state.page === "main" && (
<div>
<div className="main-colors">
<div
className="color"
style={{ backgroundColor: this.state.color1 }}
>
<h1>color 1</h1>
</div>
<div
className="color"
style={{ backgroundColor: this.state.color2 }}
>
<h1>color 2</h1>
</div>
<div
className="color"
style={{ backgroundColor: this.state.color3 }}
>
<h1>color 3</h1>
</div>
</div>
<div className="buttons-container">
<p>change color 1:</p>
<Buttons1 changeColor1={this.changeColor1} />
<p>change color 2:</p>
<Buttons2 changeColor2={this.changeColor2} />
<p>change color 3:</p>
<Buttons3 changeColor3={this.changeColor3} />
</div>
<div className="btns">
<button onClick={() => this.saveScheme()}>save selection</button>
<button onClick={() => this.changeToSavedPage()}>
go to saved page
</button>
</div>
</div>
)}
{/* saved page */}
{this.state.page === "saved" && (
<Saved goToMainPage={this.goToMainPage} />
)}
</div>
);
}
}
export default Main;
saved page:
import React from "react";
import "./saved.styles.scss";
import SavedPiece from "../saved-piece/saved-piece.component";
class Saved extends React.Component {
constructor(props){
super(props);
// this.num = this.props.isClicked;
this.state = {
}
}
render(){
return(
<div className="saved-container">
<h1>saved</h1>
{/*
here we should see the saved combinations....
*/}
</div>
)
}
}
export default Saved;

import React from "react";
const Saved = (props) => {
const {saved} = props
return (
<>
<div className="saved-container">
<h1>saved matches page</h1>
{
saved && saved.map((obj, i) => {
return <div className="main-colors" key = {i}>
<div
className="color"
style={{ backgroundColor: obj.color1 }}
>
<h1>color 1</h1>
</div>
<div
className="color"
style={{ backgroundColor: obj.color2 }}
>
<h1>color 2</h1>
</div>
<div
className="color"
style={{ backgroundColor: obj.color3 }}
>
<h1>color 3</h1>
</div>
</div>
})
}
<button onClick={() =>
props.goToMainPage()}>
back to main page
</button>
</div>
</>
)
}
export default Saved;
import React from "react";
import React from "react";
import "./main.style.css";
import Buttons1 from "../buttons/buttons1-component";
import Buttons2 from "../buttons/buttons2-component";
import Buttons3 from "../buttons/buttons3-component";
import Saved from "../saved/saved.component";
class Main extends React.Component {
constructor(props) {
super(props);
this.changeColor1 = this.changeColor1.bind(this);
this.changeColor2 = this.changeColor2.bind(this);
this.changeColor3 = this.changeColor3.bind(this);
this.changeToSavedPage = this.changeToSavedPage.bind(this);
this.goToMainPage = this.goToMainPage.bind(this);
this.saveScheme = this.saveScheme.bind(this);
this.state = {
color1: "#fff285",
color2: "#38306b",
color3: "#c4cc90",
page: "main",
saved: []
};
}
changeToSavedPage() {
this.setState({ page: "saved" });
}
goToMainPage() {
this.setState({ page: "main" });
}
changeColor1(id) {
this.setState({
color1: id
});
}
changeColor2(id) {
this.setState({
color2: id
});
}
changeColor3(id) {
this.setState({
color3: id
});
}
saveScheme() {
const { color1, color2, color3 } = this.state
this.setState({
saved: [
...this.state.saved,
{
color1,
color2,
color3
}
]
})
}
render() {
return (
<div className="container">
{this.state.page === "main" && (
<div>
<div className="main-colors">
<div
className="color"
style={{ backgroundColor: this.state.color1 }}
>
<h1>color 1</h1>
</div>
<div
className="color"
style={{ backgroundColor: this.state.color2 }}
>
<h1>color 2</h1>
</div>
<div
className="color"
style={{ backgroundColor: this.state.color3 }}
>
<h1>color 3</h1>
</div>
</div>
<div className="buttons-container">
<p>change color 1:</p>
<Buttons1 changeColor1={this.changeColor1} />
<p>change color 2:</p>
<Buttons2 changeColor2={this.changeColor2} />
<p>change color 3:</p>
<Buttons3 changeColor3={this.changeColor3} />
</div>
<div className="btns">
<button onClick={() => {
console.log(this.state.saved)
this.saveScheme()
}}>save selection</button>
<button onClick={() => {
this.changeToSavedPage()
}}>
go to saved page
</button>
</div>
</div>
)}
{/* saved page */}
{this.state.page === "saved" && (
<Saved
goToMainPage={this.goToMainPage}
saved = {this.state.saved}
/>
)}
</div>
);
}
}
export default Main;
We added an array to our main component state called saved, then when a user saves, we update the state by adding the values of the current selections, and using the spread operator to maintain the old selected values and not mutate them. Then we pass our saved array as a prop to our child component, and we map it.

Related

Show/Hide div in a mapping ReactJS

i'm currently learning ReactJS, and im facing an issue while tryng to hide/show a div! The following code is working, but when i'm clicking the button "Learn More" it hide every description on every card, but i would like to show/hide the description only where i clicked it.
import Axios from 'axios';
import React, { useEffect, useState } from 'react';
import JobApplicationList from './JobApplicationList';
import Card from "react-bootstrap/Card";
import ScriptTag from 'react-script-tag';
export default class Home extends React.Component{
constructor(){
super()
this.state={
showMe:true,
advLists: []
}
}
operation(){
this.setState({
showMe:!this.state.showMe
})
}
componentDidMount() {
Axios.get(`http://localhost:3001/get/adv`)
.then(res => {
const advLists = res.data;
this.setState({ advLists });
})
}
render(){
return (
<div className="main-page">
<div className="adv_container">
{this.state.advLists.map((val, key) => {
return (
<div className="card_">
<Card style={{ width: "100%" }}>
<Card.Body>
<Card.Title>{val.compName}</Card.Title>
<Card.Subtitle className="mb-2 text-muted">
{val.city} | {val.compWebsite}
</Card.Subtitle>
<Card.Subtitle className="mb-2 text-muted">
{val.salaire} €
</Card.Subtitle>
{ this.state.showMe?
<div className="description">
<Card.Text>{val.description}</Card.Text>
</div>
:null
}
<Card.Link onClick={()=> this.operation()} id="toto" href="#">Learn more</Card.Link>
<Card.Link href="#">Apply</Card.Link>
</Card.Body>
</Card>
</div>
);
})}
</div>
</div>
)
}
}
I kinda know what's going wrong, when i'm pressing the button i give the showMe state to every card, but i dont know how to fix it!
Thanks in advance for the help.
Make the initial showMe state null and convert operation to take an index to toggle. If the index is already saved in state then set back to null.
operation(index) {
this.setState({
showMe: this.state.showMe === index ? null : index,
})
}
Use the mapped index to pass to the handler and check this index against the showMe state to display the card.
{this.state.advLists.map((val, key) => {
return (
<div className="card_">
<Card style={{ width: "100%" }}>
<Card.Body>
<Card.Title>{val.compName}</Card.Title>
<Card.Subtitle className="mb-2 text-muted">
{val.city} | {val.compWebsite}
</Card.Subtitle>
<Card.Subtitle className="mb-2 text-muted">
{val.salaire} €
</Card.Subtitle>
{this.state.showMe === key && ( // <-- check if index/key matches
<div className="description">
<Card.Text>{val.description}</Card.Text>
</div>
)}
<Card.Link
onClick={() => this.operation(key)} // <-- pass key/index to toggle
id="toto" href="#"
>
Learn more
</Card.Link>
<Card.Link href="#">Apply</Card.Link>
</Card.Body>
</Card>
</div>
);
})}
I can give you the code pattern on how to toggle individual items using a React class component.
class MyComponent extends React.Component {
state = { items: [] }; // initial state
componentDidMount() {
// fetched data
this.setState({ items: [{ title: "one" }, { title: "two" }] });
}
toggleItem = (index) => {
let items = this.state.items;
items[index].hidden = !items[index].hidden; // mutating
this.setState({ items }); // new object triggers re-render
};
render() {
return (
<ul>
{this.state.items.map((item, index) => {
return (
<li key={index}> {/* remember to use a key */}
<button onClick={() => this.toggleItem(index)}>toggle</button>
{!item.hidden && item.title}
</li>
);
})}
</ul>
);
}
}

How do I preserve previous state of React InstantSearch

import React, { Component, useState } from 'react';
import algoliasearch from 'algoliasearch/lite';
import {
InstantSearch,
Hits,
SearchBox,
Highlight,
connectRefinementList,
} from 'react-instantsearch-dom';
import PropTypes from 'prop-types';
import './App.css';
const searchClient = algoliasearch(
'test',
'test'
);
class App extends Component {
constructor(props) {
super(props);
this.state = {
selectedCountries: []
}
}
render() {
const RefinementList = ({
items,
isFromSearch,
refine,
searchForItems,
createURL,
}) => {
return (
<ul style={{ listStyle: 'none' }}>
{
items &&
items.map(item => (
<li key={item.label}>
<input
type="checkbox"
checked={item.isRefined}
// href={createURL(item.value)}
style={{ fontWeight: item.isRefined ? 'bold' : '' }}
onChange={event => {
// event.preventDefault();
refine(item.value);
}}
/>
{isFromSearch ? (
<Highlight attribute="label" hit={item} />
) : (
item.label
)}{' '}
({item.count})
</li>
))}
</ul>
)
};
const CustomRefinementList = connectRefinementList(RefinementList);
return (
<div className="container">
<InstantSearch searchClient={searchClient} indexName="parterns">
<div className="search-panel">
<div className="search-panel__results">
<SearchBox
className="searchbox"
translations={{
placeholder: '',
}}
searchAsYouType={false}
/>
<Hits hitComponent={Hit} />
<br />
<br />
<button onClick={(e) => {
const that = this;
e.preventDefault();
that.setState({
selectedCountries: Array.from(new Set([...that.state.selectedCountries, 'India']))
})
}
}
>
Select India
</button>
<br />
<button onClick={(e) => {
const that = this;
e.preventDefault();
that.setState({
selectedCountries: Array.from(new Set([...that.state.selectedCountries, 'USA']))
})
}
}
>
Select Usa
</button>
<br />
<h3>Location</h3>
<div className="region">
<CustomRefinementList
operator="or"
limit={10}
defaultRefinement={[]}
attribute="region" />
</div> <br />
<CustomRefinementList
operator="or"
limit={this.state.selectedCountries.length}
defaultRefinement={this.state.selectedCountries}
attribute="country" />
<br />
<br />
</div>
</div>
</InstantSearch>
</div>
);
}
}
function Hit(props) {
return (
<article onClick={() => alert(props.hit.title)}>
<h1>
<Highlight attribute="title" hit={props.hit} />
</h1>
</article>
);
}
Hit.propTypes = {
hit: PropTypes.object.isRequired,
};
export default App;
The problem is all previously selected filters are getting cleared.
For example initially I click on filter ex: North America
So I will get filtered results for North America.
Now I want to have Country filter which will be visible when click on button ex Select USA
When I am clicking on Button for ex: Select USA then I am setting state because I want to render it dynamically but issue is previous state is getting cleared how can I preserve previous state for component.

Hide all div and show one div on clicking multiple button

I am trying to fit 3 component in a single page by hiding/showing on a div.But I am not really getting into how to do it.This is the first div.
<div>
<p>What is the type of your property?</p>
<button >Residence</button>
<button>Commercial</button>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Back</span>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Next</span>
</div>
Only If i click the 'Commercial' or 'Next' button it would go into the second div and first div will hide.
<div>
<p>What is the type of your commercial property?</p>
<button>Office</button>
<button>Restaurant</button>
<button >Outlet</button>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Back</span>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Next</span>
</div>
and lastly if i click 'restaurant' button from the first div and any button of the second div except the back button it will go into the third div and other div will hide.this is the third div.
<div>
<div className='slider' style={{ marginTop:'165px',marginLeft:'319px',width:'700px',backgroundColor:'EF5350'}} >
<Slider min={850} max={5000} value={value} onChangeStart={this.handleChangeStart}
onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete}
/>
<div className='value'>{value} Squarefeet</div>
<div style={{marginTop:'86px'}}>
<span onChange={this.handleChange} onClick={() => this.saveValue()} >Next</span>
<span onChange={this.handleChange} onClick={() => this.saveValue()} >Next</span>
</div>
</div>
</div>
I tried to do it this way. But it will not work.
import React from 'react';
import Link from "next/link";
class Jh extends React.Component {
constructor() {
super();
this.state = {
shown: true,
hide: false
};
}
toggle() {
this.setState({
shown: !this.state.shown
});
}
toggles() {
this.setState({
shown: !this.state.hide
});
}
render() {
var shown = {
display: this.state.shown ? "block" : "none"
};
var hidden = {
display: this.state.shown ? "none" : "block"
}
return (
<div>
<button onClick={this.toggle.bind(this)} style={ shown }>
<div>
<p>What is the type of your property?</p>
<button >Residence</button>
<button>Commercial</button>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Back</span>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Next</span>
</div>
</button>
<button onClick={this.toggles.bind(this)} style={ hidden }>
<div>
<p>What is the type of your commercial property?</p>
<button>Office</button>
<button>Restaurant</button>
<button >Outlet</button>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Back</span>
<span style={{background:'transparent', border:'0', fontSize:'16px',color:'#ef3530'}}>Next</span>
</div>
</button>
</div>
)
}
}
export default Jh
What should be my approach?
There are many patterns to achieve a "switch case", I'll try to show my favorites:
For sipmlicity, I'll use a generic use case.
Straight Forward
Managing visible state for every component:
return {visible && <CoolComponent id={1} />};
Switch case in disguise
Manage a state of object keys. (currentCounter)
const countersPicker = {
counter1: <Counter id={1} />,
counter2: <Counter id={2} />,
coolComponent: <CoolComponent id={3} />
};
return {countersPicker[currentCounter]};
Here you also can take action on the object, for example, adding a header:
return {Object.entries(countersPicker).map(([key,component]) =>
<div key={key}>
<h1>Component key = {key}</h1>
{component}
</div>
)};
Filter Children
Manage a predicate and use it for filtering/mapping the children.
Check React.Children API.
return (
<FilterComponents predicate={predicate}>
<Counter key={1} id={1} />
<Counter key={2} id={2} />
<CoolComponent key={3} id={3} />
<BestComponent key={4} id={4} />
</FilterComponents>
);
function FilterComponents({ children, predicate }) {
const filteredChildren = React.Children.toArray(children).filter(child =>
// Use the predicate.
// Filter a child by key, key & type or even use ref etc.
);
return <div>{filteredChildren}</div>;
}
I believe you are looking for something like this.
Main things to-do:
Enhance your state-value. Keep track of the different pages in sequence by using an array. Track the current page. Track the start and end of the collection.
Here is the sandbox as well: https://codesandbox.io/s/unruffled-sun-gpzx6
import React from "react";
class Pages extends React.Component {
state = {
currentPage: "property",
pages: ["property", "type", "firstBusiness"],
start: true,
end: false
};
changePage = event => {
const { currentPage, pages } = this.state;
const { name } = event.target;
//check if we are going to end
if (
name == "next" &&
pages[pages.indexOf(currentPage) + 1] === pages[pages.length - 1]
) {
this.setState({
currentPage: pages[pages.indexOf(currentPage) + 1],
end: true,
start: false
});
//go to next page
} else if (name == "next") {
this.setState({
currentPage: pages[pages.indexOf(currentPage) + 1],
start: false
});
//check if we are going to beginning
} else if (
name == "back" &&
currentPage !== pages[0] &&
pages[pages.indexOf(currentPage) - 1] == pages[0]
) {
this.setState({
currentPage: pages[pages.indexOf(currentPage) - 1],
start: true
});
//go back one page
} else {
this.setState({
currentPage: pages[pages.indexOf(currentPage) - 1],
end: false
});
}
};
goToNextPage = () => {
const { currentPage, pages, end } = this.state;
//check if we are going to end
if (pages[pages.indexOf(currentPage) + 1] === pages[pages.length - 1]) {
this.setState({
currentPage: pages[pages.indexOf(currentPage) + 1],
end: true,
start: false
});
//go to next page
} else if (end) {
return;
} else {
this.setState({
currentPage: pages[pages.indexOf(currentPage) + 1],
start: false
});
}
};
render() {
const { currentPage, start, end } = this.state;
return (
<div style={{ background: "gray" }}>
{currentPage === "property" ? (
<div>
<p>What is the type of your property?</p>
<button onClick={this.goToNextPage}>Residence</button>
<button onClick={this.goToNextPage}>Commercial</button>
</div>
) : null}
{currentPage === "type" ? (
<div>
<p>What is the type of your commercial property?</p>
<button onClick={this.goToNextPage}>Office</button>
<button onClick={this.goToNextPage}>Restaurant</button>
<button onClick={this.goToNextPage}>Outlet</button>
</div>
) : null}
{currentPage === "firstBusiness" ? (
<div>
<p>Is this your first business?</p>
<button onClick={this.goToNextPage}>Yes</button>
<button onClick={this.goToNextPage}>No</button>
</div>
) : null}
<div>
<button onClick={this.changePage} name="back" disabled={start}>
Back
</button>
<button onClick={this.changePage} name="next" disabled={end}>
Next
</button>
</div>
</div>
);
}
}
export default Pages;
So essentially you want router like functionality. Here is one approach:
class FirstPage extends React.Component {
render() {
//...first page content
}
}
class SecondPage extends React.Component {
render() {
//...second page content
}
}
const pages = {
first: FirstPage,
second: SecondPage
};
class App extends React.Component {
constructor() {
this.state = {
page: 'first'
};
}
render() {
const PageComponent = pages[this.state.page];
return <div>
<button onClick={() => this.setState({page: 'first'})}>First page</button>
<button onClick={() => this.setState({page: 'second'})}>Second page</button>
<PageComponent/>
</div>
}
}
There are many ways to solve this problem. But in my opinion the best solution is the one which solves the problem in a succinct manner.
Please find below the working solution which I have tried and works like a charm:
import React from "react";
class Pages extends React.Component {
state = {
activeTab: 1
};
toggle = tab => {
this.setState({
activeTab: tab
});
};
togglePage = page => {
if (page === "next") {
this.setState({
activeTab: this.state.activeTab + 1
});
} else if (page === "back") {
this.setState({
activeTab: this.state.activeTab - 1
});
}
};
render() {
return (
<div style={{ background: "#dedede" }}>
<div hidden={this.state.activeTab === 1 ? false : true}>
<p>1) What is the type of your property?</p>
<button class="btn btn-primary" onClick={() => this.toggle(2)}>
Residence
</button>
<button onClick={() => this.toggle(2)}>Commercial</button>
</div>
<div hidden={this.state.activeTab === 2 ? false : true}>
<p>2) What is the type of your commercial property?</p>
<button onClick={() => this.toggle(3)}>Office</button>
<button onClick={() => this.toggle(3)}>Restaurant</button>
<button onClick={() => this.toggle(3)}>Outlet</button>
</div>
<div hidden={this.state.activeTab === 3 ? false : true}>
<p>3) Is this your first business?</p>
<button onClick={this.NextAction}>Yes</button>
<button onClick={this.NextAction}>No</button>
</div>
<div>
<button
onClick={() => this.togglePage("back")}
name="back"
disabled={this.state.activeTab === 1 ? true : false}
>
Back
</button>
<button
onClick={() => this.togglePage("next")}
name="next"
disabled={this.state.activeTab === 3 ? true : false}
>
Next
</button>
</div>
</div>
);
}
}
export default Pages;
In react we have a hidden attribute which you can use to show/hide the elements without having to write any css for the same.
And I have tried to solve the problem with the least number of variables.
The sandbox for the same can be found here : https://codesandbox.io/s/mysolution-g8fu6
Hope this helps!

Add style to button in buttonGroup when user select one of the option

I am trying to add style in button When the user selects one of the button from buttonGroup then button should be highlighted and it should remain highlighted even if user select another button from different button group but in my case When user select another button option from different buttonGroup then previous button lose it’s state and it no longer shows the active highlighted state. can anyone tell me how to achieve that? In my code, I added backgroundColor to style property but doesn't seem to work.
code::
import React, { Component } from "react";
import { Button } from "semantic-ui-react";
import { withRouter } from "react-router";
import Answers from "../Answers/Answers";
class Section extends Component {
state = {
que1: "",
que2: "",
que3: ""
};
handleClick = event => {
this.setState(
{
que1: event.target.attributes.getNamedItem("data-key").value
},
() => {
console.log(this.state.que1);
}
);
};
handleClick2 = event => {
this.setState(
{
que2: event.target.attributes.getNamedItem("data-key").value
},
() => {
console.log(this.state.que2);
}
);
};
handleClick3 = event => {
this.setState(
{
que3: event.target.attributes.getNamedItem("data-key").value
},
() => {
console.log(this.state.que3);
}
);
};
render() {
let styles = {
width: '50%',
margin: '0 auto',
marginBottom: '15px'
}
console.log(this.state);
const { history } = this.props;
const { que1, que2, que3 } = this.state;
return (
<>
<p>1. I was stressed with my nerves on edge.</p>
<Button.Group widths="5" onClick={this.handleClick} style={styles}>
<Answers style={{ backgroundColor: 'gray' }} />
</Button.Group>
{` `}
<p>2. I lost hope and wanted to give up when something went wrong.</p>
<Button.Group widths="5" onClick={this.handleClick2} style={styles}>
<Answers style={{ backgroundColor: 'gray' }}/>
</Button.Group>
{` `}
<p>3. I feel very satisfied with the way I look and act</p>
<Button.Group widths="5" onClick={this.handleClick3} style={styles}>
<Answers style={{ backgroundColor: 'gray' }}/>
</Button.Group>
<p />
{` `}
<Button
disabled={!que1 || !que2 || !que3}
onClick={() => history.push("/section2")}
>
NEXT
</Button>
</>
);
}
}
export default withRouter(Section);
Answers.js
import React, { Component } from "react";
import { Button } from "semantic-ui-react";
export class Answers extends Component {
render() {
return (
<>
<Button data-key="Never">Never</Button>
<Button data-key="Occassionally">Occassionally</Button>
<Button data-key="Often">Often</Button>
<Button data-key="Very Often">Very Often</Button>
<Button data-key="Always">Always</Button>
</>
);
}
}
export default Answers;
output :
I believe the problem is that your Button.Group components are not aware of the stored state values (que1, que2, que3). I believe you need to pass these into your Buttons and render accordingly. Specifically, you need to pass the 'active' prop to the Buttons (see here: https://codesandbox.io/s/wzq0941wol).
<Button.Group>
<Button onClick={() => this.click(1)}
active={this.state.active === 1} >
One
</Button>
<Button onClick={() => this.click(2)}
active={this.state.active === 2}
>Two
</Button>
</Button.Group>
and then your click handler just saves the state:
click(val) {
this.setState({ active: val });
}
To integrate this with your Answers class above, you could do something like this:
export class Answers extends Component {
render() {
const selected = this.props.selected;
return (
<>
<Button active={selected === "Never"} data-key="Never">Never</Button>
<Button active={selected === "Occassionally"} data-key="Occassionally">Occassionally</Button>
<Button active={selected === "Often"} data-key="Often">Often</Button>
<Button active={selected === "Very Often"} data-key="Very Often">Very Often</Button>
<Button active={selected === "Always"} data-key="Always">Always</Button>
</>
);
}
}
and then in your Section class:
<Button.Group widths="5" onClick={this.handleClick} style={styles}>
<Answers selected={this.state.que1} style={{ backgroundColor: 'gray' }} />
</Button.Group>

Reactjs: How to display one toggled content at a time on button click

The code below was used to toggle content on button click and it works excellent as their respective contents gets displayed for each clicked button.
Here is what I want to implement.
Now I have the task of displaying one collapse content record on button click.
Here is what I mean, when I click on the first button, the content will be toggled and displayed.
when I click on the second button, I want to be seeing only the content of the second clicked button while hidding the
content of the first and so on. Thanks
Here is the code so far
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
shown: true,
shown1: true,
shown2: true,
shown3: true,
};
}
componentDidMount() {
this.setState({
});
}
toggle1() {
this.setState({
shown1: !this.state.shown1
});
}
toggle2() {
this.setState({
shown2: !this.state.shown2
});
}
toggle3() {
this.setState({
shown3: !this.state.shown3
});
}
render() {
var shown = {
display: this.state.shown ? "block" : "none"
};
var hidden1 = {
display: this.state.shown1 ? "none" : "block"
}
var hidden2 = {
display: this.state.shown2 ? "none" : "block"
}
var hidden3 = {
display: this.state.shown3 ? "none" : "block"
}
return (
<div>
<label>
<ul>
<button onClick={this.toggle1.bind(this)}>Toggle 1</button>
<button onClick={this.toggle2.bind(this)}>Toggle 2</button>
<button onClick={this.toggle3.bind(this)}>Toggle 3</button>
<h2 style={ hidden1 }> Toggle record 1 appears Here</h2>
<h2 style={ hidden2 }> Toggle record 2 appears Here</h2>
<h2 style={ hidden3 }> Toggle record 3 appears Here</h2>
</ul>
</label>
</div>
);
}
}
Refactored it a little bit. You can apply some css to make the content collapse.
import React, { Component } from "react";
import ReactDOM from "react-dom";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
shownId: undefined
};
}
toggle(id) {
this.setState({
shownId: id
});
}
render() {
return (
<div>
<label>
<ul>
<button onClick={() => this.toggle(1)}>Toggle 1</button>
<button onClick={() => this.toggle(2)}>Toggle 2</button>
<button onClick={() => this.toggle(3)}>Toggle 3</button>
<h2
style={{ display: this.state.shownId === 1 ? "block" : "none" }}>Toggle record 1 appears Here
</h2>
<h2
style={{ display: this.state.shownId === 2 ? "block" : "none" }}>Toggle record 2 appears Here
</h2>
<h2
style={{ display: this.state.shownId === 3 ? "block" : "none" }}>Toggle record 3 appears Here
</h2>
</ul>
</label>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
Codesandbox link

Resources