React js how to show clicked div and delete previous div content - html

Hello i have a question if some one could help.
I created a react app with tree buttons when i click on every button the code shows and hide text.
But i wanted when i click for example on button 2 the text from button 1 and 3 to be hidden. And the same for every button if i click on button 3 the text from button 1 and 2 to be hidden also.
import React, { useState } from 'react';
export default class Tinfo extends React.Component{
constructor(props){
super(props);
this.state = { show: new Array(3).fill(false) };
this.baseState = this.state
}
resetState = () => {
this.setState(this.baseState)
}
toggleDiv = (index) => {
var clone = Object.assign( {}, this.state.show );
switch(clone[index]){
case false:
clone[index] = true
break;
case true:
clone[index] = false
break;
}
this.setState({ show: clone });
}
render(){
return(
<div>
{ this.state.show[0] && <div id="tinfo"> First Div </div>}
{ this.state.show[1] && <div id="tinfo"> Second Div </div>}
{ this.state.show[2] && <div id="tinfo"> Third Div </div> }
<button onClick={() => this.toggleDiv(0)}>button 1</button>
<button onClick={() => this.toggleDiv(1)}>button 2</button>
<button onClick={() => this.toggleDiv(2)}>button 3</button>
</div>
)
}
}

since only one can be shown, then just reset the state
toggleDiv = index => {
const show = new Array(3).fill(false);
show[index] = true;
this.setState({
show
});
}
although this should now be named showDiv as it sets the state and hides the rest, it's not a toggle.

Related

Add and remove class on react buttons

I'm trying to create two buttons that will change its class when they are clicked. So when button one is clicked it will add "active" class to it and remove "active" class for sibiling button.
Now I have made some progress but the thing that is not working is that I want to add active class only when the element is clicked. So by default buttons shouldn't have any classes. When then user clicks on the first button, active class will be added to that button, then if user clicks on button two, it will remove active class from button one and add it to button two. The one more thing that isn't working as expected is when I click on the already clicked and already active button it changes the class and state. So it should be that when I click on already selected button it shouldn't do anything, the button with active state should remain active. It should basically work as jQuery toggleClass function.
My react code:
import React, { Component } from "react";
import css from "./styles.css";
export default class TypeButtons extends Component {
constructor(props) {
super(props);
this.state = { isActive: true };
}
ToggleClass = (e) => {
this.setState({ isActive: !this.state.isActive })
}
render() {
return (
<div className={css.buttonsContainer}>
<button onClick={this.handleClick} className={( !this.state.isActive ? '' : 'active' )} onClick={this.ToggleClass}>
Button 1
</button>
<button onClick={this.handleClick} className={( this.state.isActive ? '' : 'active' )} onClick={this.ToggleClass}>
Button 2
</button>
</div>
);
}
}
CSS:
.active {
background: green;
}
I have created Codesandbox example: https://codesandbox.io/s/vigorous-pare-3zo0s
So long story short, class should be added only after button has been clicked, so by default both buttons shouldn't have active class at start. Also when I click button with the active class it shouldn't change the active class, it should rather remain active, the state should only be changed when the opposite button is clicked.
Any help will mean a lot!
https://codesandbox.io/s/naughty-allen-vrj3r
Here, I edited your codesandbox.
Basically what I store in the state is a key that identifies the active button. It's null by default since that's what you wanted.
I assigned integers to each button but that can be whatever you want. You could also keep the integers, and add your buttons via a .map() to have a dynamic number of buttons for examples (see Constantin's answer).
class TypeButtons extends React.Component {
constructor(props) {
super(props);
this.state = { active: "0" };
this.buttons = [
{ id: "1", title: "Button 1" },
{ id: "2", title: "Button 2" }
];
}
handleClick = e => {
this.setState({ active: e.target.dataset.id });
};
render() {
return (
<div>
{this.state.active}
{this.buttons.map(({ id, title }) => {
return (
<button
key={id}
data-id={id}
onClick={this.handleClick}
className={this.state.active === id ? "active" : ""}
>
{title}
</button>
);
})}
</div>
);
}
}

How can a function value is displayed in a HTML tag with a return value from addEventListerner click?

I am trying to build a calculator and want to print digits on the screen. I have not yet put the calculator algorithm, just only to print the digits on the screen.
const Keys = ({calcKeys})=>(<div className="display-keys">
<div className="screen"><handleClick></div>
{calcKeys.map((item)=>{
return <button className="display-keys">{item.key}</button>
})
}
class App extends React.Component { constructor(props) { super(props);
this.state={calcKeys:[{"key": "AC"},{"key": "CE"},{"key": "±"},{"key": "/"},{"key": "7"},{"key": "8"},{"key": "9"},{"key": "x"},{"key": "4"},{"key": "5"},{"key": "6"},{"key": "-"},{"key": "1"},{"key": "2"},{"key": "3"},{"key": "+"},{"key": "."},{"key": "0"}]};}
this.displayKeys = this.displayKeys.bind(this)];
const keyButton = document.querySelector('.display-keys');
handleClick() {
keyButton.addEventListener('click', (e) => {
return const keyPad = e.key;
});
}
render(){
return(
<div className="display-container">
<Keys calcKeys={this.state.calcKeys}/>
</div>
);
}
}
ReactDOM.render( <App />, document.getElementById("root"));
For this case, if you want to click on the button you don't need to add an addEventListener.
As you are using React, you can create a function to handle click.
If you want to handle a keypress on the keyboard, that's the case to use addEventListener.
I changed your code a bit in order to make it work as expected. I didn't add any logic to make the calculator work but clicking on any button will add it to state and display on "screen".
This is what I did:
// "Keys" Component receives the calcKeys and the handleClick function.
// It uses the handleClick function on the button onClick passing the current item key
const Keys = ({ calcKeys, handleClick }) => (
<div className="display-keys">
{calcKeys.map(item => (
<button onClick={() => handleClick(item.key)}>{item.key}</button>
))}
</div>
)
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
calcKeys: [{"key": "AC"},{"key": "CE"},{"key": "±"},{"key": "/"},{"key": "7"},{"key": "8"},{"key": "9"},{"key": "x"},{"key": "4"},{"key": "5"},{"key": "6"},{"key": "-"},{"key": "1"},{"key": "2"},{"key": "3"},{"key": "+"},{"key": "."},{"key": "0"}],
value: '',
};
this.handleClick = this.handleClick.bind(this)
}
// Here I just receive the key and add it to state.
// This is the place to add logic, check if the key is "AC" for example and clean the state, etc.
handleClick(key) {
const { value } = this.state
this.setState({ value: `${value}${key}` })
}
render() {
const { value } = this.state
return (
<div className="display-container">
<div className="screen">{value}</div>
<Keys calcKeys={this.state.calcKeys} handleClick={this.handleClick} />
</div>
);
}
}
You can test it in a working JSFiddle here

