ReactJS - How can I set a value for textfield from material-ui? - reactjs

I have a selectField and I want to set a value on it. Let say I type on it and when I click a button, the button will call a function that will reset the value of the textfield?
<TextField hintText="Enter Name" floatingLabelText="Client Name" autoWidth={1} ref='name'/>

You can do it in this way
export default class MyCustomeField extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Enter text',
};
}
handleChange = (event) => {
this.setState({
value: event.target.value,
});
};
handleClick = () => {
this.setState({
value:'',
});
};
render() {
return (
<div>
<TextField
value={this.state.value}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>Reset Text</button>
</div>
);
}
}

It's maintained that the right way is to have the component be controlled in a scenario like the accepted answer there, but you can also control the value in this gross and culturally unacceptable way.
<TextField ref='name'/>
this.refs.name.getInputNode().value = 'some value, hooray'
and you can of course retrieve the value like so
this.refs.name.getValue()

Instead of using ref you should use inputRef
const MyComponent = () => {
let input;
return (
<form
onSubmit={e => {
e.preventDefault();
console.log(input.value);
}}>
<TextField
hintText="Enter Name"
floatingLabelText="Client Name"
autoWidth={1}
inputRef={node => {
input = node;
}}/>
</form>
)
};

Here is a short simple React Hook version of the answer
export default function MyCustomeField({
initialValue= '',
placeholder= 'Enter your text...'
}) {
const [value, setValue] = React.useState(initialValue)
return (
<div>
<TextField
placeholder={placeholder}
value={value}
onChange={e => setValue(e.target.value)}
/>
<button onClick={() => setValue(initialValue)}>Reset Text</button>
</div>
);
}

I would suggest to do a little wrap on the original MUI TextField.
export default function ValueTextField(props) {
const [value, setValue] = useState(props.value);
return (
<TextField {...props} onChange={(event) => setValue(event.target.value)} value={value}/>
);
}
Now you can use your own ValueTextField component now.
<ValueTextField value={"hello world"}></ValueTextField>

I prefer this way to assign the state variables:
<TextField value={mobileNumber}
onChange={e => { this.setState({ mobileNumber: e.target.value }) }}
className={classes.root}
fullWidth={true}
label={t('mobile number')} />

Related

How to implement custom handleOnChange in Formik

as I mentioned in the title, how can I implement my custom handleChange function?
Here's standard example:
const MyTextField = ({ label, ...props }) => {
const [field, meta, helpers] = useField(props);
return (
<>
<input {...field} {...props} />
</>
);
};
const Example = () => (
<div>
<h1>My Form</h1>
<Formik
initialValues={{}}
onSubmit={() => {}}
>
{() => (
<Form>
<MyTextField name="firstName" type="text" label="First Name" />
</Form>
)}
</Formik>
</div>
);
Let's say I have onChange function:
const customHandle = (e) => {
console.log('Custom Function')
}
How can I combine my custom function with Formik
EDIT.
Explanation: I will not use form in my case, I just want to have simple input which will update a 'redux or something else state managmenent'

Clicking on radiobutton returns undefined values

I want to create an app where you can choose quantity fo water that you have drinked. I want to use radiobuttons in form for 3 default values -250ml, 500ml and 1000ml.
I created radiobuttons, but when I click on them, I get undefined value after e.target method.
I tried to bind my functions on checked and onChange but it didn't help.
Main component WaterApp.js:
import WaterButtons from './WaterButtons';
const quantitiesData = [
{
id: 'water_250_ml',
value: 250,
name: 'water_250_ml'
},
{
id: 'water_500_ml',
value: 500,
name: 'water_500_ml'
},
{
id: 'water_1000_ml',
value: 1000,
name: 'water_1000_ml'
}
];
export default class WaterApp extends React.Component {
state = {
waterQuantity: 'water_250_ml'
};
handleCheckedWaterQuantity = (e) => {
this.state.checkedQuantity === e.target.value;
}
handleWaterQuantityChange = (e) => {
const waterQuantity = e.target.value;
this.setState({ waterQuantity });
console.log(waterQuantity);
}
render() {
return (
<div>
<form>
<WaterButtons
quantities={quantitiesData}
handleCheckedWaterQuantity={(e) => this.handleCheckedWaterQuantity(e)}
handleWaterQuantityChange={(e) => this.handleWaterQuantityChange(e)}
/>
</form>
</div>
)
}
}
WaterButtons.js
import WaterButton from './WaterButton';
const WaterButtons = (props) => (
<div>
{
props.quantities.map((quantity) => (
<WaterButton
key={quantity.id}
id={quantity.id}
value={quantity.value}
label={quantity.name}
checked={props.handleCheckedWaterQuantity}
handleWaterQuantityChange={props.handleWaterQuantityChange}
/>
))
}
</div>
);
export default WaterButtons;
WaterButton.js
const WaterButton = (props) => (
<div>
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(props.value)}}
/>
<label htmlFor={props.id}>
{props.label}
</label>
</div>
);
export default WaterButton;
I want to get the value for clicked radiobutton.
[EDIT] Also, I have a problem with checked value for every radiobutton. Function that is now is not working. I thought maybe I should change my code so that in WaterButton.js i define state for buttons. Then it would have to be class not stateless component.
You are calling handleWaterQuantityChange with incorrect argument please see the below code
Your onChange should be onChange={(e) => {props.handleWaterQuantityChange(e)}}
const WaterButton = (props) => (
<div>
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(e)}}
/>
<label htmlFor={props.id}>
{props.label}
</label>
</div>
);
In props.handleWaterQuantityChange you are passing props.value instead of event
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={(e) => {props.handleWaterQuantityChange(e)}}
or
<input
type="radio"
id={props.id}
value={props.value}
name="waterQuantity"
checked={props.checked}
onChange={props.handleWaterQuantityChange}

