Using state data as a props in other component conditionally - reactjs

Here is my one component DISPLAY,
import React, { Component } from "react";
import ListGroup from "./listGroup";
class Display extends Component {
handleAllClick = (e) => {
e.preventDefault();
return (
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
handleCompleted = (e) => {
e.preventDefault();
return (
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
render() {
return (
<div>
<button
type="button"
className=" all btn btn-light p-1 mr-3"
onClick={this.handleAllClick}
>
All
</button>
<button
type="button"
className=" act btn btn-light p-1 mr-3"
onClick={this.handleActiveClick}
>
Active
</button>
<button
type="button"
className=" comp btn btn-light p-1"
onClick={this.handleCompleted}
>
Completed
</button>
</div>
);
}
}
export default Display;
Actually I want to use state which is named by data in the main component and that data contains a boolean variable called completed.
Now I wanted to conditionally use this completed as props with ListGroup component(Which I have imported above).
This should look like this:
handleCompleted = (e) => {
e.preventDefault();
(!this.props.completedItem &&
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
(I have passed this completed as completedItem in the main component).
But the problem is this is not working the right way!

Related

How to make different webpages have different background using react (Backgriound should be maintained after refreshing as well)

Home.js file
const Home = () =>
{
var navigate = useNavigate();
const move = () => {
navigate("/builder");
var change = document.getElementsByTagName('html');
change[0].style.backgroundImage = "linear-gradient(to top, #370514, #722423, #a95026, #d3861d, #ebc512)";
}
return(
<div className="fullpage">
<div className="middle"> <h1>Undirected Graph Maker</h1>
<div className="aligner">
<button type="button" onClick={move} className="btn">Unweighted</button>
<button type="button" onClick={move} className="btn">Weighted</button>
</div>
</div>
</div>
);
}
export default Home;
This only changes the background on the button click and does not preserve it
We have declared a variable to store the initial background of the div. This is assigned to the React component state called background.
So, Whenever the state update on button click. it update the background of the div also.
function Home() {
const initialBackgroundColor =
'radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%)';
const [background, setBackground] = useState(initialBackgroundColor);
return (
<div className="fullpage" style={{ background }}>
<div className="middle">
<h1>Undirected Graph Maker</h1>
<div className="aligner">
<button
type="button"
onClick={() => {
setBackground(initialBackgroundColor);
}}
className="btn"
>
Unweighted
</button>
<button
type="button"
onClick={() => {
setBackground(
'linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,153,45,1) 100%)'
);
}}
className="btn"
>
Weighted
</button>
</div>
</div>
</div>
);
}
export default Home

In react js i create a todo app but when i am doing todo-delete it by default delete the first item why?

In react js i create a todo app but when i am doing todo-delete it by default delete the first item why?In react js i create a todo app but when i am doing todo-delete it by default delete the first item why?In react js i create a todo app but when i am doing todo-delete it by default delete the first item why?
import React, { useState } from "react";
import "./App.css";
const Todo = () => {
const [inputData, setInputData] = useState("");
const [items, setItems] = useState([]);
const addItem = (e) => {
let pattern = /\s/g.test(inputData);
// This pattern check empty space and InputData is checking null
if (pattern === false && inputData !== "") {
setItems([...items, inputData]);
setInputData("");
}
setInputData("");
};
// delete items
const deleteItem = (idx) => {
// console.log(idx);
let temp = [...items];
// console.log(temp);
temp.splice(idx, 1);
setItems(temp);
};
// done items
// const doneItem = (idx) => {};
return (
<>
<div className="container">
<h1 className="bg-dark text-white">Todo App</h1>
<div className="d-flex p-2 justify-content-between">
<input
type="text"
className="form-control"
placeholder="Add Your New Todo"
value={inputData}
onChange={(e) => {
setInputData(e.target.value);
// console.log(e);
// console.log(e.nativeEvent.data);
}}
/>
<button className="btn btn-dark m-1" onClick={addItem}>
+
</button>
</div>
{items.map((element, idx) => {
console.log(element);
console.log(idx);
return (
<div
className="d-flex justify-content-between p-2 bg-dark text-white"
key={idx}
>
<h4>{element}</h4>
<button
className="btn btn-danger"
onClick={(idx) => {
deleteItem(idx);
}}
>
X
</button>
{/* <button onClick={() => doneItem(idx)}>-</button> */}
</div>
);
})}
</div>
</>
);
};
export default Todo;
<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>
The problem starts in this code.
<button
className="btn btn-danger"
onClick={(idx) => { // problem starts here
deleteItem(idx);
}}
>
X
</button>;
You are already using idx as an index for your values in the map function. Button basically gives you the event and you are representing the same variable. Just remove that variable from the button onClick event and everything works fine.
Attached a sandbox

How to use button to pop up video window(ReactJs)

i'm trying to make a button that use the same style but want to use it for two button (1) go to some page (2) to pop up a video trailer. but both of them do the action (1). I don't know how to make these two button do different job.
here is the code for Button,
import React from 'react';
import './Button.css';
import { Link } from 'react-router-dom';
const STYLES = ['btn--primary', 'btn--outline', 'btn--test'];
const SIZES = ['btn--medium', 'btn--large'];
export const Button = ({
children,
type,
onClick,
buttonStyle,
buttonSize
}) => {
const checkButtonStyle = STYLES.includes(buttonStyle)
? buttonStyle
: STYLES[0];
const checkButtonSize = SIZES.includes(buttonSize) ? buttonSize : SIZES[0];
return (
<Link to={Button.props.action} className='btn-mobile'>
<button
className={`btn ${checkButtonStyle} ${checkButtonSize}`}
onClick={onClick}
type={type}
>
{children}
</button>
</Link>
);
};
here is the code for two buttons
function HeroSection() {
return (
<div className='hero-container'>
<video src='/videos/animated-banner.mp4' autoPlay loop muted playsInline/>
<h1>TITLE</h1>
<p> simple text.</p>
<div className='hero-btns'>
<Button
className='btns'
buttonStyle='btn--outline'
buttonSize='btn--large'
>
GET STARTED
</Button>
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'
onClick={console.log('hey')}
>
WATCH TRAILER <i className='far fa-play-circle' />
</Button>
</div>
</div>
);
}
export default HeroSection;
you can use onClick event for different jobs.
<Button
className='btns'
buttonStyle='btn--outline'
buttonSize='btn--large'
onClick={() => {
// ...go to some page...
}}
>
GET STARTED
</Button>
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'
onClick={() => {
// ...open pop up...
}}
>
WATCH TRAILER <i className='far fa-play-circle' />
</Button>
IMO, I think you could add new props to and conditionally use tag either Link or button by checking that props. If you pass value to props to then will be rendered as Link, else as button
import React from 'react';
import './Button.css';
import { Link } from 'react-router-dom';
const STYLES = ['btn--primary', 'btn--outline', 'btn--test'];
const SIZES = ['btn--medium', 'btn--large']
export const Button = ({
children,
type,
onClick,
buttonStyle,
buttonSize,
to
}) => {
const checkButtonStyle = STYLES.includes(buttonStyle)
? buttonStyle
: STYLES[0];
const checkButtonSize = SIZES.includes(buttonSize) ? buttonSize : SIZES[0];
const ActionTag = to ? Link : 'button';
return (
<ActionTag
className={`btn ${checkButtonStyle} ${checkButtonSize}`}
onClick={onClick}
type={type}
to={to}
>
{children}
</ActionTag>
);
};
and you could use that component like this.
If it's used to navigate to other page, pass value to props to
For popping up a video trailer pass props onClick
<Button
className='btns'
buttonStyle='btn--outline'
buttonSize='btn--large'
onClick={
// do something
}
>
pop up
</Button>
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'
to="/"
>
go to home
</Button>

Moving an item from Todolist to delete list and delete it from TodoList

Hello i want to move an item from todo list to delete list in ReactJS and i want to delete it from todo list when i move it to done list i did everything i can delete the selected item or all items but i cant add it to done list when i move it
import React from 'react';
import './App.css';
import Todoinput from './Components/Todoinput'
import Todolist from './Components/Todolist'
import Tododone from './Tododone'
import { render } from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import uuid from 'uuid';
class App extends React.Component {
state= {
items:[],
id:uuid(),
item:'',
editItem:false
}
handleChange = (e) => {
this.setState ({
item:e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault ();
const newItem = {
id:this.state.id,
title:this.state.item,
};
const updatedItems = [...this.state.items,newItem]
this.setState ({
items:updatedItems,
item:'',
id:uuid(),
editItem:false
})
}
clearList = (e) => {
this.setState ({
items:[]
})
}
doneItem = (id) => {
const doneItems = this.state.items.filter (item => item.id !== id);
this.setState ({
items:doneItems,
})
}
handleEdit = (id) => {
const doneItems = this.state.items.filter (item => item.id !== id);
const selectedItem = this.state.items.find(item=> item.id === id)
console.log(selectedItem)
this.setState ({
items:doneItems,
item:selectedItem.title,
editItem:true,
id:id
})
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-10 mx-auto col-md-8 mt-4">
<h3 className="text-capitalize text-center">Todo Inputs</h3>
<Todoinput item={this.state.item} handleChange={this.handleChange}
handleSubmit={this.handleSubmit}
editItem={this.state.editItem}
/>
<Todolist items={this.state.items} clearList={this.clearList} doneItem={this.doneItem} handleEdit={this.handleEdit}/>
<Tododone doneItem={this.doneItem} />
</div>
</div>
</div>
);
}
}
export default App;
/**/
import React from 'react'
import Todoitem from './Todoitem'
class Todolist extends React.Component {
render() {
const {items,clearList,doneItem,handleEdit}=this.props
return (
<ul className="list-group my-5">
<h3 className="text-capitalize text-center">todo list</h3>
{
items.map(item => {
return (
<Todoitem
key={item}
title={item.title}
doneItem={()=> doneItem(item.id)}
handleEdit={()=> handleEdit(item.id)}
/>
)
})
}
<button type="button" className="btn btn-danger btn-block text-capitalize mt-5"
onClick={clearList}
>clear list</button>
</ul>
)
}
}
export default Todolist
/**/
import React from 'react'
class Todoinput extends React.Component {
render() {
const {item,handleChange,handleSubmit,editItem} = this.props
return (
<div className="card card-body my-3">
<form onSubmit={handleSubmit}>
<div className="input-group">
<div className="input-group-prepend">
<div className="input-group-text bg-primary text-white">
<i className="fa fa-book" ></i>
</div>
</div>
<input type="text" className="form-control text-capitalize" placeholder="Add A To Do Item"
value={item}
onChange={handleChange}
/>
</div>
<button type="submit"
className={editItem ? "btn btn-block btn-success mt-3" : "btn btn-block btn-primary mt-3" }>
{editItem ? 'Edit Item' : "Add Item"}</button>
</form>
</div>
)
}
}
export default Todoinput
/**/
import React from 'react'
class Todoitem extends React.Component {
render() {
const {title,doneItem,handleEdit} = this.props
return (
<li className="list-group-item text-capitalize d-flex justify-content-between my-2">
<h6>{title}</h6>
<div className="todo-icon">
<span className="mx-2 text-success" onClick={handleEdit}>
<i className="fa fa-edit"></i>
</span>
<span className="mx-2 text-danger"onClick={doneItem}>
<i className="fa fa-window-close"></i>
</span>
</div>
</li>
)
}
}
export default Todoitem
/**/
import React from 'react'
class Tododone extends React.Component {
render() {
const {items,clearList,doneItem,title,item}=this.props
return (
<div>
<h2 className="text-capitalize text-center">Done Items</h2>
<li className="list-group-item text-capitalize d-flex justify-content-between my-2">
<h6>{item}</h6>
<div className="todo-icon">
<span className="mx-2 text-danger" onClick={doneItem}>
<i className="fa fa-trash"></i>
</span>
</div>
</li>
<button type="button" className="btn btn-danger btn-block text-capitalize mt-5"
onClick={clearList}>clear list</button>
</div>
)
}
}
export default Tododone
so if anyone can help Please i post all the code above if anyone can help me please <
To track if a task is done, add a isDone field to item, when you say it's done, flag it to true.
So when you create a new item:
const newItem = {
id:this.state.id,
title:this.state.item,
isDone: false
};
When you render items that are not done, filter through isDone===false, like this:
<Todolist items={this.state.items.filter(item => item.isDone === false)} ... />
When you delete an item from the ToDoList you want it to go to the DoneList, so you set your doneItem function like this:
doneItem = id => {
const newItems = [...this.state.items];
const item = newItems.find(item => item.id === id);
item.isDone = true;
this.setState({
items: newItems
});
}
When you render the done list, filter through isDone === true, like this:
<Tododone items={this.state.items.filter(item => item.isDone === true)} ... />
Now get the items prop in Tododone and map it to see the done items, this below is just an example:
{items.map(item => (
<li className="list-group-item text-capitalize d-flex justify-content-between my-2">
<h6>{item.title}</h6>
<div className="todo-icon">
<span className="mx-2 text-danger" onClick={doneItem}>
<i className="fa fa-trash"></i>
</span>
</div>
</li>
))}
Since I don't know what you want to do with those divs and spans I'll leave them like you set them.
When you click on clear list I assume you want to delete only the todoList or only the doneList, I suggest you to pass a flag to tell App which list to clear.
Here's the sandbox with your code that solves your problem.
down and dirty because I have to head to work would be to add something like doneItemsArray: [] in your state and then just do another filter in your doneItem method.
doneItem = id => {
const filteredTodos = this.state.items.filter(item => item.id !== id);
const doneItem = this.state.items.filter(item => item.id === id);
this.setState({
items: doneItems,
doneItemsArray: [...this.state.doneItemsArray, doneItem]
});
};

How to display the products in modal body

I struck in the code that trying to display the products in modal body but not displaying. when i click on image it showing in console but not getting an idea how to display products in modal body. For to display in modal i used react-bootstrap. modal pop up is displaying when i click on image and it displaying header and footer. But in modal body i want to display the product details which i clicked. can any one help ..
import React, { Component } from "react";
import { Grid, Row, Col, Image, Button, Modal } from "react-bootstrap";
import AddToCartView from "./AddToCartView";
// import ProductView from './ProductView';
class ProductList extends Component {
constructor(props){
super(props);
this.state = {
show : false
}
}
handleShow = (item) => {
this.getProductDetails(item);
this.setState({
show : true
})
}
handleClose = () => {
this.setState({
show : false
})
}
getProductDetails = (prod) => {
// console.log(id,'clicked');
console.log(prod);
console.log(prod.title);
console.log(prod.id);
console.log(prod.price);
// let click = document.getElementsByTagName(Image.id);
// console.log(click);
// const { viewProducts } = this.props
// console.log(viewProducts);
// viewProducts.map((prod,id) => {
// console.log(prod.ptype);
// })
}
// console.log(viewProducts,'viewProducts');
render(){
const { viewProducts } = this.props;
return (
<div className="list-container">
<div className="mobile-list">
<h3> Showing { viewProducts.length } mobiles </h3>
</div>
<Grid>
<Row>
{viewProducts.map((item, key) => (
<Col xs={8} md={4} lg={4} key={item.id}>
<figure>
<Image onClick={() => this.handleShow(item) } src={item.image}
thumbnail />
<figcaption>{item.title}</figcaption>
<figcaption>
<label>Rs. </label>
{item.price}
</figcaption>
</figure>
<Button bsStyle="primary" onClick={this.props.onChange}>
<i className="fa fa-shopping-cart" />
Add
</Button>
<hr />
</Col>
))}
</Row>
</Grid>
<Modal show={this.state.show} onHide={() => this.handleClose()}>
<Modal.Header closeButton>
<Modal.Title>Product Details</Modal.Title>
</Modal.Header>
<Modal.Body>
{/* <ProductView displayProductView= { (item) =>
this.props.displayProductDetails(item) }/> */}
</Modal.Body>
<Modal.Footer>
<Button onClick={() => this.handleClose()}>Close</Button>
</Modal.Footer>
</Modal>
</div>
);
};
}
export default ProductList;
You are aware the ProductView component is commented out within the Modal Body right?
I'm not seeing where you pass the item to ProductView. Most likely your ProductView is getting nothing to display. Maybe you could change render of ProductView to just render a 'Hello' to see if that is the case.

Resources