I'm discovering ReactJS, trying some stuff but i face a problem: my body height is fixed to 76px and i can't do anything to that, i tried a lot a stuff, nothing worked.
Here's the code i'm using
import * as React from 'react';
// This fonction make the color change on the button on the first click
function ChangeStyle() {
var elem = document.getElementById('Button1');
if (elem == null) {
return;
}
elem.style.background = '#ff4848';
}
// Main Class
export class Button extends React.Component {
render() {
// Style sheet of the Button
var buttonStyle = {
fontSize: 50,
background: '#ffb516',
color : '#FFFFFF',
width: 500,
border: 'none',
textAlign: 'center',
display: 'block',
margin: 'auto'
};
// Set the Background color
document.body.style.backgroundColor = '#25353f';
document.body.style.position = 'relative';
document.body.style.height = '100%';
// Try to make the button in center
/*
var centerDiv = {
position: 'absolute' as 'absolute',
top: '50%',
left: '30%',
margin: 'auto'
}
*/
// Test on linearGradient
/*
function degraded() {
<svg width='15' height='71' fill='url(#Gradient-1)'>
<defs>
<linearGradient id='Gradient-1' x2='0%' y2='100%'>
<stop offset='0%' stop-color='#25353f'/>
<stop offset='100%' stop-color='#5b6c72'/>
</linearGradient>
</defs>
</svg>
}
*/
// Create the button
return (
<div id="fullHeight" style={{height: '100%'}}>
<div /*style={centerDiv}*/>
<button
id="Button1"
style={buttonStyle}
onClick={() => ChangeStyle()}
>
Pushtalents
</button>
</div>
</div>
);
}
}
export default Button;
Any idea why? And how to fix this problem?
Maybe it helps if you remove position: relative; from body. It doesn't do anything anyways. Other than that you can try to set the body height to 100vh.
Related
I'm trying to use setState to access my css const mystyle object to change the background color on the squares from blue to red but everytime the button is pressed. It seems everytime I press the button the Setstate does not render on screen any advice or help? Would be greatly appreciated
class MyHeader extends React.Component {
constructor(props){
super(props)
this.state = {backgroundColor: 'blue'};
}
render() {
const mystyle = {
borderRadius: "10px",
background: this.state.backgroundColor,
padding: "10px",
width: "100px",
height: "100px",
marginTop: "10px",
lineHeight: "80px",
color: "dimGrey",
fontWeight: "bold",
fontSize: "3em",
textAlign: "center"
};
function State() {
this.setState({backgroundColor: 'red'})
}
return (
<div>
<h1 style={mystyle}></h1>
<h1>{this.state.backgroundColor}</h1>
</div>
);
}
}
function Test() {
function Test2() {
setchange(change + Math.floor(Math.random() * 10));
if(change > 20) {
setchange(change + Math.floor(Math.random() - 10))
}
}
const [change, setchange] = React.useState(1)
return (
<div>
<h1>click the button to randomize colors</h1>
<button onClick={this.State}>Randomize colors!</button>
<div className='.flex-item'></div>
<h1>{change}</h1>
<div className="flex-item"></div>
<MyHeader />
<MyHeader />
</div>
);
}
ReactDOM.render(<Test />, document.getElementById("root"));
my codepen link to the code
The main issue is trying to do something where the child component, MyHeader, has the function to change state, but trying to invoke it from the parent component, Test. It's just simpler to pass the color as a prop from Test to MyHeader.
Alternatively, you can do the useContext thing, but I think this is easier. I've stripped out all superfluous code that wasn't getting used. You can of course, add them back as you need to.
const MyHeader = ({backgroundColor}) => {
const mystyle = {
borderRadius: "10px",
background: backgroundColor,
padding: "10px",
width: "100px",
height: "100px",
marginTop: "10px",
lineHeight: "80px",
color: "dimGrey",
fontWeight: "bold",
fontSize: "3em",
textAlign: "center"
};
return (
<div>
<h1 style={mystyle}></h1>
<h1>{backgroundColor}</h1>
</div>
);
}
}
const Test = (props) => {
const [backgroundColor, setBackgroundColor] = useState("blue");
const onButtonClick = () => {
setBackgroundColor("red");
}
return (
<div>
<h1>click the button to randomize colors</h1>
<button onClick={onButtonClick}>Randomize colors!</button>
<div className='.flex-item'></div>
<h1>{change}</h1>
<div className="flex-item"></div>
<MyHeader backgroundColor={backgroundColor} />
</div>
);
};
I have integrated dialogflow in a react page and it is working now the issue is whenever I am writing a phrase in the bot is responding but the chat window is not getting auto scrolled to bottom. I want the bot window to be automatically scrolled to bottom every time.
class App extends Component {
render() {
const { feed, sendMessage } = this.props;// structure of the bot
return (
<div // which is the main div
style={{
backgroundColor: "green",
height: "70%",
width: "23%",
position: "fixed",
bottom: 0,
right: 5
}}
>
<div // inner div
style={{
height: "67%",
width: "22%",
position: "fixed",
bottom: "30px",
maxHeight: "65%",
right: "5px",
overflowY: "scroll",
overflowX: "hidden"
}}
>
<h1>CHATBOT!</h1>
{feed.map(entry => ( // the div where the user is typing the response
<div>{entry.text}</div> // inner- inner div
))}
</div>
<div
style={{
position: "fixed",
right: "23%",
bottom: "28px",
marginLeft: "-1300px"
}}
>
<input
style={{
position: "fixed",
width: "22%",
height: "3%"
}}
type="text" // the value by which the user is connected the bot
onKeyDown={e => // this is the box where the response is coming from the bot
e.keyCode === 13 ? sendMessage(e.target.value) : null
}// 13 is the ascii of ENTER
/>
</div>
</div>
);
}
}
const mapStateToProps = state => ({
feed: state
});
chat.js // intergration with dialogflow
const accessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //you have to enter your key
const client = new ApiAiClient({ accessToken });
const ON_MESSAGE = "ON_MESSAGE";
export const sendMessage = (text, sender = "user") => ({ // bot text box
type: ON_MESSAGE,
payload: { text, sender }
});
const messageMiddleware = () => next => action => {
next(action);
if (action.type === ON_MESSAGE) {
const { text } = action.payload;
client.textRequest(text).then(onSuccess);
function onSuccess(response) {// response from dialgflow
const {
result: { fulfillment }
} = response;
next(sendMessage(fulfillment.speech, "bot"));
}
}
};
const initState = [{ text: "" }];
const messageReducer = (state = initState, action) => {
switch (action.type) {
case ON_MESSAGE:
return [...state, action.payload];
default:
return state;
}
};
app.js
class App extends Component {
render() {
const { feed, sendMessage } = this.props;// structure of the bot
return (
<div // which is the main div
style={{
backgroundColor: "green",
height: "70%",
width: "23%",
position: "fixed",
bottom: 0,
right: 5
}}
>
<div // inner div
style={{
height: "67%",
width: "22%",
position: "fixed",
bottom: "30px",
maxHeight: "65%",
right: "5px",
overflowY: "scroll",
overflowX: "hidden"
}}
>
<h1>CHATBOT!</h1>
{feed.map(entry => ( // the div where the user is typing the response
<div>{entry.text}</div> // inner- inner div
))}
</div>
<div
style={{
position: "fixed",
right: "23%",
bottom: "28px",
marginLeft: "-1300px"
}}
>
<input
style={{
position: "fixed",
width: "22%",
height: "3%"
}}
type="text" // the value by which the user is connected the bot
onKeyDown={e => // this is the box where the response is coming from the bot
e.keyCode === 13 ? sendMessage(e.target.value) : null
}// 13 is the ascii of ENTER
/>
</div>
</div>
);
}
}
const mapStateToProps = state => ({
feed: state
});
I want the bot window to be automatically scrolled whenever I type anything in the window.
In the App component, you can create a span or div and place it right below the chat-feed.
Then give that element a ref, which we will use to scroll to upon receiving any new message.
You can use React.createRef() to make that ref. Refs essentially give us access to methods you traditionally see in vanilla JavaScript.
It also looks like you're receiving updated messages via props from Redux. So we can use componentDidUpdate() to run some logic that will scroll to that ref element.
class App extends Component {
endOfFeed = React.createRef()
scrollToEnd = () => {
if(this.endOfFeed.current){
this.endOfFeed.current.scrollIntoView()
}
}
componentDidUpdate(prevProps){
if(prevProps.feed.length !== this.props.feed.length){
this.scrollToEnd()
}
}
render() {
const { feed, sendMessage } = this.props;// structure of the bot
return (
<div // which is the main div
style={{
backgroundColor: "green",
height: "70%",
width: "23%",
position: "fixed",
bottom: 0,
right: 5
}}
>
<div // inner div
style={{
height: "67%",
width: "22%",
position: "fixed",
bottom: "30px",
maxHeight: "65%",
right: "5px",
overflowY: "scroll",
overflowX: "hidden"
}}
>
<h1>CHATBOT!</h1>
{feed.map(entry => ( // the div where the user is typing the response
<div>{entry.text}</div> // inner- inner div
))}
<span ref={this.endOfFeed}></span>
</div>
<div
style={{
position: "fixed",
right: "23%",
bottom: "28px",
marginLeft: "-1300px"
}}
>
<input
style={{
position: "fixed",
width: "22%",
height: "3%"
}}
type="text" // the value by which the user is connected the bot
onKeyDown={e => // this is the box where the response is coming from the bot
e.keyCode === 13 ? sendMessage(e.target.value) : null
}// 13 is the ascii of ENTER
/>
</div>
</div>
);
}
}
const mapStateToProps = state => ({
feed: state
});
You can use window.scrollY property and give offset accordingly.
Check this https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY
I have multiple icons stored in a component under switch statement. Based on a condition, I want to display that icon in render function of another component. If I manually add the svg and the path element, then the icon gets displayed correctly. But I would like to optimize my code such that when I call the function with correct parameters, it extracts the corresponding svg element along with its path element.
First Component(where icons reside):
export function getSymbolPlotly(symbol) { // eslint-disable-line
let elm;
const { color, shape } = symbol;
switch (shape) {
case 'x-dot':
elm = <path
className="point"
transform="translate(8,8)"
d="M0,3.39l3.39,3.39l3.39,-3.39l-3.39,-3.39l3.39,-3.39l-3.39,-3.39l-3.39,3.39l-3.39,-3.39l-3.39,3.39l3.39,3.39l-3.39,3.39l3.39,3.39ZM0,0.5L0.5,0L0,-0.5L-0.5,0Z"
style={{
opacity: 1,
strokeWidth: '0px',
fill: color,
fillOpacity: 1
}}></path>;
break;
case 'square':
elm = <path
className="point"
transform="translate(8,8)"
d="M6,6H-6V-6H6Z"
style={{
opacity: 1,
strokeWidth: '0px',
fill: color,
fillOpacity: 1
}}></path>;
break;
case 'hourglass':
elm = <path
className="point"
transform="translate(6,8)"
d="M6,6H-6L6,-6H-6Z"
style={{
opacity: 1,
strokeWidth: '0px',
fill: color,
fillOpacity: 1
}}></path>;
break;
default:
elm = <circle cx="6" cy="6" r="6" transform="translate(0,2)" fill={color}></circle>;
}````
Second component(render function where I need to display icons):
````switch (user.processState) {
case 'DENIED':
return <span><svg style={{ width: '15px', height: '15px' }}>
{getSymbolPlotly('hourglass')}
</svg></span>
case 'CANCELLED':
return <span><svg style={{ width: '15px', height: '15px' }}>
<path className="point"
transform="translate(8,8)"
d="M0,3.39l3.39,3.39l3.39,-3.39l-3.39,-3.39l3.39,-3.39l-3.39,-3.39l-3.39,3.39l-3.39,-3.39l-3.39,3.39l3.39,3.39l-3.39,3.39l3.39,3.39ZM0,0.5L0.5,0L0,-0.5L-0.5,0Z"
style={{
opacity: 1,
strokeWidth: '0px',
fill: '#e5004c',
fillOpacity: 1
}}></path>
</svg>{this.state.message}</span>;
}
In the above code, case CANCELLED displays the icon perfectly as I am manually adding the path element. But I would like to optimize the code as I would need to display the icons at multiple locations and adding path element at every position would make the code tedious. If I call the getSymbol function and pass the name of the icon as parameter, it doesn't display anything. Even when the parameter doesn't match any case, it won't even display the default circle element.
Is there a way to extract the svg and path element in cleaner way from another component ?
In your getSymbolPlotly function you destructure an object called symbol const { color, shape } = symbol;. When you call that function you pass a string called getSymbolPlotly('hourglass'), there is the first error.
I don't know if you pasted the entire code for the getSymbolPlotly function but you must also return the element. To extract in a more "clean" way you can to like this.
import React from "react";
export function getSymbolPlotly(symbol) {
// eslint-disable-line
const { color, shape } = symbol;
switch (shape) {
case "x-dot":
return (
<path
className="point"
transform="translate(8,8)"
d="M0,3.39l3.39,3.39l3.39,-3.39l-3.39,-3.39l3.39,-3.39l-3.39,-3.39l-3.39,3.39l-3.39,-3.39l-3.39,3.39l3.39,3.39l-3.39,3.39l3.39,3.39ZM0,0.5L0.5,0L0,-0.5L-0.5,0Z"
style={{
opacity: 1,
strokeWidth: "0px",
fill: color,
fillOpacity: 1
}}
/>
);
case "square":
return (
<path
className="point"
transform="translate(8,8)"
d="M6,6H-6V-6H6Z"
style={{
opacity: 1,
strokeWidth: "0px",
fill: color,
fillOpacity: 1
}}
/>
);
case "hourglass":
return (
<path
className="point"
transform="translate(6,8)"
d="M6,6H-6L6,-6H-6Z"
style={{
opacity: 1,
strokeWidth: "0px",
fill: color,
fillOpacity: 1
}}
/>
);
default:
return (
<circle cx="6" cy="6" r="6" transform="translate(0,2)" fill={color} />
);
}
}
And in some other component you can call it like this.
return (
<div className="App">
<div>
<svg style={{ width: "15px", height: "15px" }}>
{getSymbolPlotly({ shape: "hourglass", color: "red" })}
</svg>
</div>
<div>
<svg style={{ width: "15px", height: "15px" }}>
{getSymbolPlotly({ shape: "x-dot", color: "purple" })}
</svg>
</div>
</div>
);
I've created a Codesandbox with a working demo here.
I'm creating a React widget and using the react-jss HOC for styling. The widget is just a small part of a larger page, and I want to be able to signal it to open or close with a button on another part of the page outside of the React render. Originally I was doing it like this:
var modal = ReactDOM.render(<Modal />, document.getElementById('widget'))
// Inside an onClick function
modal.toggleModal()
That was before JSS, but now widget doesn't return the component, it returns the JSS HOC. I've tried passing <Widget /> a prop and updating that and then using widget.forceUpdate() but that did nothing. Not really sure what else to try at this point. I'm currently just toggling everything outside of React, but I want the component to be able to close itself as well.
import React, { Component } from 'react'
import injectSheet from 'react-jss'
const styles = {
show: {
display: 'block',
},
modal: {
display: 'none',
background: 'rgba(0, 0, 0, 0.3)',
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
width: '100%',
height: '100%',
},
form: {
maxWidth: '440px',
margin: '15px',
padding: '30px',
background: '#fff',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
input: {
width: '100%',
marginBottom: '15px'
},
button: {
width: '100%'
}
}
class Modal extends Component {
constructor(props) {
super(props)
this.state = {
show: false
}
this.toggleModal = this.toggleModal.bind(this)
}
toggleModal() {
this.setState({show: !this.state.show})
}
render() {
const { classes } = this.props
return (
<div className={`${classes.modal} ${this.state.show ? classes.show : ''}`}>
<form className={classes.form}>
<label htmlFor="aatitle-field">Title</label>
<input className={classes.input} type="text" id="aatitle-field" name="title" value="" />
<button className={`btn ${classes.button}`}>Save</button>
</form>
</div>
)
}
}
export default injectSheet(styles)(Modal)
First of all, please use the classnames library to generate classNames, it's so more elegant.
Secondly, classes are applied in order they are parsed by the brower. So what you're doing is tricky. How can we know if the modal class is parsed before show? (This is a requirement in your current code). You can simply move the modal declaration before the show declaration in styles and surely this will work, but this is a fragile solution. Better is to use a show and hide class and apply them according the state. This removes the dependency of which style class is loaded first. So remove display:none from modal and introduce hide:
Something like:
import React, { Component } from 'react'
import injectSheet from 'react-jss'
const styles = {
show: {
display: 'block',
},
hide: {
display: 'none',
},
modal: {
background: 'rgba(0, 0, 0, 0.3)',
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
width: '100%',
height: '100%',
},
form: {
maxWidth: '440px',
margin: '15px',
padding: '30px',
background: '#fff',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
input: {
width: '100%',
marginBottom: '15px'
},
button: {
width: '100%'
}
}
class Modal extends Component {
constructor(props) {
super(props)
this.state = {
show: false
}
this.toggleModal = this.toggleModal.bind(this)
}
toggleModal() {
this.setState({show: !this.state.show})
}
render() {
const { classes } = this.props
return (
<div className={`${classes.modal} ${this.state.show ? classes.show : classes.hide}`}>
<form className={classes.form}>
<label htmlFor="aatitle-field">Title</label>
<input className={classes.input} type="text" id="aatitle-field" name="title" value="" />
<button className={`btn ${classes.button}`}>Save</button>
</form>
</div>
)
}
}
export default injectSheet(styles)(Modal)
```
I'm trying to replicate http://www.milkbardigital.com.au/ as a learning project in react.
Currently I'm struggling to get the PNG image over the top of the background image.
Here's my code,
import React from 'react';
import {Image} from 'react-bootstrap';
export default React.createClass ( {
render() {
var background = {backgroundSize : 'cover'};
var textStyle = {
position: 'absolute',
top: '50%',
left: '50%'
};
return (
<div style={{width: 'auto'}}>
<Image
style={background} responsive
src="http://www.milkbardigital.com.au/wp-content/uploads/2015/11/Milkbar-Home-Background.jpg">
</Image>
<h1 style={textStyle}>Agile Media Content</h1>
</div>
);
}
});
<Image src="http://www.milkbardigital.com.au/wp-content/uploads/2015/11/Milkbar-Digital-Media.png" responsive/>
This "Image src" I've tried to place inside the above code but it won't work.
Anyone able to work this out?
It's with React Bootstrap!
Thanks,
Edit - - -
I've worked out how to get it slightly on top, now trying to get it put in the right position.
This is the code, ignore the opacity part,
/**
* Created by Hewlbern on 21-Jan-17.
*/
import React from 'react';
import {Image} from 'react-bootstrap';
export default React.createClass ( {
render() {
var background = {backgroundSize : 'cover',
opacity: '0.5',
};
var textStyle = {
position: 'absolute',
top: '50%',
left: '50%'
};
var ontop = {
display: 'block',
margin: 'auto',
width: '50%',
};
return (
<div style={{width: 'auto'}}>
<Image
style={background} responsive
src="http://www.milkbardigital.com.au/wp-content/uploads/2015/11/Milkbar-Home-Background.jpg">
</Image>
<h1 style={textStyle}>Agile Media Content</h1>
<Image style={textStyle} responsive src="http://www.milkbardigital.com.au/wp-content/uploads/2015/11/Milkbar-Digital-Media.png" />
</div>
);
}
});