How to change the button text on click - javascript

import React from "react";
function ToDoItem(props) {
function but(){
document.getElementById('testBtn').value='ok'
}
return (
<div
>
<li>{props.text} <button class="deletebtn" onClick={() => {
props.onChecked(props.id);
}}><span>Delete</span></button>
</li>
<hr/>
<input type="button" value="Test" id="testBtn" onclick={but}/>
</div>
);
}
export default ToDoItem;
I wrote this function to change the value of the id from from "Test" to "ok", but I donot know why it is not working. When I use onclick="but()" instead of onclick={but}, it says the function but() is unused. I am not why is this not working. Please help

This is how you do it in React. You dont mix react, with DOM manipulation:
import React, {useState} from "react";
function ToDoItem(props) {
const [buttonText, setButtonText] = useState('Test');
return (
<div>
<li>
{props.text}
<button
class="deletebtn"
onClick={() => {
props.onChecked(props.id);
}}
>
<span>Delete</span>
</button>
</li>
<hr />
<input
type="button"
value={buttonText}
id="testBtn"
onClick={() => setButtonText("Ok")}
/>
</div>
);
}
export default ToDoItem;
And an, update for follow-up question. With the styling it depends what kind of styling you use in your react application. But you could use inline styling to get the behaviour you want. I for one use styled components when working in React...here's an updated code.
import React, { useState } from "react";
function ToDoItem(props) {
const [buttonText, setButtonText] = useState("Test");
const [buttonColor, setButtonColor] = useState("red");
const changeButton = () => {
setButtonText(buttonText === "Test" ? "Ok" : "Test");
setButtonColor(buttonColor === "red" ? "blue" : "red");
};
return (
<div>
<li>
{props.text}
<button
class="deletebtn"
onClick={() => {
props.onChecked(props.id);
}}
>
<span>Delete</span>
</button>
</li>
<hr />
<input
style={{ backgroundColor: buttonColor }}
type="button"
value={buttonText}
id="testBtn"
onClick={changeButton}
/>
</div>
);
}
export default ToDoItem;

Adding to my comments, your code reimplemented with hooks.
import React, { useState } from "react";
function ToDoItem(props) {
const [value, setValue] = useState('Test');
function but(){
setValue('ok');
}
return (
<div>
<li>{props.text} <button class="deletebtn" onClick={() => {
props.onChecked(props.id);
}}><span>Delete</span></button>
</li>
<hr/>
<input type="button" value={value} id="testBtn" onclick={but}/>
</div>
);
}
export default ToDoItem;

Related

My innerHTML is coming out to be null despite using id or class or querySelector

