How to properly display div content when click users randomly in react - reactjs

The code below successfully display users div messages at the bottom of the page when clicked Users button serially (Eg User1, User2, user3 etc.)
Here is my issue: When I click the Users Button randomly (Eg. User1, user6, user5, user12 etc.) The Div message box gets scattered all over the page as can be seen in the screenshot below.
I do not know if the issue is from css or react components.
Please how do I get each of the users message DIV to be displayed correctly at the bottom whether the users button is clicked serially or randomly
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.mainArea {
position: fixed;
width: 80%;
bottom: 0%
}
.contact_box {
position: relative;
bottom: -5px;
width: 250px;
background: black;
color: red;
border-radius: 5px 5px 0px 0px;
bottom: 0px;
display: inline-block;
}
</style>
<div id="app"></div>
<script type="text/babel">
class Application extends React.Component {
constructor(props) {
super(props);
this.state = {
arr: [
{ id: 1, name: "user1"},
{ id: 2, name: "user2"},
{ id: 3, name: "user3"},
{ id: 4, name: "user4"},
{ id: 5, name: "user5"},
{ id: 6, name: "user6"},
{ id: 7, name: "user7"},
{ id: 8, name: "user8"},
{ id: 9, name: "user9"},
{ id: 10, name: "user10"},
{ id: 11, name: "user11"},
{ id: 12, name: "user12"},
{ id: 13, name: "user13"},
{ id: 14, name: "user14"},
{ id: 15, name: "user15"}
],
popStatus: false,
};
this.popIt = this.popIt.bind(this);
}
popIt(id) {
this.state.arr[id].popStatus = true;
this.setState({
popStatus: true
});
}
render() {
return (
<div>
<h3>List of users Records</h3>
<div class="sidebar">
<ul>
{this.state.arr.map((obj, i) => (
<li key={i}>
{obj.name} - {obj.name}
<button
type="button"
onClick={() => { this.popIt(i); }}
className=""
>
{obj.name}
</button>
</li>
))}
</ul>
</div>
<div className="mainArea">
{this.state.arr.map((obj, i) => (
<div key={i} className="contact_box" >
{obj.popStatus === true && <div className="">
<b>Username:</b> {obj.name}<br />
Message .........<br />
Message .........<br />
Message .........<br />
Message .........<br />
Message .........<br />
Message .........<br />
</div>
}
</div>
))}
</div>
</div>
);
}
}
ReactDOM.render(<Application />, document.getElementById('app'));
</script>
</body>
</html>

Your issue is partly the result of your CSS and partly the result of your conditional rendering logic in your JSX.
CSS
You have a styled wrapper that displays for every user regardless of whether popStatus is true. That styled wrapper has a fixed width so it takes up space on the page whether or not anything actually renders inside of it.
More specifically, you’re rendering this div for every user:
<div key={i} className="contact_box" >
Take a look at where this line sits in your JSX.
The column gaps you see between user info boxes are these div being rendered. You can use whatever CSS you want just keep in mind if you include an element wrapping your conditional check for popStatus in your render then it will show for each user.
The most straightforward solution is to just remove it or move it down inside the render after your conditional check.
Conditional Rendering
When you map over users you can perform your conditional check for popStatus first.
This way, you will only render something when the condition is met.
Also better to set the key to be the user id to uniquely identify the user rather than use an index.
NOTE: You should avoid mutating state directly. This line: this.state.arr[id].popStatus = true; should be moved inside setState and you should return a new copy when performing this update.
NOTE: It's unclear what the popStatus prop on the top level object in your state is doing as it seems irrelevant to your problem. I commented it out from the demo.
The demo below should get you going in the right direction I think.
Example/Demo (View at the link below)
https://codesandbox.io/s/user-list-pop-example-vuyx59
styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.main-area {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 8px;
}
.contact-box {
background: black;
color: red;
border-radius: 5px 5px 0px 0px;
padding: 10px;
}
App.js
import "./styles.css";
import { useState } from "react";
const initialState = {
users: [
{ id: 1, name: "user1", popStatus: false },
{ id: 2, name: "user2", popStatus: false },
{ id: 3, name: "user3", popStatus: false },
{ id: 4, name: "user4", popStatus: false },
{ id: 5, name: "user5", popStatus: false },
{ id: 6, name: "user6", popStatus: false },
{ id: 7, name: "user7", popStatus: false },
{ id: 8, name: "user8", popStatus: false },
{ id: 9, name: "user9", popStatus: false },
{ id: 10, name: "user10", popStatus: false },
{ id: 11, name: "user11", popStatus: false },
{ id: 12, name: "user12", popStatus: false },
{ id: 13, name: "user13", popStatus: false },
{ id: 14, name: "user14", popStatus: false },
{ id: 15, name: "user15", popStatus: false }
]
// what was this for?
// popStatus: false
};
export default function App() {
const [state, setState] = useState(initialState);
function popIt(id) {
setState((prev) => {
return {
...prev,
users: prev.users.map((user) =>
user.id === id ? { ...user, popStatus: true } : user
)
};
});
}
return (
<div className="App">
<h3>List of users Records</h3>
<ul style={{ listStyle: "none" }}>
{state.users.map((user) => (
<li key={user.id}>
{user.name}{" "}
<button
type="button"
onClick={() => {
popIt(user.id);
}}
>
{user.name}
</button>
</li>
))}
</ul>
<div className="main-area">
{state.users.map(
(user) =>
user.popStatus && (
<div key={user.id} className="contact-box">
<b>Username:</b>
{user.name}
<br />
Message .........
<br />
Message .........
</div>
)
)}
</div>
</div>
);
}
Screenshot of how user info is displayed in sequence no matter what order users are clicked:

