Im trying to change the style whenever ReactSlider is changed. I want to add for example brightness when slider is increased in React. I did it but I cannot seem to get the styles to be added to the image whenever the slider goes through the onchange event. Here is the code:
import React, { Component } from 'react';
import { BsFileEarmarkPlus } from 'react-icons/bs';
import ReactSlider from 'react-slider';
class Edit extends React.Component {
constructor(props) {
super(props);
this.state = {
file: null,
}
this.ImageUpload = this.ImageUpload.bind(this);
this.ChangeImage = this.ChangeImage.bind(this);
}
ImageUpload(event) {
console.log(event.target.files[0]);
this.setState({
file: URL.createObjectURL(event.target.files[0]),
});
}
ChangeImage(props) {
console.log(props);
var amount = this.props + '%';
var imgStyles = {
filter: 'brightness(' + amount + ')'
}
}
render() {
return (
<div className="editor">
<h1>Editor</h1>
<label htmlFor="fileChoose"><BsFileEarmarkPlus />Upload
<input type="file" id="fileChoose" onChange={this.ImageUpload} />
</label>
<hr />
<div className="img-surround">
<img
src={this.state.file}
id="img"
style={imgStyles} />
</div>
<div className="edit-nav">
<ReactSlider
className="horizontal-slider"
defaultValue={0}
max={100}
min={-100}
thumbClassName="example-thumb"
trackClassName="example-track"
renderThumb={(props, state) => <div {...props}>{state.valueNow}</div>}
onChange={this.ChangeImage}
/>
</div>
</div>
);
}
}
export default Edit;
The only problem is imgStyles is undefined when called from outside the render(). Everything else works.
Because you defined 'imgStyles' variable in 'ChangeImage' function.
You should define this variable out of class or define it as state variable.
var imgStyles = {};
class Edit extends React.Component {
...
ChangeImage(props) {
console.log(props);
var amount = this.props + '%';
imgStyles = {
filter: 'brightness(' + amount + ')'
}
}
...
Or
...
constructor(props) {
super(props);
this.state = {
file: null,
imgStyles: {}
}
}
...
ChangeImage(props) {
console.log(props);
var amount = this.props + '%';
this.setState({ imgStyles: { filter: 'brightness(' + amount + ')' } });
}
...
<img
src={this.state.file}
id="img"
style={this.state.imgStyles} />
...
I need to change the name of every avatar every X seconds, I have follow this solution and it works fine but, right now its changing all the names to the same name from RandomAcidName array.
I imagine that I need to iterate through this list also, so each name is passing just once to every avatar.
Here is my code
nameJuggler is passing the name to each avatar
import React, { Component } from "react";
import "./Avatar.scss";
import AcidData from "../Acidsdata/Acids-data.json";
import RandomAcidName from "../../../src/randomAcidName.json";
const getDate = new Date();
const getDay = getDate.getDate();
const getMonth = getDate.getMonth() + 1;
const fullTodayDate = getDay + "/" + getMonth;
const AvatarDisplay = props => {
return (
<div key={props.id} className="container__position-relative">
<img src={props.photo} alt={props.name} className="avatar__img" />
<div className="container__position-absolute avatar__name">
<span>{props.name}</span>
</div>
{props.cumple}
</div>
);
};
class AcidPoblation extends Component {
constructor(props) {
super(props);
this.state = {
sudoNameId: 0,
acidos: AcidData,
randomName: RandomAcidName
};
}
componentDidMount() {
this.changeName = setInterval(() => {
let currentSudoNameId = this.state.sudoNameId;
this.setState({
sudoNameId: currentSudoNameId + 1
});
}, 1500);
}
componentDidUnmount() {
clearInterval(this.changeName);
}
render() {
let nameJuggler =
RandomAcidName[this.state.sudoNameId % RandomAcidName.length];
return (
<main className="container__grid">
{this.state.acidos.map(item => (
<AvatarDisplay
photo={item.acidphoto}
name={nameJuggler}
birth={item.birthdate}
id={item.acidid}
cumple={
item.birthdate === fullTodayDate ? (
<img
src="https://via.placeholder.com/40x40"
alt="feliz cumpleaƱos"
className="container__position-absolute avatar__birth-date"
/>
) : null
}
/>
))}
</main>
);
}
}
export default AcidPoblation;
Here is the Json with the names
[
"Anderson",
"Ashwoon",
"Aikin",
"Bateman",
"Bongard",
"Bowers",
"Boyd",
"Cannon",
"Cast",
"Deitz",
"Dewalt",
"Ebner",
"Frick",
"Hancock",
"Haworth",
"Hesch",
"Hoffman",
"Kassing",
"Knutson",
"Lawless",
"Lawicki",
"Mccord",
"McCormack",
"Miller",
"Myers",
"Nugent",
"Ortiz",
"Orwig",
"Ory",
"Paiser",
"Pak",
"Pettigrew",
"Quinn",
"Quizoz",
"Ramachandran",
"Resnick",
"Sagar",
"Schickowski",
"Schiebel",
"Sellon",
"Severson",
"Shaffer",
"Solberg",
"Soloman",
"Sonderling",
"Soukup",
"Soulis",
"Stahl",
"Sweeney",
"Tandy",
"Trebil",
"Trusela",
"Trussel",
"Turco",
"Uddin",
"Uflan",
"Ulrich",
"Upson",
"Vader",
"Vail",
"Valente",
"Van Zandt",
"Vanderpoel",
"Ventotla",
"Vogal",
"Wagle",
"Wagner",
"Wakefield",
"Weinstein",
"Weiss",
"Woo",
"Yang",
"Yates",
"Yocum",
"Zeaser",
"Zeller",
"Ziegler",
"Bauer",
"Baxster",
"Casal",
"Cataldi",
"Caswell",
"Celedon",
"Chambers",
"Chapman",
"Christensen",
"Darnell",
"Davidson",
"Davis",
"DeLorenzo",
"Dinkins",
"Doran",
"Dugelman",
"Dugan",
"Duffman",
"Eastman",
"Ferro",
"Ferry",
"Fletcher",
"Fietzer",
"Hylan",
"Hydinger",
"Illingsworth",
"Ingram",
"Irwin",
"Jagtap",
"Jenson",
"Johnson",
"Johnsen",
"Jones",
"Jurgenson",
"Kalleg",
"Kaskel",
"Keller",
"Leisinger",
"LePage",
"Lewis",
"Linde",
"Lulloff",
"Maki",
"Martin",
"McGinnis",
"Mills",
"Moody",
"Moore",
"Napier",
"Nelson",
"Norquist",
"Nuttle",
"Olson",
"Ostrander",
"Reamer",
"Reardon",
"Reyes",
"Rice",
"Ripka",
"Roberts",
"Rogers",
"Root",
"Sandstrom",
"Sawyer",
"Schlicht",
"Schmitt",
"Schwager",
"Schutz",
"Schuster",
"Tapia",
"Thompson",
"Tiernan",
"Tisler"
]
I need that every name is assing just once.
In this link is a replica of my project...
The problem is
let nameJuggler = [this.state.sudoNameId % RandomAcidName.length];
this.state.sudoNameId won't be unique because it's just a number set in the parent component and will be provided to all of the AvatarDisplays not dynamically changing.
An easy fix would just make the .map also have an index so you can add the index to the this.state.sudoNameId which will make each number unique.
See code below
return (
<main className="container__grid">
{this.state.acidos.map((item, index) => {
let nameJuggler =
RandomAcidName[(this.state.sudoNameId + index) % RandomAcidName.length];
return (
<AvatarDisplay
photo={item.acidphoto}
name={nameJuggler}
birth={item.birthdate}
id={item.acidid}
cumple={
item.birthdate === fullTodayDate ? (
<img
src="https://via.placeholder.com/40x40"
alt="feliz cumpleaƱos"
className="container__position-absolute avatar__birth-date"
/>
) : null
}
/>
)
})}
</main>
I'm trying to make if else statement to allow user to type only integer in TextArea but i have no idea how.
This is my code:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
currencyValue: '',
currencyCode: 'USD',
result: ''
}
}
handleChangeCurrencyValue(event) {
console.log('qwer ' + this)
this.setState(Object.assign({}, this.state, {currencyValue: event.target.value}))
}
handleChangeCurrencyCode(event) {
console.log('qwer ' + this)
this.setState(Object.assign({}, this.state, {currencyCode: event.target.value}))
}
calculate(event){
var obj = this
axios.get('http://localhost:8080/Currency/currency?currencyCode=' + this.state.currencyCode + '¤cyValue=' + this.state.currencyValue + '&responseType=json')
.then(function(resp){
console.log('RESULT: ', resp.data.result)
obj.setState(Object.assign({}, obj.state, {result: resp.data.result}))
})
.catch(error => {
console.log(error)
});
}
render() {
return (
<div>
<TextArea functionChangeValue={this.handleChangeCurrencyValue.bind(this)} value={this.state.currencyValue} />
<ComboBox functionChangeCode={this.handleChangeCurrencyCode.bind(this)} value={this.state.currencyCode} />
<p>
<button onClick={this.calculate.bind(this)}>Calculate</button>
</p>
<div>{this.state.result}</div>
</div>
);
}
}
class TextArea extends React.Component {
render() {
return (
<div>
<h4>
<div>Type value you want to exchange: </div>
<input type='text' onChange={this.props.functionChangeValue}/>
{/* <div>Value of your currency is: {this.props.value}</div> */}
</h4>
</div>
);
}
}
class ComboBox extends React.Component {
render() {
return(
<div>
<h4>
<div>Select your currency:</div>
<select onChange={this.props.functionChangeCode}>
<option>USD</option>
<option>EUR</option>
<option>GBP</option>
</select>
{/* <div>Your currency is: {this.props.value}</div> */}
</h4>
</div>
);
}
}
export default App;
Can you give me idea or some example?
You can use regex and conditionally change state.
onChange(event){
const regex = /^[0-9\b]+$/;
const value = event.target.value;
if (value === '' || regex.test(value)) {
this.setState({ value })
}
}
Consider making use of the ValidatorJS Library as opposed to rolling your own validation method.
Example usage in your code would be something like this...
handleChangeCurrencyValue(event) {
console.log('qwer ' + this)
const currencyValue = event.target.value;
if(validator.isInt(currencyValue)) {
this.setState({ currencyValue });
}
}
I recommend using libraries that have been thoroughly tested for validation as this will reduce security concerns down the line. Also, validator is extremely easy to implement.
can it be something like that:
<input type="number" min="0" step="1"/>
You can use regex (regular expression) to handle that. The regex that you use is /[0-9]+/g.
For example you have input:
<input value={this.state.value} onChange={this.onChange}/>
And the onChange:
onChange(text) {
let newText = '';
const numbers = '^[0-9]';
for (let i = 0; i < text.length; i++) {
if (numbers.indexOf(text[i] > -1)) {
newText += text[i];
}
this.setState({ currencyValue: newText });
}
}
or like this:
onChange(e){
const re = /^[0-9\b]+$/;
if (e.target.value == '' || re.test(e.target.value)) {
this.setState({currencyValue: e.target.value})
}
}
May it can help you! :)
I'm trying to create a currency input, that starts as something like
" $00.00"
and then when you start typing, it types the cents first, then moves on to the dollars (ie, updates the right side numbers first), e.g
" $00.50"
A reddit user posted this piece of JS code to help me : https://codepen.io/benjaminreid/pen/gRbgxK?editors=0010
const FormattedInput = class extends React.Component {
constructor(props) {
super(props);
this.amountChanged = this.amountChanged.bind(this);
this.state = {
value: 0,
};
}
amountChanged(e) {
this.setState({
value: e.target.value,
});
}
formatValue(value) {
return accounting.formatMoney(parseFloat(value) / 100);
}
render() {
return (
<div>
<label for="formatted">Formatted input</label>
<input
id="formatted"
type="text"
value={this.formatValue(this.state.value)}
/>
<label for="amount">Actual user input (type in here)</label>
<input
id="amount"
type="text"
onChange={this.amountChanged}
value={this.state.value}
/>
</div>
);
}
}
const App = () =>
<div>
<FormattedInput/>
</div>
;
ReactDOM.render(
<App/>,
document.querySelector('#app')
);
It works great, but the input you enter and the input that gets displayed are in two different boxes. I was wondering if there was a way to type straight into the formatted currency box?
Does anyone have a better solution perhaps? Help would be greatly appreciated.
I tried to code something to solve your problem. It is not so hard to build from scratch.
const FormattedInput = class extends React.Component {
constructor(props) {
super(props);
this.amountChanged = this.amountChanged.bind(this);
this.state = {
value: '',
rawValue: '',
};
}
amountChanged(e) {
let tmpAmount = '';
let tmpValue = e.target.value.slice(-1);
let newRawValue = this.state.rawValue + tmpValue;
if ( this.state.value.length > e.target.value.length) {
this.setState({
value: '',
rawValue: '',
})
}
else {
if (newRawValue.length === 1) {
tmpAmount = '0.0' + newRawValue;
}
else if (newRawValue.length === 2) {
tmpAmount = '0.' + newRawValue;
}
else {
let intAmount = newRawValue.slice(0, newRawValue.length - 2);
let centAmount = newRawValue.slice(-2);
tmpAmount = intAmount.replace(/\B(?=(\d{3})+(?!\d))/g, ",") + '.' + centAmount;
}
this.setState({
value: tmpAmount,
rawValue: newRawValue,
});
}
}
formatValue(value) {
return accounting.formatMoney(parseFloat(value) / 100);
}
render() {
return (
<div>
<label for="amount">Mix</label>
<input
id="amount"
type="text"
placeholder="$0.00"
onChange={this.amountChanged}
value={this.state.value}
/>
</div>
);
}
}
const App = () =>
<div>
<FormattedInput/>
</div>
;
ReactDOM.render(
<App/>,
document.querySelector('#app')
);
I've made a simple react tasklist, which allows me to add new tasks. I now want to be able to remove tasks, but cant see how to pass a function property down to a child / grandchild component.
I'm wanting to pass the deleteTaskFromState function property down to the <Task /> component. I've successfully done this with the addTaskToState function, but cant see how to do it with the deleteTaskFromState function prop.
Codepen here
On line 108 I've pass deleteTaskFromState to the <TaskList /> component, but when I put deleteTask={this.props.deleteTaskFromState} on the <Task /> component (line 57) it errors with Cannot read property 'props' of undefined.
If anyone can help I'd be hugely grateful!
After this property is passed I need to then complete the function prop deleteTaskFromState to remove the selected task from state, if anyone know how to do that too, that would be great!
// function to generate unique id for react keys - use npm uuid usually
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4()
// + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
class TaskInput extends React.Component {
createTask(event){
event.preventDefault();
let task = {
key: guid(),
task : this.refs.task.value,
priority : this.refs.priority.value,
}
this.props.addTaskToState(task);
this.refs.addTaskForm.reset();
}
render() {
return (
<form onSubmit={this.createTask.bind(this)} ref="addTaskForm">
<input placeholder="enter a task" ref="task" />
<input placeholder="priority" ref="priority" />
<button type="submit">Submit</button>
</form>
);
}
}
class Task extends React.Component {
render() {
return (
<div>
<li className="task"><button>x</button>
<strong> {this.props.taskdata.priority} </strong>
{this.props.taskdata.task}</li>
</div>
);
}
}
class TaskList extends React.Component {
render() {
if(this.props.deleteTaskFromState) {
console.log('deleteTaskFromState found')
}
let TaskItems;
if(this.props.taskstate){
TaskItems = this.props.taskstate.map(function (taskdata) {
return (
<Task taskdata={taskdata} key={taskdata.key}/>
);
});
}
return (
<ul className="task-list">
{TaskItems}
</ul>
);
}
}
class TaskListApp extends React.Component {
constructor(props) {
super(props);
this.state = {
tasks : [
{
key: "task1",
task: "dance",
priority: "superhigh",
},
{
key: "task2",
task: "tax return",
priority: "superlow",
}
]
};
}
deleteTaskFromState(keyToDelete) {
let tasks = this.state.tasks;
// find object in state array with keyToDelete
// remove object
}
addTaskToState(task) {
let tasks = this.state.tasks;
tasks.push(task);
this.setState({tasks:tasks});
}
render() {
return (
<div>
<h1>Task List</h1>
<TaskInput addTaskToState={this.addTaskToState.bind(this)} />
<TaskList
taskstate={this.state.tasks}
deleteTaskFromState={this.deleteTaskFromState.bind(this)}
/>
</div>
);
}
}
ReactDOM.render(<TaskListApp />, document.getElementById("app"));
All you have to do just pass deleteTaskFromState
to child/grandchild like you did with addTaskToState
CodePen
class Task extends React.Component {
deleteTask() {
this.props.deleteTaskFromState(this.props.taskdata.key)
}
render() {
return (
<div>
<li className="task"><button onClick={this.deleteTask.bind(this)}>x</button>
<strong> {this.props.taskdata.priority} </strong>
{this.props.taskdata.task}</li>
</div>
);
}
}
class TaskList extends React.Component {
render() {
if(this.props.deleteTaskFromState) {
console.log('deleteTaskFromState found')
}
let TaskItems;
if(this.props.taskstate){
let deleteTaskFromState = this.props.deleteTaskFromState;
TaskItems = this.props.taskstate.map(function (taskdata) {
return (
<Task
taskdata={taskdata}
key={taskdata.key}
deleteTaskFromState={deleteTaskFromState} />
);
});
}
return (
<ul className="task-list">
{TaskItems}
</ul>
);
}
}