This is the most frequent problem I come across, in this file was trying to access the innerHTML of the textarea using the same property.
But the error says that the input.innerHTML is null.
You can understand better by code,
import React, { Component, useEffect, useState } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
let noteArray;
let input = document.getElementById('.input_area') ;
const AddNote = () =>{
console.log("here" ,input.innerHTML) ;
}
return (
<>
<div>
<div className="input_info">
<textarea id='input_area' name="" cols="50" rows="5">op</textarea>
<br />
<button onClick={AddNote} className='add'>Add Note</button>
</div>
<br />
<div id='display_info' >
</div>
</div>
</>
)
}
I tried from class, id, and querySelector but none of them is working.
Can anyone suggest me some edits?
EDIT--
To be sure that the elements of the component has been mounted to the DOM you need to execute the selection queries in useEffect hook, Also you need to use value attribute instead of innerHTML
import React, { Component, useEffect, useState } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
let noteArray;
useEffect(() => {
let input = document.getElementById('.input_area');
console.log("here" ,input.value);
})
const AddNote = () =>{
let input = document.getElementById('.input_area');
console.log("here" ,input.value);
}
return (
<>
<div>
<div className="input_info">
<textarea id='input_area' name="" cols="50" rows="5">op</textarea>
<br />
<button onClick={AddNote} className='add'>Add Note</button>
</div>
<br />
<div id='display_info' >
</div>
</div>
</>
)
}
But, I suggest you use useRef instead of DOM select queries.
For example
import React, { Component, useEffect, useState, useRef } from 'react'
import './Body.css';
import axios from "axios";
import './Body.css'
export default function Navbar() {
let noteArray;
const textAreaRef = useRef(null)
useEffect(() => {
console.log(textAreaRef.current.value)
})
const AddNote = () =>{
console.log(textAreaRef.current.value)
}
return (
<>
<div>
<div className="input_info">
<textarea ref={textAreaRef} id='input_area' name="" cols="50" rows="5">op</textarea>
<br />
<button onClick={AddNote} className='add'>Add Note</button>
</div>
<br />
<div id='display_info' >
</div>
</div>
</>
)
}
const { useState } = React;
function Navbar() {
const [input, setInput] = useState("op");
const [noteArray, setNoteArray] = useState([])
const addNote = () => {
setNoteArray((prevState) => ([...prevState, input]))
}
const inputChange = (e) => {
setInput(e.target.value)
}
return (
<div>
<div className="input_info">
<textarea id='input_area' name="" cols="50" rows="5" value={input} onChange={e => inputChange(e)}></textarea>
<br />
<button className='add' onClick={addNote}>Add Note</button>
</div>
<br />
<div id='display_info' >
<ul>
{noteArray.map(val => {
return <li>{val}</li>
})
}
</ul>
</div>
</div>
);
}
ReactDOM.render(<Navbar />, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<body id="root"></body>
I guess this is what you want to achieve and a better pattern in react. Also you can improve it by changing the data structure of note array

How to get a variable back from a called component

I have a problem: I have my main class Input.js. A user can select a photo and upload it. The problem is I want to check if the user uploaded a photo or not when he press the button. For example I can give from Profilepic.js to Pic.js the picture as props. But how could I get back a variable? For example I want to set the variable in Profilepic.js and when the user I pressing the button the method onClick() should executed. Inside of this method it should check which value the variable isPreview has. And if the User hasnt uploaded a picture there should be a lable signaling him that he has to upload an image to continue.
Input.js
import React, { useState, useEffect } from 'react';
import { InputTags } from 'react-bootstrap-tagsinput';
import 'react-bootstrap-tagsinput/dist/index.css';
import './Input.css';
import Profilepic from './Profilepic';
const Input = () => {
const checkAll = () => {
// Call Preview from Profilepic.js
}
return (
<div className="body-container">
<Profilepic></Profilepic>
<div className="row gutters">
<div className="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
<div className="text-right">
<button type="button" id="submit" name="submit" className="btn btn-primary" onClick={checkAll}>Speichern & Weiter <i class="fas fa-paper-plane"></i></button>
</div>
</div>
</div>
</div>
);
}
export default Input
Profilepic.js
import React, { useState } from "react";
import { Pic } from "./Pic.js";
const Profilpic = () => {
const [preview, setPreview] = useState(null);
const [isPreview, setIsPreview] = useState(false);
const fileSelectedHandler = (event) => {
try {
console.log(event.target.files[0]);
if (event.target.files[0].size > 70001680) {
alert("File is too big! Wie Samys Dick");
} else {
let img = URL.createObjectURL(event.target.files[0]);
setPreview(img);
setIsPreview(true);
}
}
catch (err) {
}
};
return (
<div>
{preview ? (
<div>
<label htmlFor="myInput">
<Pic preview={preview}></Pic>
</label>
<input
id="myInput"
style={{ display: "none" }}
type={"file"}
onChange={fileSelectedHandler}
/>
</div>
) : (
<div>
<label htmlFor="myInput">
<i className="fas fa-user-circle"></i>
</label>
<input
id="myInput"
style={{ display: "none" }}
type={"file"}
accept=".png,.jpg,.jpeg, .jfif"
onChange={fileSelectedHandler}
/>
</div>
)}
</div>
);
};
export default Profilpic;
Pic.js
import React from "react";
import "./Photo.css";
const STYLES = ["btn--primary", "btn--outline", "btn--test"];
const SIZES = ["btn--medium", "btn--large"];
export const Pic = ({ preview }) => {
//const checkButtonStyle = STYLES.includes(buttonStyle) ? buttonStyle : STYLES[0];
//const checkButtonSize = SIZES.includes(buttonSize) ? buttonSize : SIZES[0];
// Püsh for Samy
return (
<div class="profilepic">
<img
class="profilepic__image"
src={preview}
width="120"
height="120"
alt="Profibild"
/>
<div class="profilepic__content">
<span class="profilepic__icon">
<i class="fas fa-camera"></i>
</span>
<span class="profilepic__text">Profilbild ändern</span>
</div>
</div>
);
};
Description of the Problem
You can use the useImperativeHandle. This requires a bit of a wrapping of
Profilepic
import React, { forwardRef, useImperativeHandle, useState } from "react";
import { Pic } from "./Pic.js";
function Profilepic(props, ref) {
const [preview, setPreview] = useState(null);
const [isPreview, setIsPreview] = useState(false);
useImperativeHandle(
ref,
() => ({ isPreview }),
[isPreview]
);
...
return (
...
);
};
export default forwardRef(Profilepic);
Input
import React, { useState, useEffect, useRef } from 'react';
import Profilepic from './Profilepic';
const Input = () => {
const profilePicRef = useRef();
const checkAll = () => {
// access profilePicRef.current.isPreview
}
return (
<div className="body-container">
<Profilepic ref={profilePicRef} />
...
<button
type="button"
id="submit"
name="submit"
className="btn btn-primary"
onClick={checkAll}
>
Speichern & Weiter <i class="fas fa-paper-plane" />
</button>
...
</div>
);
}

Deleting multiple items in checkboxes at once using REACT

I'm trying to delete multiple items at once for checkboxes in REACT, but the code does not seem to delete the items being checked.
Here's my approach to doing this. I made a function in tasks.jsx file
called add_ids_to_be_deleted to append the id that was being checked
in the checkbox to an array of ids to be deleted called list_of_ids.
This function is called in the child component in priorityLists.jsx.
When the user clicks the delete button, I created a useEffect to
filter out all the items in toDo whose ids are not included in the ids
to be deleted.
The problem is it keeps deleting the last item whenever I check a checkbox regardless of the order.
For example, I add 3 checkboxes and
check the first checkbox to delete it. Instead of the first checkbox
being deleted, the last item is deleted even though it wasn't being
checked.
tasks.jsx
import React, { useState, useEffect } from 'react';
import { Delete, Refresh, Add } from '../components/Actions';
import { Header } from '../components/Header';
import ToDoList from '../components/TaskList';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faPlus, faTrash } from '#fortawesome/free-solid-svg-icons';
import { v4 as uuidv4 } from 'uuid';
function Task() {
const [toDo, setToDo] = useState([]);
const [idsToRefresh, setIdsToRefresh] = useState([]);
const [list_of_Ids, setIds] = useState([]);
const [filter_now, setFilterNow] = useState(false);
function addToDos() {
const id = uuidv4();
setToDo(
toDo.concat({
_isKey: id,
_checked: false,
value: <ToDoList _onDelete={add_Ids_ToBe_Deleted} _key={id} />
})
);
setIdsToRefresh(idsToRefresh.concat(id));
}
function switchNow() {
if (!filter_now) {
setFilterNow(true);
} else {
setFilterNow(false);
}
}
useEffect(() => {
if (toDo[0] !== undefined) {
setToDo(
toDo.filter(item => {
return !list_of_Ids.includes(item._isKey);
})
);
}
}, [filter_now]);
function add_Ids_ToBe_Deleted(_id_ToBe_Deleted) {
setIds(item => [...item, _id_ToBe_Deleted]);
}
function refresh() {
setToDo(
toDo.filter(item => {
return !idsToRefresh.includes(item._isKey);
})
);
}
return (
<div className="main-content">
<div className="container-fluid">
<div className="row underline">
<div className="col">
<div className="row">
<div className="col-3 pt-2">
<Refresh _refresh={refresh} />
</div>
<div className="col-6 text-center">
<Header header={'Tasks'} />
</div>
<div className="col-3 pt-2">
<button className="float-right">
<FontAwesomeIcon
onClick={switchNow}
icon={faTrash}
size="2x"
/>
</button>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col">
{toDo.map(item => {
return (
<div>
<ul>
<li>{item.value}</li>
</ul>
</div>
);
})}
</div>
</div>
<div className="row">
<div className="col pr-4">
<button onClick={addToDos} className="float-right" name="add">
<FontAwesomeIcon icon={faPlus} size="2x" />
</button>
</div>
</div>
</div>
</div>
);
}
export default Task;
Tasklist.jsx
import React from 'react';
import { PriorityLists } from '../components/PriorityLists';
import { Priority } from './Actions';
function ToDoList(props) {
return (
<PriorityLists
_onDelete={props._onDelete}
keys={props._key}
name="toDoList"
>
<Priority />
</PriorityLists>
);
}
export default ToDoList;
Prioritylists.jsx
import React, { useState, useEffect } from 'react';
import { Priority } from './Actions';
function PriorityLists(props) {
return (
<form>
<div className="input-group mb-3">
<div className="input-group-prepend">
<div className="input-group-text">
<input
is_checked={false}
unique_Key={props.keys}
onClick={e =>
props._onDelete(
e.target.attributes.getNamedItem('unique_Key').value
)
}
id="check-item"
type="checkbox"
aria-label="Checkbox for following text input"
/>
</div>
</div>
<textarea class="form-control" rows="1" name={props.name}></textarea>
{props.children}
</div>
</form>
);
}
export { PriorityLists };