You have an issue with your map function:
{this.state.arr.map((obj, i) => (
<div key={i} className="contact_box" >
{obj.popStatus === true && <div className="">
<b>Username:</b> {obj.name}<br />
First you print contact_box div, and later you check popStatus, and based on that you print content. Because you set CSS for the cotact_box, which is printed always, you have these blank spots.
Just move contact_box div inside if statement, and it should be fine:
{this.state.arr.map((obj, i) => (
{obj.popStatus === true &&
<div key={i} className="contact_box" >
<b>Username:</b> {obj.name}<br />
// rest of the box
</div>
}
)}
In the process, you can rid of this additional div.
Also, I recommend using functional component and hooks, it will be simpler to manage the state, and it is recommended for newer React versions.

Related

style and work with arr in vue.js. How styling only active element?

I have cards array and button on every card. If I click my button, all buttons are changing style.
How apply style to active button not for all?
<template>
<div>
<div v-for="i in cards" id="card" :key="i" class="col-sm-4">
<btn
id="heartBtn"
class="fa fa-heart"
aria-hidden="true"
:class="color"
#click="changeColor = !changeColor"
></btn>
</div>
</div>
</template>
<script>
export default {
name: 'MainLayout',
data: () => ({
changeColor: false,
cards: [1, 2, 3, 4, 5, 6, 7, 8, 10, 11],
}),
computed: {
color() {
if (this.changeColor === true) {
return 'faClick'
} else {
return 'fa'
}
},
},
}
</script>
tnx for help All/ I take you code and rebuild his.I got the right one code for me/ Rebild code:
id="card"
class="col-sm-4"
v-for="card in cards"
:key="card.id"
><btn
id="heartBtn"
class="fa fa-heart"
aria-hidden="true"
:class="card.color ? 'faClick' : 'fa'"
#click="changeColor(card.id)"
></btn>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'mainLayout',
data: () => ({
cards: [
{ id: 1, color: false },
{ id: 2, color: false },
{ id: 3, color: false },
{ id: 4, color: false }
]
}),
methods: {
changeColor (id) {
this.cards = this.cards.map((card) => {
if (card.id === id) {
card.color = !card.color
}
return card
})
}
},```
Something like this will solve your issue
<template>
<div>
<div
v-for="card in cards"
:key="card.id"
class="card col-sm-4"
:class="card.color ? 'faClick' : 'fa'"
>
<button
id="heartBtn"
class="fa fa-heart"
aria-hidden="true"
#click="toggleColor(card.id)"
>
{{ card.id }}
</button>
</div>
</div>
</template>
<script>
export default {
name: 'MainLayout',
data() {
return {
cards: [
{ id: 1, color: false },
{ id: 2, color: false },
{ id: 3, color: false },
{ id: 4, color: false },
],
}
},
methods: {
toggleColor(id) {
this.cards = this.cards.map((card) => {
if (card.id === id) {
card.color = !card.color
}
return card
})
},
},
}
</script>
<style scoped>
.faClick { /* this is a visual example */
border: 2px solid red;
}
</style>
Here is how it looks in the DOM
And regarding the state

Issue in removing Grandchild in a recursive component

What I have been trying to achieve?
Create a nested context menu that is driven by a config.
Where am I stuck:
Sub menus are rendering correctly, but if there is more than 2 level, the change in root level only affects its sub-menu and not its entire tree
Here is the sandbox link for you to check.
Steps to reproduce:
On load, a menu is displayed (say menu)
Click on File, it will open its sub menu (say sub-menu1).
Click on Open in the sub-menu1, again another sub menu (say sub-menu2) is open.
Now when you click on Edit in menu, sub-menu1 disappears but not sub-menu2
I think, I know the problem. sub-menu2 is not refreshing because props or state is not changed. To hide it, we will need to trickle down some prop but can't think of elegant way to do it without state management system.
You'll have a better time if the ContextMenu component is responsible for state management and recursion is flattened into iteration.
function ContextItem({ item, onClick }) {
return (
<div className="menu-item" onClick={() => onClick(item)}>
<p className="menu-title">{item.title}</p>
{item.children && item.children.length > 0 ? <i className="right-icon">{">"}</i> : null}
</div>
);
}
function MenuList({ list, onClick }) {
return (
<div className="menu-container">
{list.map((listItem) => (
<ContextItem item={listItem} key={listItem.title} onClick={onClick} />
))}
</div>
);
}
const ContextMenu = ({ list }) => {
const [openSubmenus, setOpenSubmenus] = React.useState([]);
const clickHandler = React.useCallback((item, level) => {
if (item.children && item.children.length) {
setOpenSubmenus((oldItems) => {
return [...oldItems.slice(0, level), item.children];
});
} else {
setOpenSubmenus([]); // item selected, clear submenus
alert(item.title);
}
}, []);
const menus = [list, ...openSubmenus];
return (
<div className="menu">
{menus.map((menu, level) => (
<MenuList
key={level}
list={menu}
level={level}
onClick={(item) => clickHandler(item, level)}
/>
))}
</div>
);
};
const menuList = [{
title: "File",
children: [{
title: "Close",
children: [],
action: "fileClose",
}, {
title: "Open",
children: [{
title: "A:\\",
children: [],
action: "",
}, {
title: "C:\\",
children: [],
action: "",
}, {
title: "\\",
children: [],
action: "",
}],
action: "",
}, {
title: "Find",
children: [{
title: "here",
children: [],
}, {
title: "elsewhere",
children: [],
}],
action: "",
}, {
title: "Backup",
children: [],
action: "backup",
}],
action: "",
}, {
title: "Edit",
children: [],
action: "edit",
}];
function App() {
return <ContextMenu list={menuList} />;
}
ReactDOM.render(<App />, document.getElementById("root"));
.menu {
display: flex;
flex-direction: row;
}
.menu-container {
display: flex;
flex-direction: column;
background-color: #eee;
border: 1px solid gray;
border-radius: 4px;
}
.menu-item {
display: flex;
flex-direction: row;
margin: 2px;
max-width: 200px;
line-height: 30px;
padding: 5px 10px;
}
.menu-title {
min-width: 80px;
height: 30px;
flex-grow: 1;
margin: 0;
vertical-align: middle;
}
.menu-title.active {
background-color: blue;
color: white;
}
.right-icon {
width: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You could use the label as the key to reset the ContextMenu state when selectedItem change (assuming the label is unique at a given depth, but it seems reasonable, otherwise you could add unique ids).
export const ContextMenu = ({list}) => {
const [selectedItem, setSelectedItem] = useState();
return (
<div className="menu">
<div className="menu-container">
{list.map((listItem) => {
return (
<ContextItem
item={listItem}
key={listItem.title}
onClick={setSelectedItem}
/>
);
})}
</div>
{selectedItem?.children.length > 0 && <ContextMenu
key={selectedItem.title}
list={selectedItem.children}/>}
</div>
);
};

REACT.JS: How to loop over all NavBar buttons and remove their class and add "active" class to the clicked button

I am trying to make a simple NavBar with React.js. The problem I found myself in is the looping over all nav buttons and remove the "active" className and then add "active" to just that one clicked button.
I managed to make a state that toggles "active" to true on the clicked element which then in the className attribute does this If statement:
className={this.state.active ? "nav-item nav-link active" : "nav-item nav-link"}
Here is the full code:
import React, { Component } from 'react';
class NavButton extends Component {
state = {
active: false
}
setActive = () => {
this.setState({
active: !this.state.active
})
}
render() {
return (
<a
className={this.state.active ? "nav-item nav-link active" : "nav-item nav-link"}
href={this.props.href}
onClick={this.setActive}> {this.props.title}
</a>
)
}
}
class NavBar extends Component {
buttons = [
{
title: "Home",
key: 0
},
{
title: "Team",
key: 1
},
{
title: "Discord",
key: 2
},
{
title: "Gallery",
key: 3
},
{
title: "Download",
key: 4
}
]
render() {
return (
<nav className="navbar" id="navbarMain">
<div></div>
<div className="navbar-nav flex-row">
{this.buttons.map(button => <NavButton title={button.title} key={button.key} />)}
</div>
<div></div>
</nav>
)
}
}
export default NavBar
This works, for just one element (don't mind that the active state goes false when it's true. The problem is, how would I do it in the React way to remove the active className in all other buttons?
With plain JS i have no issues to do that, i just loop over all elements that have the className "navbar-item" and set their classnames to be without the "active" one then add " active" to the pressed element like in this example https://www.w3schools.com/howto/howto_js_tabs.asp
Would you guys be able to help and tell me what would be the best react way to do this?
Much appreciated!
A common pattern for these use-cases is to keep the relevant state in the parent, so that it is the parent (NavBar) that keeps track of which child (NavButton) is "active". The NavButton can then become a stateless component which takes "active" as a prop.
const NavButton = ({active, title, href, onSetActive}) => {
return (
<button
className={active ? "nav-item nav-link active" : "nav-item nav-link"}
href={href}
onClick={onSetActive} >
{title}
</button>
)
}
class NavBar extends React.Component {
constructor(props) {
super(props);
this.state = {
activeIndex: 0, // keep the active index in state
buttons: [
{
title: "Home",
key: 0
},
{
title: "Team",
key: 1
},
{
title: "Discord",
key: 2
},
{
title: "Gallery",
key: 3
},
{
title: "Download",
key: 4
}
]
}
}
handleChangeActive(newActiveIndex) {
this.setState({activeIndex: newActiveIndex});
}
render() {
const {activeIndex} = this.state;
return (
<nav className="navbar" id="navbarMain">
<div></div>
<div className="navbar-nav flex-row">
{this.state.buttons.map((button, buttonIndex) =>
/* determine which nav button is active depending on the activeIndex state */
<NavButton onSetActive={ () => this.handleChangeActive(buttonIndex)} active={buttonIndex === activeIndex } title={button.title} key={button.key} />)}
</div>
<div></div>
</nav>
)
}
}
ReactDOM.render(<NavBar />, document.querySelector("#app"));
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
.nav-item.nav-link {
background: grey;
}
.nav-item.nav-link.active {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<body>
<div id="app"></div>
</body>
I would move your state and logic to the NavBar component. It would be responsible to store and set the current active button, and pass it as prop to all buttons.
class NavBar extends Component {
state = {
activeButtonIndex: null;
}
buttons = [
{
title: "Home",
key: 0
},
{
title: "Team",
key: 1
},
];
renderButton = (button, index) => (
<NavButton
{...button}
isActive={this.state.activeButtonIndex === index}
setActive={() => this.setState({ activeButtonIndex: index })}
/>
);
render() {
return (
<nav className="navbar" id="navbarMain">
<div className="navbar-nav flex-row">
{this.buttons.map((button, index) => this.renderButton(button, index)}
</div>
</nav>
);
}
}
const NavButton = ({ isActive, setActive, href, title }) => (
<a
className={isActive ? "nav-item nav-link active" : "nav-item nav-link"}
href={href}
onClick={setActive}
>
{title}
</a>
);

How to handle state on Flat List Items in React-Native

I am setting a counter on the items of the FlatList component of React-Native. How can I update the list item every time the user press the "+" or "-" button?
I am currently being able to update the value on the state, however the list doesnt display the new state. I have tried adding extraData component to the FlatList, but it doesnt seem to update anyways.
This is the data structure
data: [
{
id: 1,
name: "Bread",
price: "400",
imageS: "../resources/pan-corteza-blanda.jpg",
quantity: 2
},
... more data
This is the function that handles the increment
handleIncrement = i => {
this.setState(state => {
const formatData = state.data.map((item, j) => {
console.log("Id", i + " /// " + item.id);
if (item.id === i) {
item.quantity = item.quantity + 1;
return item;
} else {
return item;
}
});
console.log("FormatData" + formatData); //Displays the correct quantity of the item updated
return {
formatData
};
});
};
And this is the list component
<FlatList
data={this.state.data}
style={styles.list}
extraData={this.state.data}
renderItem={this.renderItem}
/>
I expect to update the text component of the list item with the right quantity value every time a user presses the "+" or "-" button.
You need to update the data state instead of returning an item.
handleIncrement = i => {
const item = this.state.data[i];
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + 1 }),
...this.state.data.slice(i + 1)
]
});
};
You can refactor the function and use it for both - and +.
// pass array index and quantity 1 for + and -1 for -
handleIncrement = (i, qty) => {
const item = this.state.data[i];
if (item && item.quantity === 0 && qty === -1) {
return;
}
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + qty, }),
...this.state.data.slice(i + 1),
],
});
};
Below is demo that uses the above function, it's in reactjs. The function will work in react native too.
h1, p {
font-family: Lato;
}
.container {
display: flex;
flex-direction: row;
border-bottom-style: solid;
margin-bottom: 5px;
}
.image-container {
flex-grow: 0;
}
.info-container {
display: flex;
margin-left: 10px;
flex-direction: row;
}
.title {
margin-top: 0;
}
.titleContainer {
width: 100px;
}
.cover {
width: 30px;
}
.buttons {
flex-grow: 1;
display: flex;
margin-left: 10px;
}
.incrementButtons {
width: 20px;
height: 20px;
margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class Item extends React.Component {
render() {
return (
<div className="container">
<div className="image-container">
<img className="cover" src={this.props.image} />
</div>
<div className="info-container">
<div className="titleContainer">
<p className="title">{this.props.title}</p>
</div>
<div className="buttons">
<p className="title">{this.props.qty}</p>
<img onClick={() => this.props.increment(this.props.index, -1)} className="incrementButtons" src="https://img.icons8.com/metro/26/000000/minus-math.png" />
<img onClick={() => this.props.increment(this.props.index, 1)} className="incrementButtons" src="https://img.icons8.com/metro/26/000000/plus-math.png" />
</div>
</div>
</div>
)
}
}
class App extends React.Component {
state = {
data: [
{
id: 1,
name: 'Avocado',
price: '400',
imageS: 'https://img.icons8.com/metro/26/000000/avocado.png',
quantity: 0,
},
{
id: 6,
name: 'Bread',
price: '300',
imageS: 'https://img.icons8.com/metro/26/000000/bread.png',
quantity: 0,
},
{
id: 2,
name: 'Milk',
price: '300',
imageS: 'https://img.icons8.com/metro/26/000000/milk-bottle.png',
quantity: 0,
},
],
};
handleIncrement = (i, qty) => {
const item = this.state.data[i];
if (item && item.quantity === 0 && qty === -1) {
return;
}
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + qty, }),
...this.state.data.slice(i + 1),
],
});
};
render() {
const items = this.state.data.map((item, index) => (
<Item qty={item.quantity} index={index} key={index} increment={this.handleIncrement} title={item.name} image={item.imageS} />
))
return (
<div>
{items}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>
this.state.data is never changed on your handleIncrement, and this is what you are passing into FlatList. Thats why FlatList doesn't update.
After handleIncrement runs, the only thing that changes in your state is:
{
formatData: [...stuff here]
}
Maybe you want to pass down this.state.formatData instead or rename it in handleIncrement to data.
Also, your state structure would probably be better as a map, where the keys are itemIds. This way you don need to map through the whole list every time you want to increment the quantity.
e.g.
{
1: {
id: 1,
name: "Bread",
price: "400",
imageS: "../resources/pan-corteza-blanda.jpg",
quantity: 2
},
// more data...
}
Now, your handleIncrement looks like this:
handleIncrement = itemId => this.setState(prevState => ({
...prevState,
[itemId]: ++prevState[itemId].quantity
}))

React Component wont render in Codepen

I have a simple radio button group component on codepen here that is not rendering in codepen. I want to post this to the code review stackexchange, since it is one of the first components i've built and will be necessary in many places on a web app I am building. However for that post, I want my codepen example to be working.
I think I am probably breaking some rule about how to use es6 in react to get the app to render, but I am struggling to debug. My console.logs() are not helping, and the error messages in codepen arent helping a ton either.
Since I linked to my codepen, I have to accompany it with code, so here's what I have in my codepen at the moment:
import React, { Component } from 'react';
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap';
class ToolButtonGroup extends Component {
constructor(props) {
super(props);
};
render() {
// Get Variables from the params prop
const { header, buttons, initialVal } = this.props.params;
const { borderRadius, margin, padding, fontsize, border } = this.props.params;
const { gridID, gridColumns, minRowHeight } = this.props.params;
// Create the individual buttons
const pageButtons = buttons.map((buttoninfo, idx) => {
return (
<ToggleButton
key={idx}
style={{
"borderRadius": borderRadius,
"margin": margin,
"padding": padding,
"fontSize": fontsize,
"border": border
}}
bsSize="large"
value={buttoninfo.value}>
{buttoninfo.label}
</ToggleButton>
)
})
// Return the button group
return(
<div
style={{"border": "1px solid red" }}
id={gridID}>
<h2 style={{
"width": "100%",
"margin": "0 auto",
"fontSize": "1.75em",
"marginTop": "5px",
"border": "none"
}}
>{header}</h2>
<ToggleButtonGroup
type="radio"
name="charttype-options"
defaultValue={initialVal}
onChange={this.props.handler}
style={{
"display": "grid",
"gridTemplateColumns": "repeat(" + gridColumns + ", 1fr)",
"gridAutoRows": "auto",
"gridGap": "8px"
}}
>
{pageButtons}
</ToggleButtonGroup>
</div>
)
}
}
class StarterApp extends Component {
constructor(props){
super(props);
this.state = {
pitchersOrHitters: "",
position: ""
}
}
// Button and Select Handlers!
handlePitchHitChange = (pitchersOrHitters) => {
this.setState({pitchersOrHitters})
}
handlePositionChange = (position) => {
this.setState({ position: position });
}
render() {
console.log("A")
// 0. Load State and Props
const { pitchersOrHitters, position } = this.state;
// Pitcher or Hitter Radio Button Group params
const pitchOrHitButtonGroup = {
borderRadius: "25px",
margin: "1% 10%",
padding: "5%",
fontsize: "2em",
border: "2px solid #BBB",
gridColumns: 1, minRowHeight: "10px", "gridID": "buttons1",
header: "Choose One:",
buttons: [
{ value: "Pitchers", label: "Pitchers" },
{ value: "Hitters", label: "Hitters" },
],
initialVal: "Pitchers"}
// Pitcher or Hitter Radio Button Group params
const positionButtonGroup = {
borderRadius: "10px",
margin: "1% 10%",
padding: "5%",
fontsize: "1.25em",
border: "2px solid #BBB",
gridColumns: 4, minRowHeight: "20px", "gridID": "buttons2",
header: "Choose One:",
buttons: [
{ value: "SP", label: "SP" },
{ value: "RP", label: "RP" },
{ value: "1B", label: "1B" },
{ value: "2B", label: "2B" },
{ value: "SS", label: "SS" },
{ value: "3B", label: "3B" },
{ value: "LF", label: "LF" },
{ value: "RF", label: "RF" },
{ value: "CF", label: "CF" }
],
initialVal: "SP"}
return(
<div className="chart-grid-container">
<ToolButtonGroup
params={pitchOrHitButtonGroup}
value={pitchersOrHitters}
handler={this.handlePitchHitChange} />
<ToolButtonGroup
params={positionButtonGroup}
value={position}
handler={this.handlePositionChange} />
</div>
)
}
}
ReactDOM.render(
<StarterApp />,
document.getElementById('root')
);
.chart-grid-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: minmax(200px, auto);
grid-gap: 5px;
grid-template-areas:
"btns1 btns1 btns2 btns2 btns2 btns2 . . . . . .";
}
#buttons1 { grid-area: btns1; }
#buttons2 { grid-area: btns2; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react-dom.min.js"></script>
<div id='root'>
COME ON WORK!
</div>
Im unsurprisingly struggling to get this code snippet working as well. Although in this case, it is because I don't know how to include react-bootstrap, which is something I've already done in my codepen.
Thanks!
I noticed I got the errors when using import statements on that specific project.
This is probably a limitation of transpiling engine on the codepen. Better if you use some platform (ie: enter link description here) that already has all of these solved out for you.
Here is your code on codesandbox.

Resources