How to limit number of characters in Field using Redux? - reactjs

I have Field input and my idea is to user can input only 15 characters.
After 15 characters I want not displaying anything in field. I have tried with normalize but not working. I'm checking with value.length and after 15 characters my state is not updating which is good but I can still entering characters. I want after 15 entered characters, if user put something not to show that in browser. Can anyone help me?
<Field
name={`name`}
placeholder='placeholder'
classes={classes}
component={this.component}
onChange={this.changeHandler}
/>
changeHandler= (event) => {
if(event.target.value.length < 16)
{
this.setState({
myProperty: event.target.value
});
}

For redux-form Field there isn't a props to limitate number of chars. Considering that you are using Field in a form, you could validate the field itself (using validate props as in this example) but still the possibility to add more than 15 chars.
But as you know you could customize your Field using component props. Something like:
<Field name="myField" component={renderField}/>
And in renderField you could use input and in input you have maxlength props.
So your renderField could be something like:
const renderField = (field) => (
<div className="input-row">
<input {...field.input} type="text" maxlength="15"/>
</div>
)
This should solve your problem.

For this you would need a handled value. Pass value={this.state.myProperty} to the Field. So if this property is no longer updated after 15 characters, the value of the field won't be updated either.

Related

How to parse untouched fields in react-final-form

I have an input for an amount in react-final-form. If it's not filled, I need to set its form value to zero. I can't pass an initial value to it as if it hasn't been filled by the user, the input itself should stay empty.
In react-final-form docs there's a parse function. But it works only if the field has been touched (filled and then cleared by the user). Is there any way to parse untouched fields and set them to zero in form values, without updating the input?
Here is my code:
<Field
name="amount"
component={CurrencyInput}
parse={value => (value ? value : 0)}
/>
And here is the link to my codesandbox.
if by doing this what you are trying to accomplish is that the object displayed in the <pre> has a default value of zero when the input is empty you could use a state variable and inside the parse keep updating its value
const [amount, setAmount] = useState(0);
const onInputChange = e => {
e === "" || e === undefined ? setAmount(0) : setAmount(e);
};
and in the Field tag
<Field
name="amount"
component={CurrencyInput}
parse={value => onInputChange(value)}
defaultValue={amount}
/>
check the codesandbox here:
https://codesandbox.io/s/react-final-form-wreact-number-format-and-parse-22q3n
Hope this Resolves the issue

How to pass on a start value to input? [duplicate]

This question already has answers here:
React Input Element : Value vs Default Value
(4 answers)
Closed 3 years ago.
Here it is:
<input type="text" name="firstname" onChange={this.handleInputChangeEdit}/>
When I try to set start value into input (value ={...}) it becomes blocked and it's impossible to change string. How to evade this?
You can use defaultValue instead of value as attribute for input as mentioned on react documentation (for uncontrolled components). There are multiple ways to effect the same change but this seems to be the simplest based on what you were already trying to do.
https://reactjs.org/docs/uncontrolled-components.html#default-values
To give the input a default value while still being able to update it, you should connect it to your component-state.
Simply put, any time you type something, you trigger your handleInputChangeEdit function. It takes the text you enter and updates the firstname field in state. That value gets passed back down to the input for display.
class App extends React.Component{
state = {
firstname: "This is the default text"
}
handleInputChangeEdit = (event) => {
this.setState({
[event.target.name]: event.target.value
})
}
render(){
return(
<input
value={this.state.firstname}
type="text"
name="firstname"
onChange={this.handleInputChangeEdit}
/>
)
}
}
The initial/default value will be whatever you had in the state object and now you are free to update the input-text which continues this pattern.

How to customize error display logic in Formik?

Formik has two options controlling when validation occurs: validateOnChange and validateOnBlur.
Problem with using validateOnChange - user will get errors as they start typing, say, email - because it is not valid when you just started to type first letters.
In case of validateOnBlur - let's say user typed in invalid email, left the field, returned and fixed to correct email - the error will be shown anyway until they leave the field, so this also does not work for me.
What I would like to achieve - first time validate a field on blur and starting that point - on change.
Every field should get this treatment individually.
I tried to find native ways to do it but couldn't find any, so I came up with this solution that I do not really like because it is not flawless:
TL;DR: I override standard onBlur and onChange coming from Field's props and a) onBlur - mark field as changed once (probably I could use touched here) b) onChange I check if field was touched once and if so - call validation.
0) Disable validation
<Formik
validateOnChange={false}
validateOnBlur={false}
...
1) Added changedFields to my state
public state: IState = {
changedFields: {}
};
2) Use special method that overrides default onBlur and onChange
<Field name="userName" render={(props: FieldProps<MyFormInterface>) => (
<input type="text" label={'Name'} {...formikCustomValidation(props, this)} />
)}/>
3) The method. Passing Field's props and the parent component where state with changedFields is located.
function formikCustomValidation({ field, form }: FieldProps, ownerCmp: Component<any, any>) {
return {
...field,
onBlur: e => {
if (field.value !== form.initialValues[field.name]) {
ownerCmp.setState({
changedFields: {
...ownerCmp.state.changedFields,
[field.name]: true
}
});
}
field.onBlur(e);
setTimeout(form.validateForm);
},
onChange: e => {
field.onChange(e);
if (ownerCmp.state.changedFields[field.name]) {
setTimeout(form.validateForm);
}
}
};
}
The question is - is there a way to do it easier?
The problem with this solution - if I Submit and untouched form and some errors come up - focus and fix value does not mark field as valid - because it is the first 'touch' and field is still in stat waiting for first blur state that supposed to make listen for 'changes'.
Anyway, maintaining this could be a pain, so looking for better solution.
Thanks!

