onBlur required
I have a case where i validate onBlur={this.props.setValue(this.props.getValue());} / onExit Now only validation rule that i want to achieve is: Required / No empty text
And my input component code looks like:
<MyInput required name="req" title="Required input!" validationError="This field is required!" />
Now the problem is: Form will say that it's not valid and it would trigger onInvalidSubmit
But input will never get anything in this.props.getErrorMessage() method it will stay null and because of that i can't catch error onSubmit
So i spent some time looking around and going through a code, and I found out that if I implement my component like this, it would WORK!:
<MyInput required name="req" title="Required input!" validationErrors={{"isDefaultRequiredValue":"This field is required!"}} />
My component and form code looks something like:
MyInput Component
import React from 'react';
import { propTypes, withFormsy } from 'formsy-react';
class MyInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this)
this.handleOnBlur = this.handleOnBlur.bind(this)
}
handleOnBlur(event) {
// Validate at Blur
this.props.setValue(this.props.getValue());
// Execute onBlur prop
if (typeof this.props.onBlur === 'function') {
this.props.onBlur(event);
}
}
handleChange(event) {
// Store validation but dont validate
if(!this.props.isValid()){
this.props.setValue(event.currentTarget.value);
}else{
this.props.setValue(event.currentTarget.value, false);
}
// Execute onChange prop
if (typeof this.props.onChange === 'function') {
this.props.onChange(event);
}
}
render() {
const errorMessage = this.props.getErrorMessage();
return (
<div>
<label htmlFor={this.props.name}>{this.props.title}</label>
<input
onChange={this.handleChange}
onBlur={this.handleOnBlur}
value={this.props.getValue() || ''}
name={this.props.name}
/>
<span className='validation-error'>{errorMessage}</span>
</div>
);
}
}
MyInput.propTypes = {
...propTypes,
};
export default withFormsy(MyInput);
MyFormsyForm
import React from 'react';
import ReactDOM from 'react-dom';
import Formsy from 'formsy-react';
// My Input
import MyInput from 'Input';
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Formsy onValidSubmit={()=>alert('Valid')} onInvalidSubmit={()=>alert('Invalid')}>
/* This will Not work! */
<MyInput required name="test1" title="Test1" validationError="This field is required!" />
/* This will work! */
<MyInput required name="test2" title="Test2" validationErrors={{"isDefaultRequiredValue":"This field is required!"}} />
<button type="submit">Submit to validate!</button>
</Formsy>
);
}
}
ReactDOM.render(<App/>, document.getElementById('example'));
Not sure if it's a bug or my bad implementation but, it's just feels kinda natural to add prop required and if you only have required then validationError is dedicated to required state?
Anyway, thanks for your hard work with Forms!
So this is roughly how I have my components built, with required and errors being different things in the render:
const errorMessage = this.props.getErrorMessage()
, isPristine = this.props.isPristine()
, isValid = this.props.isValid()
, showRequired = this.props.showRequired()
, showError = _.isBoolean(this.props.showError) ? this.props.showError : this.props.showError()
, showRequiredMessage = !isPristine && !isValid && showRequired;
{showRequiredMessage &&
<HelpBlock>{label || 'This field'} is required.</HelpBlock>}
{showErrorMessage &&
<HelpBlock>{errorMessage}</HelpBlock>}
Hopefully some other people will chime in, but I would especially check out formsy-react-components by @twisty for examples of great component source.
Does this answer your question? I may have interpreted it incorrectly.
It's just my idea to make required easier to use. With just required and validationError without ugly validationErrors={{"isDefaultRequiredValue":"This field is required!"}}.
OKAY, two more years working on Formsy and I now understand this issue! The proposal is that when validationError: string and required: true and validations: undefined then validationError should be used as the required error much like it would be used as the validation error.
I think I understand this now, and yes, it does seem to help tighten the usage in that use case. However, on first understanding, it seems very complicated and likely to generate confusion. Does anyone else have any opinions, or want to correct any of my understanding, or advocate for it?
hahahahaha, well better ever than never :D
This is just something we had problem with, lot of forms with a lot of fields with very long props just to achieve default required state.
I've later update this to fallback to isDefaultRequiredValue":"This field is required!" props with just required message and found that kind of approach can hard code required message error, tho that is not that big of a problem.