Having an active state toggler on multiple buttons - javascript

I am trying to have my buttons light up once clicked, and dim when clicked twice. To indicate the user has already clicked that button.
const [isActive, setActive] = useState("false");
const handleToggle = () => {
setActive(!isActive);
};
And my buttons are toggling with the following code
<button
type="button"
value="Peperoni, "
className={isActive ? "button btn first" : "button btn firstActive"}
onClick={(event) => {
ToppingPlusMinus(event);
}}
>
Pepperoni
</button>
So far I have this working, however the buttons are all tied to the same state so when one is clicked they all light up. I am stumped on how to downsize this and make each button toggle its active class individually.
I'm aware I could just brute force it with many states for each button, but I know there is a smarter solution on there.
Thank you in advance for your time.
My full code is on a codesandbox here

You need to create a component that tracks its own state and fires the onClick
const ButtonClickable = props => {
const [isActive, setActive] = useState(false);
const handleToggle = (ev) => {
setActive(!isActive);
props.onClick && props.onClick(props.value)
};
return <button
type="button"
className={isActive ? "button btn first" : "button btn firstActive"}
onClick={handleToggle}
>
{props.value}
</button>
}
Then in the parent compoennt
<ButtonClickable onClick={ToppingPlusMinus} value="Peperoni, "/>
<ButtonClickable onClick={ToppingPlusMinus} value="Other, "/>
<ButtonClickable onClick={ToppingPlusMinus} value="Milk, "/>
Note that ToppingPlusMinus becomes ToppingPlusMinus(value)

Related

js, react: cannot reenable a button that is rendered as disabled

i have a simple buttoN.
<Button id='button1' disabled onClick={() => buttonClick(false)}variant="contained">Text</Button>
This button is rendered as a grayed out version of itself, which is good.
Now, I want to enable the button. It should be:
document.getElementById("button1").disabled = false;
But nothing is enabled again.
What is the issue here?
Generally, you should avoid using document.getElementById and similar in React whenever possible.
To make your button enable, do the following:
const [isDisabled, setIsDisabled] = useState(true);
return (
<>
<Button id='button1' disabled={isDisabled} onClick={() => buttonClick(false)}variant="contained">Text</Button>
<div onClick={() => setIsDisabled(value => !value)}>toggle disabled</div>
</>
)

How to toggle style property using UseState

In react I would like to lock scroll-bar when sub-menu is out and then again unlock it when menu is hidden. I press the same button to open and close sub-menu (adds and removes translate for this element).
With what i did page sucessfully locks but when i press menu button and sub-menu dissapears the page is still locked, how can i change that the code is below:
const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive);
document.body.style.overflow = "hidden"
};
<div className="button"
onClick={toggleClass}
className={
isActive ? "nav-button closebtn active" : "nav-button closebtn"}>
<span></span>
</div>
how can I toggle the value of overflow from hidden to unset by pressing the button, just like i do with adding the class when i press the same button
Use toggle and add style in CSS file.
import './myStyle.css';
const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive);
document.body.classList.toggle('lock', isActive); // <-- Add this
};
<div className="button"
onClick={toggleClass}
className={
isActive ? "nav-button closebtn active" : "nav-button closebtn"}>
<span></span>
</div>
// myStyle.css
.lock {
overflow: hidden;
}
I believe that in your togle you have to validate if it is active or not and in that change the hidden to visible
Something like:
const toggleClass = () => {
setActive((active) => {
if(active){
document.body.style.overflow = "visible";
return !active;
}
document.body.style.overflow = "hidden";
return !active;
});
};

How to make same button to increase count and revert back to its previous state in React (useState)?

I want to change the count by one and make the same button revert back to its previous state on click.
export const CountButton = () => {
previousState = 100;
const [count, setCount] = useState(false);
return(
<div>
<button onClick={() => setCount(!count)}>Click Me!</button>
<div>{count ? previousState + 1 : previousState }</div>
</div>
)
}
This code will increase the vote by one and then revert on the second click.