Reset state to initial state only for specific state variables

I want to reset state's variable to initial only for specific value
I have tried this:
const initialState={
name:'',
location:'',
....
....
....
}
this.state={
...initialState,
spinner:false,
open:false,
errorMessage:''
}
resetToInitialState = () =>{
this.setState(...initialState);
}
I am calling this resetToInitialState inside a function like this.resetToInitialState();
<TextField
id="outlined-name"
label="Machine id"
className={classes.textField}
InputProps={{
classes: {
input: classes.text,
},
}}
value={ !name && null } //tried this not working
onChange={e => this.setState({name: e.target.value})}
margin="normal"
variant="outlined"
/>
You forgot {}
this.setState({...initialState})
When you try to reset state, you need to clone initial state. If you pass in a reference to initialState, that will get mutated when you change state.
this.setState({...initialState});
To create a controlled component, TextField needs the value to be this.state.name.
<TextField
id="outlined-name"
label="Machine id"
className={classes.textField}
InputProps={{
classes: {
input: classes.text,
},
}}
value={ this.state.name }
onChange={e => this.setState({name: e.target.value})}
margin="normal"
variant="outlined"
/>
Edit: Reset TextField component when value is My Value
If you only want to reset the state when name is a specific value, you need to create a different onChange function and set onChangeReset to the onChange prop in the TextField component.
onChangeReset = e => {
if(e.target.value === 'My Value') {
this.resetToInitialState();
else {
this.setState({ name: e.target.value});
}
}
<TextField
onChange={this.onChangeReset}
value={this.state.name}
/>
Edit: Add multiple TextField components with reset function to reset all of the TextField components at the same time.
import React, { Component } from 'react';
class MyGroupedTextFields implemements Component {
constructor(props) {
super(props);
this.state = {
fields: {},
spinner: false,
open: false,
errorMessage: ''
};
}
resetTextFields = () => {
const state = { ...this.state };
state.fields = {};
this.setState({ state });
}
onTextFieldChange = event => {
const fields = {...this.state.fields};
fields[event.target.name] = event.target.value;
this.setState({ fields });
}
submit = async () => {
// perform submit network request
// pseudo code
const response = await submitForm(this.state.fields);
}
render() {
return (
<div>
<TextField
name='textField1'
onChange={this.onTextFieldChange}
value={this.state.fields.textField1}
/>
<TextField
name='textField2'
onChange={this.onTextFieldChange}
value={this.state.fields.textField2}
/>
<TextField
name='textField3'
onChange={this.onTextFieldChange}
value={this.state.fields.textField3}
/>
<button onClick={this.resetTextFields}>
Reset
</button>
<button onClick={this.submit}>
Submit
</button
</div>
);
}
}

React - Date input value not updated to state

In my React App, I am able to set the state and update the database for all values except the date input field. My code is below:
import React, { Component } from 'react'
...
...
import DateInput from '../others/input/datePicker'
...
..
change = (what, e) => this.setState({ [what]: e.target.value })
changeDOB() {
this.setState({ age: document.getElementByClassNames("datePicker").value })
}
render() {
let {
...
...
age,
...
} = this.state
...
...
//date of birth
let stringAge = age.toString()
stringAge =
stringAge.substring(0, 4) +
'-' +
stringAge.substring(4, 6) +
'-' +
stringAge.substring(6, 8)
...
<DateInput
type="date"
change={this.changeDOB}
placeholder={stringAge}
className="datePicker"
/>
...
...
const mapStateToProps = store => ({
ud: store.User.user_details,
tags: store.User.tags,
session: store.User.session,
})
export default connect(mapStateToProps)(EditProfile)
export { EditProfile as PureEditProfile }
Here is DateInput code:
import React from 'react'
import { string, func, oneOf, bool } from 'prop-types'
const DateInput = ({ type, placeholder, ...props }) => (
<input
type={type}
placeholder={placeholder}
spellCheck="false"
autoComplete="false"
{...props}
/>
)
DateInput.defaultProps = {
type: 'date',
placeholder: '',
disabled: false,
}
DateInput.propTypes = {
type: oneOf(['date']),
placeholder: string.isRequired,
maxLength: string,
disabled: bool,
}
export default DateInput
I tried this.change like other fields but that does not work either.
How to get the new value updated in the state ?
Note: The text is red is the value currently in the database.
You need to add onChange attribute for the input field in the DateInput component as
const DateInput = ({ type, placeholder, ...props }) => (
<input
type={type}
placeholder={placeholder}
spellCheck="false"
autoComplete="false"
onChange = {props.Onchange}
{...props}
/>
)
Then your main component should be as
changeDOB(e) {
this.setState({ age: e.target.value });
}
render() {
return(
<DateInput
type="date"
Onchange={this.changeDOB}
placeholder={stringAge}
className="datePicker"
/>
)
}
Please find a working example here
You are passing all the props to input component but you need to pass your event handler function to onchange input element or Try onkeypress instead. Something like below. You can also try getting input value with event instead of document
Arrow function: No need of manual binding
changeDOB = (event) => {
this.setState({ age: event.target.value
})
}
<DateInput
type="date"
change={this.changeDOB}
placeholder={stringAge}
className="datePicker"
value={this.state.age}
/>
<input
type={type}
placeholder={placeholder}
spellCheck="false"
autoComplete="false"
onchange={(event) => props.change(event)}
value={props.value}
{...props}
/>
Normal function: Binding required and only in constructor
this.changeDOB = this.changeDOB.bind(this);
changeDOB(event){
this.setState({ age: event.target.value
})
}
<DateInput
type="date"
change={this.changeDOB}
placeholder={stringAge}
className="datePicker"
value={this.state.age}
/>
<input
type={type}
placeholder={placeholder}
spellCheck="false"
autoComplete="false"
onchange={props.change}
value={props.value}
{...props}
/>
The date is being taken in the ISO format whereas the display expects it in the localformat.
This worked for me:
const [deadline, setDeadline] = useState(new Date());
<input
type="date"
id="start"
name="trip-start"
value={deadline.toLocaleDateString}
onChange={(event) => setDeadline({deadline:event.target.value})}
min="2022-01-01"
max="2022-12-31"
>
</input>

reactjs container component form values

I am new to react and am trying to get the value from the firstName input in handleSubmit. handleSubmit is working but for some reason the input value is undefined. I tried following some other examples but they were all forms in React components.
let SomeForm = (props) => {
let firstName = '';
const handleSubmit = (e) => {
e.preventDefault();
console.log(firstName);
}
return (
<div>
<form onSubmit={handleSubmit}>
<TextField
floatingLabelText="First Name"
floatingLabelFixed={true}
underlineStyle={styles.underlineStyle}
underlineFocusStyle={styles.underlineFocusStyle}
value={firstName}
/>
<input type="submit" value="Submit" />
</form>
</div>
)
}
SomeForm = connect()(SomeForm)
export default SomeForm
You need to add onChange to the TextField to handle the updates. And because SomeForm is a stateful component, you may need to use a class component instead of a stateless functional component.
class SomeForm extends React.Component {
state = {
firstName: ''
};
handleChange = (e, value) => {
this.setState({ firstName: value });
};
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state.firstName);
};
render () {
return (
<div>
<form onSubmit={this.handleSubmit}>
<TextField
id="text-field-controlled"
floatingLabelText="First Name"
floatingLabelFixed={true}
underlineStyle={styles.underlineStyle}
underlineFocusStyle={styles.underlineFocusStyle}
value={this.state.firstName}
onChange={this.handleChange}
/>
<input type="submit" value="Submit" />
</form>
</div>
)
}
}
See the API and examples of TextField here: http://www.material-ui.com/#/components/text-field
You need function that you will throw in your TextField component and with onChange you can get value of input.
handleChange(e){
Console.log(e.target.value)
}
And in TextField
<TextField onChange={this.handleCahnge}/}
Or use refs
<TextField ref="textfield" />
And get value with this.refs.textfield.getValue()

Resources