Switch Button using Hooks in ReactJS to display different content

I'm trying to create a switch button that can display 2 different contents depending on which of the 2 buttons I click on using the hooks in react js.
I would like to display for example a sentence "You have clicked on the left button" when I click on the left one and the opposite when I click on the right one.
I would like the content to be displayed just below the switch buttons.
In addition, I would like my button to remain active when I clicked on it. That is to say, it should be of a darker color since it is active.
Do you have an idea?
This is the piece of code :
import React,{useState} from 'react';
import {Button} from "react-bootstrap";
import {FontAwesomeIcon} from "#fortawesome/react-fontawesome";
import {faBars, faChartLine} from "#fortawesome/free-solid-svg-icons";
import CustomerTable from "../CustomerTable/CustomerTable";
export default function HookButtonSwitch(props) {
const [resultatContenu, setResultatContenu] = useState('Content initial');
const [state, setState] = useState(false);
const handleEventSwitchButton = event => {
let resultatContenu;
switch(event.target.id) {
case 'stats':
console.log("Coucou Stats");
resultatContenu = 'Stats';
break;
case 'list':
console.log("Coucou List");
resultatContenu = 'LIST';
break;
}
setResultatContenu(resultatContenu);
};
const toggle = () => setState(!state);
return (
<div>
<br />
<Button
id="list"
variant="light"
className="border-radius-left"
onClick={handleEventSwitchButton}
>
<FontAwesomeIcon icon={faBars} />
</Button>
<Button
id="stats"
variant="light"
className="border-radius-right"
onClick={handleEventSwitchButton}
>
<FontAwesomeIcon icon={faChartLine} />
</Button>
<div> {resultatContenu} </div>
{/* <p>-------</p>
<div onClick={toggle}>
<div className="toggle">
{state ? <div>Yes! 👍 </div> : <div>No! 👎</div>}
</div>
</div>
*/}
</div>
)
}
Thank you in advance.
check hope its work
import React,{useState} from 'react';
import {Button} from "react-bootstrap";
import {FontAwesomeIcon} from "#fortawesome/react-fontawesome";
import {faBars, faChartLine} from "#fortawesome/free-solid-svg-icons";
import CustomerTable from "../CustomerTable/CustomerTable";
export default function HookButtonSwitch(props) {
const [resultatContenu, setResultatContenu] = useState('Content initial');
const [state, setState] = useState(false);
const handleEventSwitchButton = (event,condition) => {
this.setState({buttonSwitch:condition})
let resultatContenu;
switch(event.target.id) {
case 'stats':
console.log("Coucou Stats");
resultatContenu = 'Stats';
break;
case 'list':
console.log("Coucou List");
resultatContenu = 'LIST';
break;
}
setResultatContenu(resultatContenu);
};
const toggle = () => setState(!state);
const {buttonSwitch=false}= this.state
return (
<div>
<br />
<Button
id="list"
variant="light"
className="border-radius-left"
style={buttonSwitch&&{backgroundColor:'black'}}
onClick={(e)=>handleEventSwitchButton(e,true)}
>
<FontAwesomeIcon icon={faBars} />
</Button>
<Button
id="stats"
variant="light"
className="border-radius-right"
style={!buttonSwitch&&{backgroundColor:'black'}}
onClick={(e)=>handleEventSwitchButton(e,false)}
>
<FontAwesomeIcon icon={faChartLine} />
</Button>
<div> {resultatContenu} </div>
{/* <p>-------</p>
<div onClick={toggle}>
<div className="toggle">
{state ? <div>Yes! 👍 </div> : <div>No! 👎</div>}
</div>
</div>
*/}
</div>
)
}

