Im new to javascript and trying to figure this out. I am trying to have the div structure in renderNewCard() appear on the page everytime you click the button. The button seems to work when i call a function with just an alert message, but it does nothing when i call this method and try to output the div structure. I attached a picture of what the div structure looks like and what should be added when clicking the button. In the render, don't worry about the lander and authentication methods for those work fine. Im having issues with the button producing the output i want from calling the function with the div structure. I might be missing something, but not entirely sure. Any help/advice is appreciated.
.Home .newObjects {
height: 130px;
padding-top: 81px;
}
.Home .newObjects button {
border-width: 2px;
border-color: rgb(98, 98, 98);
border-style: solid;
border-radius: 6px;
background: rgb(255, 255, 255);
box-shadow: 0px 0px 9px 0px rgba(0, 0, 0, 0.18);
width: 72px;
height: 100%;
margin-left: 72%;
font-weight: bold;
}
.Home .newObjects button:focus {
outline: none;
}
.card {
min-height: 310px;
}
.scroll-box {
overflow-y: scroll;
height: 310px;
padding: 1rem;
}
.card-border{
border-style: solid;
border-width: 2px;
margin-top: 50px;
box-shadow: 0px 0px 9px 0px rgba(0, 0, 0, 0.18);
}
import React, {Component} from "react";
import "./Home.css";
import {ControlLabel, FormControl, FormGroup} from "react-bootstrap";
export default class Home extends Component {
renderNewObjectsButton() {
return (
<div className="newObjects">
<button onClick={()=>this.renderNewCard()}>New</button>
</div>
)
}
render() {
return (
<div className="Home">
{this.props.isAuthenticated ? [this.renderNewObjectsButton()]
: this.renderLander() }
</div>
);
}
renderNewCard(){
return(
<div className="row" id="container">
<div className="card-border" >
<div className="card">
<div className="card-body">
Customer
</div>
<div className="card-body">
Vehicle
</div>
<div className="card-body">
Transaction
</div>
</div>
</div>
</div>
);
}
}
enter image description here
<button onClick={() => { this.setState({ show: true })}}>{this.state.show &&this.renderNewCard()}</button>
Go through this https://medium.com/#johnwolfe820/rendering-components-in-onclick-events-in-react-bc0d7b54e1cd link. It is just setting the value to rendered on the basis of conditions.
Hope it will serve your purpose.
call your home object inside button onclick
you have somthing like
export var home = new Home()
so use this like
<button onClick={()=>home.renderNewCard()}>New</button>
Each react component has one render method and will only render what is returned by that method. And the way to influence the render method is by changing the props or the state of the component.
What you need is a variable stored in the state of the component like:
import React, {Component} from "react";
import "./Home.css";
import {ControlLabel, FormControl, FormGroup} from "react-bootstrap";
export default class NewObjectsButton extends Component {
render() {
return (
<div className="newObjects">
<button onClick={this.props.renderNewCard}>New</button>
</div>
)
}
}
export default class NewCard extends Component {
render() {
return(
<div className="row" id="container">
<div className="card-border" >
<div className="card">
<div className="card-body">
Customer
</div>
<div className="card-body">
Vehicle
</div>
<div className="card-body">
Transaction
</div>
</div>
</div>
</div>
);
}
}
export default class Home extends Component {
state = {
shouldRenderNewCard: false,
};
renderNewCard() {
this.setState({ shouldRenderNewCard: true });
};
render() {
return (
<div className="Home">
{this.props.isAuthenticated ? <NewObjectsButton renderNewCard={this.renderNewCard} />
: this.renderLander() }
{this.state.shouldRenderNewCard ? <NewCard /> : null}
</div>
);
}
}
Related
I tried to create a component 'Card' and use it like a container.
the code work well without 'card'.
when I tried to add it the 'Card.css' and expense-item in ExpenseItem.css doesn't work
this is 'ExpenseItem.js':
import Card from './Card';
import ExpenseDate from './ExpenseDate';
import './ExpenseItem.css';
function ExpenseItem(props) {
return (
<Card className='expense-item' >
<ExpenseDate date={props.date} />
<div className='expense-item__description'>
<h2 >{props.title}</h2>
<div className='expense-item__price'>{props.amount} Da </div>
</div>
</Card>
);
}
export default ExpenseItem;
this is 'Card.js':
import './Card.css';
function Card(props){
const classes ='card'+props.className;
return <div className={classes}> {props.children} </div>;
}
export default Card;
and this is 'Card.css':
.card {
border-radius: 12px;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}
and finally this is 'ExpenseItem.css':
.expense-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem;
margin: 1rem 0;
background-color: #ff0000;
}
You need a space between card and the class name in the classes variable. Because there is no space, the className attribute in the card component is just cardexpense-item.
This is how it should look:
const classes = 'card '+props.className;
By the way, you can also use ES6 template literals feature (it's up to you but I prefer them more):
const classes = `card ${props.className}`;
I would like to create one component that included the dot between 2 elements. the code I have is like following, However, I tried to use span element then create css so I can display . between 2 span. but react does not generate the dot between 2 span. I also tried to use div and then dot did display but format of 2 element does not align at center
//html
import "./styles.css";
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
{/** use div format is not correct */}
<div>May 1st 5:31PM</div>
<div className="panel-dot"></div>
<div>Google</div>
{/** dot is not generated
<span>May 1st 5:31PM</span>
<span className="panel-dot"></span>
<span>Google</span>
*/}
</div>
</div>
</div>
);
}
//css
.panel {
width: 600px;
height: 500px;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
left: 0.5%;
right: 33.44%;
}
.panel-title {
padding: 8px;
color: #ffffff;
background-color: #3aac6f;
}
.panel-dot {
width: 4px;
height: 4px;
background: #3aac6f;
align-self: center;
}
codepen:
You can try this :
App.js
import React from 'react';
import './style.css';
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
<span>May 1st 5:31PM</span>
<span>Google</span>
</div>
</div>
</div>
);
}
style.css
.panel-title span:first-of-type::after {
content: '.';
}
Demo : Stackblitz
OR
App.js
import React from 'react';
import './style.css';
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
<span>May 1st 5:31PM</span>
<span>{"."}</span>
<span>Google</span>
</div>
</div>
</div>
);
}
I use the npm package use-dark-mode as the name implies, it makes it possible to change the theme to light or dark, The problem is that I want to change the background-color of some blocks when changing the theme to dark, and vice versa, return the old color when I switch to light mode, for example, my block background is orange, I switch to dark mode, it turns red and when I switch to light mode, it returns old orange
App.js
import React from 'react';
import './App.css'
import Content from "./components/Content/Content";
import Dark_Mode from "./components/Dark Mode/Dark_Mode";
const App = () => {
return(
<div>
<Dark_Mode />
<Content />
</div>
);
};
export default App;
Content.jsx
import React from 'react';
import './style.css'
const Content = () => {
return (
<>
<div className={"content_container"}>
<h3>Hello from React.JS</h3>
</div>
</>
);
};
export default Content;
Dark_Mode.jsx
import React from 'react';
import useDarkMode from 'use-dark-mode';
const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<div>
<button type="button" onClick={darkMode.disable}>
☀
</button>
<button type="button" onClick={darkMode.enable}>
☾
</button>
</div>
);
};
export default DarkModeToggle;
style.css
#import '../../App.css';
.content_container {
margin: auto;
width: 500px;
max-width: 100%;
background: orange;
}
.content_container h3 {
text-align: center;
}
App.css
body.light-mode {
background-color: #fff;
color: #333;
transition: background-color 0.3s ease;
}
body.dark-mode {
background-color: #1a1919;
color: #999;
}
:root {
--color-orange: orange;
}
As you can see, I have App.css when the theme changes, it changes the background of the <body>, I still have Content.jsx when switching theme I want to change the background of the block with the className content_container which is connected to style.css, In addition, you may have noticed that I tried to use global styles, but I failed. Finally, I would like to show a screenshot on the site for a clear understanding of everything.
You could give the root element a class on theme change and use css variables in root, but be class specific:
Dark_mode.jsx:
function setTheme(themeName) {
document.documentElement.classList.remove('light-theme', 'dark-theme');
document.documentElement.classList.add(themeName);
}
const DarkModeToggle = () => {
const activateDarkTheme = () => setTheme('dark-theme');
const activateLightTheme = () => setTheme('light-theme');
return (
<div>
<button type="button" onClick={activateDarkTheme}>
☀
</button>
<button type="button" onClick={activateLightTheme}>
☾
</button>
</div>
);
};
Styles:
:root, // this is used for the default theme, will be overwritten by other styles with classes because of specifity
:root.dark-theme {
--color-bg: #000;
}
:root.light-theme {
--color-bg: #fff;
}
I found a more convenient solution! although it is my fault, I was a little inattentive and did not study the documentation of this package that I use in my project, here is a simple solution
Content.jsx
import './Content.css'
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
}
Content.css
.Dark_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: orange;
}
.Light_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: rgb(24, 106, 199);
}
I'm using react-styled-components to style some custom components in my React/AntDesign application but the styles are not applied to my application.
When I tried reproducing the component in a clean codesandbox.io project the styles were applied successfully.
While some styled-components in my project do work this doesn't, what could be interfering with styled-components?
Here's the code:
import React from "react";
import "antd/dist/antd.css";
import styled from "styled-components";
import { FaMale, FaFemale, FaChild, FaUserFriends } from "react-icons/fa";
import { MdChildFriendly } from "react-icons/md";
import { Row, Col, Modal, Button } from 'antd';
class App extends React.Component {
state = { visible: false };
showModal = () => {
this.setState({
visible: true,
});
};
handleCancel = e => {
console.log(e);
this.setState({
visible: false,
});
};
ProductBtn = styled.div`
box-shadow: 0 0 15px rgba(0,0,0,0.1);
border: 1px solid #eee;
padding: 16px;
text-align: center;
border-radius: 5px;
cursor: pointer;
background-color: #fff
p {
margin-bottom: 0;
margin-top: 5px;
font-weight: bold;
}
`;
render() {
return (
<div>
<Button type="primary" onClick={this.showModal}>New Transaction</Button>
<Modal
title="New transaction"
visible={this.state.visible}
nOk={this.handleCancel}
onCancel={this.handleCancel}
>
<Row gutter={[16, 16]}>
<Col span={8}>
<this.ProductBtn onClick={this.handleProductClicked}>
<FaUserFriends style={{ fontSize: '24px' }} />
<p>Add couple</p>
<small>$70.00</small>
</this.ProductBtn>
</Col>
...
</Row>
</Modal>
</div>
)
}
}
export default App;
This is how it should look and how it looks in CodeSandbox:
This is how it looks in my application, without the widget/button-like styling on the ProductBtn styled component:
I am a little bit confused, when I am passing a method defined in the parent component, that is changing the view of the parent component down to a child component (e.g to a button in the child component), and when I click the button on the child component, does the method from parent component gets executed in the parent class (and therefore, on the parent view) or on the child class (and then on the child view)?
lets say I want to display an alert message on the parent class when the button in the child class gets clicked, the alert message will get displayed on the parent I guess.
But is it also possible to pass a method defined in the parent down to the child and then change some views in the child component?
EDIT:
I give an example for my problem:
I have a component to render conditionally in Parent Class:
I pass the method onShowAlert to show an alert on parent component
if (this.state.alleAnzeigen.length > 0) {
anzeigenListe = (
<AnzeigenComponent
anzeigenArray={this.state.alleAnzeigen}
onClickAlert={this.onShowAlert}
onButtonFinish={this.finishDocumentHandler}
/>
)
In my AnzeigenComponent, I pass the method down to Anzeige Component,
first, I had onClickalert={() => props.onClickAlert} without the (), however, in my Parent the method was not executed then.
const anzeigenArray = (props) => {
return props.anzeigenArray.map((anzeige,index) => (
<li className="mainList" key={anzeige.id} style={{padding: "10px"}} >
<Anzeige
anzeige={anzeige}
key={anzeige.id}
index={index}
onClickalert={() => props.onClickAlert()}
onButtonfinish={() => props.onButtonFinish(anzeige,index)}
/>
</li>
))
}
export default anzeigenArray;
my SubComponent "Anzeige" however, is a bigger Stateful Component Class:
when I click the button inside the singleAnzeige render function, I execute props.onClickalert()-> the method that I have passed down as props. However, the method doesn't do anything, unless I already execute that method with parentheses "()" in the component that I mentioned one above, I am just wondering, why is that so? Is there a limit of subcomponents where I can pass the method down only 2 levels or so, so that it still works?
import React, {Component} from 'react';
import DubletteComponent from '../components/DubletteComponent';
import { Button, Alert } from 'reactstrap';
import { Container, Row, Col } from 'reactstrap';
class Anzeige extends Component {
constructor(props) {
super(props);
}
singleAnzeige = (props) => {
// let newText = this.htmlspecialchars_decode("71065 Sindelfingen71032 Böblingen75365 Calw72202 Nagold71083 Herrenberg71229 Leonberg");
// console.log(newText);
return (
<Row>
<Col xs={12} md={2}><b>ID:</b> {props.anzeige.id}</Col>
<Col xs={12} md={3}><b>Titel:</b> {props.anzeige.title}</Col>
<Col xs={12} md={3}><b>Institution:</b> {props.anzeige.institution}</Col>
<Col xs={12} md={2}><b>Ort:</b> {props.anzeige.ort}</Col>
<Col xs={12} md={2} className="linkButton">
Link
<button className="finishButton" onClick = {
() => {
if (window.confirm('Are you sure you wish to finish this document?')) {
props.onButtonfinish(props.anzeige,props.index);
props.onClickalert();
}
}
}>fertig</button>
</Col>
<style jsx>
{`
p, a {
}
.linkButton {
flexDirection: 'row',
justifyContent: 'flex-end',
}
.anzeigeLink {
}
.finishButton:hover {
background-color: green;
}
.finishButton {
float: right;
border: 1px solid blue;
border-radius: 10px;
background-color: dark-green;
}
#media(max-width: 576px){
.finishButton {
float: none;
margin-right: 30px;
margin-left: 20px;
}
}
`}
</style>
</Row>
);
}
render() {
return (
<div className="anzeigeCard">
{this.singleAnzeige(this.props)}
<DubletteComponent className="dublette" anzeigeID={this.props.anzeige.id} onSendDoubletten = {this.props.onClickAlert}/>
<style jsx>
{`
.anzeigeCard {
border-radius: 10px;
padding: 10px;
margin: 5px 0px 5px 0px;
border: 1px solid light-green;
width: 100%;
box-shadow: 2px 2px 2px 2px;
}
`}
</style>
</div>
)
}
}
export default Anzeige
Is there a limit of subcomponents where I can pass the method down
only 2 levels or so, so that it still works?
There is no limit on how many levels you want to to pass your method as a prop,
if (this.state.alleAnzeigen.length > 0) {
anzeigenListe = (
<AnzeigenComponent
anzeigenArray={this.state.alleAnzeigen}
onClickAlert={this.onShowAlert}
onButtonFinish={this.finishDocumentHandler}
/>
)
}
const anzeigenArray = (props) => {
return props.anzeigenArray.map((anzeige,index) => (
<li className="mainList" key={anzeige.id} style={{padding: "10px"}} >
<Anzeige
anzeige={anzeige}
key={anzeige.id}
index={index}
onClickalert={props.onClickAlert}
onButtonfinish={props.onButtonFinish}
/>
</li>
))
}
export default anzeigenArray;
import React, {Component} from 'react';
import DubletteComponent from '../components/DubletteComponent';
import { Button, Alert } from 'reactstrap';
import { Container, Row, Col } from 'reactstrap';
class Anzeige extends Component {
constructor(props) {
super(props);
}
singleAnzeige = (props) => {
// let newText = this.htmlspecialchars_decode("71065 Sindelfingen71032 Böblingen75365 Calw72202 Nagold71083 Herrenberg71229 Leonberg");
// console.log(newText);
return (
<Row>
<Col xs={12} md={2}><b>ID:</b> {props.anzeige.id}</Col>
<Col xs={12} md={3}><b>Titel:</b> {props.anzeige.title}</Col>
<Col xs={12} md={3}><b>Institution:</b> {props.anzeige.institution}</Col>
<Col xs={12} md={2}><b>Ort:</b> {props.anzeige.ort}</Col>
<Col xs={12} md={2} className="linkButton">
Link
// I couldn't verify this code, but I guess your "if" implementation may cause some error, so in order to help you investigate easier, I remove the "if" here
<button className="finishButton" onClick = {
() => props.onButtonfinish(props.anzeige,props.index);
}>fertig</button>
</Col>
<style jsx>
{`
p, a {
}
.linkButton {
flexDirection: 'row',
justifyContent: 'flex-end',
}
.anzeigeLink {
}
.finishButton:hover {
background-color: green;
}
.finishButton {
float: right;
border: 1px solid blue;
border-radius: 10px;
background-color: dark-green;
}
#media(max-width: 576px){
.finishButton {
float: none;
margin-right: 30px;
margin-left: 20px;
}
}
`}
</style>
</Row>
);
}
render() {
return (
<div className="anzeigeCard">
{this.singleAnzeige(this.props)}
<DubletteComponent className="dublette" anzeigeID={this.props.anzeige.id} onSendDoubletten = {this.props.onClickAlert}/>
<style jsx>
{`
.anzeigeCard {
border-radius: 10px;
padding: 10px;
margin: 5px 0px 5px 0px;
border: 1px solid light-green;
width: 100%;
box-shadow: 2px 2px 2px 2px;
}
`}
</style>
</div>
)
}
}
export default Anzeige