Dynamically set a property value for an Input in Semantic UI React

I have an Input element that I want to display an error on when the form validation fails.
<Input ref="amount" error={false} />
When the user enters an incorrect amount, I want to change "error" to "true". How can this be done?
I have tried:
this.refs.amount.props.error = true;
Which seems bad but I'm not sure how else. If I add a conditional statement in the definition of the Input element, that seems to only evaluate once and then remain the same. Do I need to force an update on the element? If so, how?
Yes it's possible to validate the input when the form is submitted.
All you need is to keep track on input value and use same approach as #SajithDilshan for the input error.
this.state = {
error: false,
value: ''
}
...
render(){
return
...
<Input
ref="amount"
value={this.state.value}
error={this.state.error}
/>
...
}
Then onSubmit should looks like:
onSubmit(e){
const isError = this.state.value === '';
this.setState({error: isError});
// rest of your logic
}
Hope it will help!
Use the onChange() method on the input as below.
<Input ref="amount" onChange={this.onInputChange} error={this.state.error} />
After that implement the onInputChange() method as below in your component.
onInputChange = (e) => {
if (e.target.value === "") { // logic to validate the input
this.setState({error: true});
} else {
this.setState({error: false});
}
}
Note that this will add error property to the state.
Further, you should not modify the props within a component. Props are passes from parent component to the child component as immutable inputs.
This is not exactly the answer, but still:
This type of fiddling with each possible state of form element (valid, invalid, warning, show tooltip, was edited, in focus, left focus, was submitted, submit failed or not, etc) becomes to much trouble when the form grows beyond 1 input field.
I would suggest to use redux-form package that integrates with semantic-ui-react` almost perfectly and provided you have provided it with the validate function does everything else for you. It takes some time to understand the basics of it, but it really pays.

How to clear the text field in formsy material ui React

Hi I am using React 14 and writing it in ES6. I am using formsy-material-ui for form validations. There is a scenario where I want to clear the value of text field on click of a button.
I tried the following code
<FormsyText
name="email"
ref="email"
validations="isEmail"
validationError="Invalid Email"
hintText="Email"
value={this.state.emailValue}
/>
And on click of the button, I am executing the following line of code
this.setState({emailValue : ''});
But the text field is not getting cleared.
How to clear it.
Pls help.
So, if you were using a controlled input (maybe using directly the TextField from Material-ui) - your code would be right, however the FormsyText component handle it's value internally.
If you pass a value or defaultValue it'll just be used when it's rendered, you can check it here.
I only see one way to clear the value now, in an imperative style.
this.refs.email.setState({ value: "" })
Note: I suggest you to change the way you're using the ref. Using refs with a string is deprecated and probably will be removed in the future. Instead you should pass a function that's gonna receive that component. https://facebook.github.io/react/docs/more-about-refs.html
Example:
<FormsyText
name="email"
ref={(node) => this._emailText = node}
validations="isEmail"
validationError="Invalid Email"
hintText="Email"
value={this.state.emailValue}
/>
//And to clear it
this._emailText.setState({ value: "" })
Try reset field after setState:
this.setState({emailValue : ''});
this.refs.email.reset()
Also you can reset all form.
this.refs.form.reset()
const formRefdeposit = useRef(null);
<Formsy
onValidSubmit={handleSubmit}
onValid={enableButton}
onInvalid={disableButton}
ref={formRef}
>
....Form Fields
</Formsy>
if you have class in your js file then use
this.formRef.current.reset();
if without class then use
formRef.current.reset();

Resources