How do I display text on button click in React.js

Have this code (below) and am trying to display the text at the click of a button in React.js.
Heres the code:
class App extends Component{
render(){
alert=()=>{return(<h1>Hi</h1>)}
return(<div className="App">
<button onClick={this.alert}>Enter</button>
</div>);
}}
export default App;
Any ideas why it's not working...?
If you want to display it in an alert window, you need to call a function to trigger the window.
class App extends Component{
onButtonClickHandler = () => {
window.alert('Hi')
};
render(){
return(<div className="App">
<button onClick={this.onButtonClickHandler}>Enter</button>
</div>);
}
}
However, if you need to show the message in your render, you can use a state to manage that.
class App extends Component{
state = {
showMessage: false
}
onButtonClickHandler = () => {
this.setState({showMessage: true});
};
render(){
return(<div className="App">
{this.state.showMessage && <p>Hi</p>}
<button onClick={this.onButtonClickHandler}>Enter</button>
</div>);
}
}
Source code:
If you need to toggle the text on button click, you just need to update the onButtonClickHandler function to this.setState({ showMessage: !this.state.showMessage });.
It won't display as like that. Here you are calling alert function and returning some JSX. How react will know where to render?. Do it like below.
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.state = {
render: false
}
this.alertHi = this.alertHi.bind(this);
}
alertHi() {
this.setState({render: !this.state.render});
}
render() {
return(
<div className="App">
<button onClick={this.alertHi}>Enter</button>
{this.state.render && <h1>Hi</h1>}
</div>
);
}
}
Demo

How to hide a div and replace it with another div in reactjs?