get nested element from OnClicks target react

I'm trying to change Button's appearance onClick and then will have another button to save the set according to a check and then shipped to database.
With code below I have the button changing appearance/color but not the icon. The icon is nested within the button element like so:
<td key={i}>
<button
onClick={this.schedulerTableTimeChange}
className="waves-effect waves-light btn"
>
<i className="material-icons">check_box</i>
</button>
</td>
So can get the whole element with item.target and change the color with item.target.className = x but I also want to change the child element of the nested <i>child</i> as well to change the icon. How can I do this?
Here is my entire onClick:
schedulerTableTimeChange(item){
const green = 'waves-effect waves-light btn';
const red = 'waves-effect waves-light red btn';
if(item.target.className === red){
item.target.className = green
//change <i> child here here
}else if(item.target.className === green){
item.target.className = red
//change <i> child here here
}
}
also using materialize-css which accounts for the color and icon changes based on className
I would suggest a Button component, something like this:
import React, { Component } from "react";
class Button extends Component {
state = { checked: false };
clickHandler = e => {
this.setState({ checked: !this.state.checked });
if (this.props.onClick) {
this.props.onClick(e);
}
};
render() {
const { checked } = this.state;
const green = "waves-effect waves-light btn";
const red = "waves-effect waves-light red btn";
return (
<button onClick={this.clickHandler} className={checked ? green : red}>
<i className="material-icons">
{checked ? "check_box" : "somethingelse"}
</i>
</button>
);
}
}
export default Button;
Of course change somethingelse to the correct icon name... Here's a demo
HTH
-Ted

Add & Remove CSS classes with React

I am new to React. I have a few buttons in a button group:
<div className="btn-group">
<button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type1")} >Button1</button>
<button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type2")} >Button2</button>
<button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type3")} >Button3</button>
</div>
Whenever the user clicks on one of the buttons, this button should become the active, selected one. I found out that I need to add the CSS class active to the corresponding button, but I am not sure how to implement this.
I thought about this for a bit. I have a changeDataType function connected to my buttons, in which I do some other stuff. Would I then, in there, somehow manipulate the CSS?
So I guess my questions are first, how to target the button I need to target, and second, how I could change that button's CSS with React.
In react when state changes react re-renders. In your case if you want to change the way something looks then you probably want to force another render. What you can do is have the className be part of state and then update the state when you want, causing the component to re-render with the new className. For example:
constructor() {
super();
this.state = {
className: 'btn'
}
}
render () {
return (
<Button className={this.state.className}>Click me</Button>
)
}
Since the className is bound to state updating state will cause the button to render again with the new className. This can be done like this:
updateClass() {
let className = this.state.className;
className = className + ' ' + 'btn-primary'
this.setState({className})
}
This is an example of the function you can call on the click of a button and update the className for the button.
There's a nice utility you can use for classname logic + joining classNames together
https://github.com/JedWatson/classnames
Based on setting React state for active you could do something like the following. You can get as complex as you need to with the logic. If the logic result is falsy, that key won't be included in the output.
var classNames = require('classnames');
var Button = React.createClass({
// ...
render () {
var btnClass = classNames({
btn: true,
'btn-active': this.state.isActive
});
return <button className={btnClass}>{this.props.label}</button>;
}
});
Here how I did this:
//ChatRoomPage component
function ChatRoomPage() {
const [showActionDropdown, setShowActionDropdown] = useState('hide');
function showActionDropdownHandler(){
console.log("clicked")
if(showActionDropdown=='hide')
setShowActionDropdown('show')
else
setShowActionDropdown('hide')
}
return (
<div>
<button onClick={ () => showActionDropdownHandler() } className="btn " type="button">Actions</button>
<div className={`action_menu ${showActionDropdown}`}>
...
</div>
</div>
);
}
export default ChatRoomPage;

Categories

Resources