How ReactJS display fetch response onClick

I am trying to generate a random user information when pressing the button, and display the information above the button. In ProfilePanel.js, I created a avatar and user constants, which will use to show the information. In index.js, the avatar constant works for that since it doesn't need to use the Button. however, for user constant, it doesn't work. In below's code, I am fetching a api data to display user name, but it didn't show anything, I am not sure where wrong, is something wrong in Button.js or index.js. and how can I fix it. Can somebody help me out? Thanks.
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
index.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Panel from "./ProfilePanel";
import axios from 'axios';
import './index.css';
import Button from './Button';
const url = 'https://randomuser.me/api/';
class App extends Component {
constructor(props) {
super(props);
this.state = {
contacts: []
}
}
componentDidMount() {
this.fetchdata();
}
fetchdata() {
axios.get(url)
.then(res => {
console.log(res);
this.setState({ contacts: res.data.results});
});
}
render(){
const {contacts} = this.state;
return (
<div className="panel">
{contacts.map(contact => (
<div class="panel">
<Panel
key={contact.picture} avatar={contact.picture.medium}
/>
<li class="flex-container">
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
<Button title="location" onClick={this.fetchdata}>
</Button>
<Button key={contact.email} title="email">
</Button>
<Button key={contact.phone} title="phone">
</Button>
<Button key={contact.login.password} title="password">
</Button>
</li>
</div>
))}
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
ProfilePanel.js
import React, { Component } from "react";
import PropTypes from "prop-types";
import './index.css';
import Button from './Button';
const style={
borderRadius: 150,
margin: 15,
}
class Panel extends Component {
render() {
const { avatar, user } = this.props;
return (
<div className="Panel">
<div class="panels">
<div className="avatar">
<img src={avatar} class="imageStyle" alt="" width={"200%"} height={"auto"}/>
</div>
</div>
<div class="center">
<h2 className="user">{user}</h2>
</div>
</div>
);
}
}
export default Panel;
Button.js
import './index.css';
import React, { Component } from 'react';
class Button extends Component {
constructor(props) {
super(props);
this.state = {
open:false,
};
}
render() {
const { title } = this.props;
const {open} = this.state;
return (
<button className={` ${open ? 'open' : ''}`}
class='button' onClick={(e) => this.handleClick(e)}>
<div className="panel-heading">
<h2 class='buttoncenter'>{title}</h2>
</div>
</button>
);
}
handleClick(e) {
e.preventDefault();
this.setState({
open: this.state.open
})
}
}
export default Button;
You're not changing state in the handle click. You need to set open to true;
handleClick(e) {
e.preventDefault();
this.setState({
open: true
})
}
You need to pass your user information in index.js. I think you have missed to pass the user props to the panel component, so that it shows the avatar alone. Without passing the users props, you are trying to destructure there in panel component.
//index.js should be like this
render(){
const {contacts} = this.state;
return (
<div className="panel">
{contacts.map(contact => (
<div class="panel">
<Panel
key={contact.picture} user={contact.name} avatar={contact.picture.medium}
/>
<li class="flex-container">
<Button title="name" >
<p key={contact.name} user={contact.name}></p>
</Button>
<Button title="location" onClick={this.fetchdata}>
</Button>
<Button key={contact.email} title="email">
</Button>
<Button key={contact.phone} title="phone">
</Button>
<Button key={contact.login.password} title="password">
</Button>
</li>
</div>
))}
</div>
);
}

Categories