There are 2 divs. div1 and div2.
Initialy, div1 is shown and div2 is hidden.
Onclick of a button, div1 has to be hidden and div2 should be displayed in the place of div1.
Create a state to indicate whether div1 is to be shown or div2 is to be shown. Then, add a onClick handler function to the button. Finally, conditionally render which component is to be shown according to that state.
Code:
class TwoDivs extends React.Component {
state = {
div1Shown: true,
}
handleButtonClick() {
this.setState({
div1Shown: false,
});
}
render() {
return (
<div>
<button onClick={() => this.handleButtonClick()}>Show div2</button>
{
this.state.div1Shown ?
(<div className="div1">Div1</div>)
: (<div className="div2">Div2</div>)
}
</div>
);
}
}
You can achieve it by adding a new property inside component's state. Clicking the button will simply toggle that state, and the component will re-render, due to setState method. Please notice that this will toggle between the two divs. If you only want to show the second one, set the new state like this: this.setState({firstDivIsActive: false}
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
firstDivIsActive: true
};
}
render() {
let activeDiv;
if (this.state.firstDivIsActive) {
activeDiv = <div>I am one</div>;
} else {
activeDiv = <div>I am two</div>;
}
return (
<div>
<button
onClick={() => {
this.setState({
firstDivIsActive: !this.state.firstDivIsActive
});
}}
>
Toggle Div
</button>
{activeDiv}
</div>
);
}
}
I would have done like below in simple HTML and JQuery as below:
<input id="DivType" type="hidden" value="div1" class="valid" />
<div id="div1" />
<div id="div2" />
function ToggleDiv() {
var divType = $("#DivType").val();
if (divType === "div1") {
$("#div1").show();
$("#div2").hide();
$('#DivType input').value = "div2";
}
else if (divType === "div2") {
$("#div1").show();
$("#div2").hide();
$('#DivType input').value = "div1";
}
}
ToggleDiv will be called on OnClick event of button.
Not sure whether there is any better way to do it in React.
class ToggleDivs extends React.Component {
state = {
showDiv1: true,
}
handleButtonClick() {
this.setState({
showDiv1: !this.state.showDiv1
});
}
render() {
const { showDiv1 } = this.state;
const buttonTitle = showDiv1 ? 'Div2' : 'Div1';
const div1 = (<div className="div1">Div1</div>);
const div2 = (<div className="div2">Div2</div>);
return (
<div>
<button onClick={() => this.handleButtonClick()}>Show {buttonTitle}</button>
{showDiv1 ? div1 : div2}
</div>
);
}
}

Toggle between the visibility of 2 divs in reactjs

I have a simple reactjs website hosted on GitHub Pages. It lists articles, something like feeds in reddit. I have an AddArticle requirement, wherein, upon clicking the 'Add Article' button on the bottom of the page, the Div containing this button must become hidden, and a new Div for adding the details of the article(containing 2 text-boxes and a button named 'Submit') must show up. Upon clicking the 'Submit' button, the earlier Div has to reappear with the new Div getting hidden.
The following is the code I currently use(that is incomplete). Please go through it and provide any insight into the problem. Thanks.
class Child extends React.Component {
constructor(props) {
super(props);
this.onClickSubmitButton = this.onClickSubmitButton.bind(this);
this.state = {
showing: false
};
}
onClickSubmitButton(){
console.log('test-2');
this.setState(
{
showing: true
}
);
}
render() {
const { showing } = this.state;
return (
<div id="div_2">
<br/>
<input type="text" placeholder="Add the article title here" className="block_text"></input>
<br/><br/>
<input type="text" placeholder="Add the article text here" className="block_text"></input>
<br/><br/>
<button
type="button"
onClick={() =>
this.onClickSubmitButton()}
>
Submit
</button>
{ showing
? <div>This is visible</div>
: null
}
</div>
);
}
}
export default class AddArticle extends React.Component {
constructor(props) {
super(props);
this.onClickAddButton = this.onClickAddButton.bind(this);
this.state = {
error: undefined,
tempArticle: undefined,
childVisible: false,
parentVisible: true
};
}
onClickAddButton(){
console.log('test-1');
this.setState(
prevState => (
{
childVisible: !prevState.childVisible,
parentVisible: !prevState.parentVisible
}
)
);
}
// this is the render method
render() {
return (
<div id="div_1">
<br/><br/>
<button
type="button"
onClick={() =>
this.onClickAddButton()}
>
Add Article
</button>
{
this.state.childVisible
? <Child />
: null
}
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Here is a solution. You should had just send prop to the <Child /> component
DEMO