React Admin - How to disable validation onChange - javascript

I'm using react-admin, and I have a huge form, with a bunch of custom validation. It's very slow, even with the build version.
I tried to find a way to disable the validation on change and to have it only on blur or submit. But I have not found a solution or even workaround.
Every time a key is pressed in one of my input text (for example), the validation is triggered multiple times, and it takes a while for the letter to appear.
That's why I want to disable the validation on change.
Here's an example of one of my forms, every letter I write in one of my FormTab, the "validate me" is showing.
export const ThemeCreate: FC = (props: any) => (
<Create {...props} title="ui.themes.create" mutationMode="pessimistic">
<TabbedForm
toolbar={<GenericCreateToolbar />}
validateOnBlur
warnWhenUnsavedChanges
validate={() => {
console.log('validate me!');
}}
>
<MainFormTab />
<TranslationsFormTab />
</TabbedForm>
</Create>
);

You need to use the validateOnBlur={true} prop in the form component.
This prop is from final-form's <Form> component, see the last one in this doc page https://final-form.org/docs/react-final-form/types/FormProps

Related

Material UI Checkbox controlled by keyboard

we are developing a web application using react and material ui and we need to take care of accessibility which means our web application shall be used by persons with disabilities.
Therefore, the web application needs to by operable by keyboard.
It is necessary that one can tab through the forms and use enter to trigger some action. For inputs and buttons this works fine. However, for checkboxes there is a problem. I can focus on a checkbox using tab but I cannot check the checkbox using enter.
When I use onChange/onClick the checkbox gets checked only when I use the mouse:
<Checkbox
checked={this.state.statementNecessary}
onChange={() => {
this.setState({ statementNecessary: !this.state.statementNecessary })}} />
When I use onChange/Onclick + onKeyDown I can focus the checkbox with tab but when I use tab another time the checkbox gets checked even if I just want to go to the next input element.
<Checkbox
checked={this.state.statementNecessary}
onKeyDown={() => {
this.setState({ statementNecessary: !this.state.statementNecessary })}}
onChange={() => {
this.setState({ statementNecessary: !this.state.statementNecessary })}} />
Any hints are appreciated.
I just found out that checkboxes are supposed to get checked by using space:
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/checkbox_role
So, this is the desired behavior which is working with material ui.
you must check which key is pressed and check for example if Enter Key is pressed then change the state of CheckBox
onKeyDown={(e) => {
if (e.key === "Enter" )this.setState({ statementNecessary: !this.state.statementNecessary })}}

How to autofocus select input after async call?

I'm using Material UI's Autocomplete component, and I'm running into an issue. I have a debounced API call that is made when a user starts typing, and I disable the text input field while the call is being executed.
The issue is that disabling and then enabling the text field makes the text input lose focus. I've tried giving it an ID and grabbing it in the DOM and running .onFocus(), but that a) didn't work and b) isn't very React-y.
I also tried to add a useRef hook, but that didn't work either.
Any thoughts/suggestions?
Codesandbox
Hey you can add inputRef prop and then just wait until it is done loading. Here is exmaple:
const inputComponent = React.useRef(null);
return (
<Autocomplete
{/* ... */}
renderInput={params => (
<TextField
{/* ... */}
InputProps={{
{/* ... */}
inputRef: inputComponent,
{/* ... */}
}}
/>
)}
/>
);
And then I am guessing that you tried to focus element while it was still disabled, I guess a little race condition. You can add useEffect that is dependent on open and loading like this:
React.useEffect(() => {
if (!loading && open) {
inputComponent.current?.focus();
}
}, [loading, open]);
Here is the link to sandbox with it. Cheers, hope it helps.
P.S I don't think it is a good idea to disable the field while options are loading, it won't feel smooth for the user :)

React-final-form-array how to rerender form based on new state

I'm using react-final-form-arrays to build a dynamic field system, so far the scenario would be like this:
User clicks on button to open the editor modal (Add/Remove custom field using react-final-form-array. Once done, click Save and it will update the primary form.
The primary form is also using react-final-form-array to loop through the fields and render, without the Add/Remove button added.
I've tried to put a very sample from here: https://codesandbox.io/s/react-final-form-field-arrays-wbhgq?fontsize=14
In that sample, <Form1 /> is actually the editor form. Once submitted, <Form2 /> will render with new fields updated.
If I reload the page, it works but of course this is not what it should have been.
What should I change to make my <Form2 /> update ?
Thanks in advance
I'm not sure if I understood you correctly but the main idea is to create a store for the initialValues using useState or state of class component
const App = () => {
const [initialValues, setInitialValues] = useState();
return (
<Styles>
<Form1 onSubmit={setInitialValues} />
<Form2 initialValues={initialValues} />
</Styles>
);
};
If it is not what you want to achieve explain it in details

React text form fields without onChange

Is there any way (please provide an example) in React / React Native to have a component render a timer with milliseconds, a submit button, and a text input field where the following conditions are met?
The user can type in the input field and see what he is typing.
No event handlers are assigned to the input field
When the submit button is clicked the program displays an alert() with the text typed by the user.
The component has an initial state value that is initially displayed in the input field.
The user does not experience unexpected behaviors while typing.
A previous question about this subject lead me to this more specific question about the matter (I hope you can see how it is related).
The most commonly accepted pattern in React to implement input fields suggest to always use an onChange event (see the docs), but I think this leads to repetition and noise in the code, so I´m looking for a better pattern where the developer doesn´t have to think about the onChange behavior when all he needs is an input form field.
Extra Note 1: An "state value" is a value in the component's state. i.e. "constructor(){ this.state = {value:'Initial Value'} };".
Extra Note 2: The purpose of the timer is to make sure you're triggering a render() periodically, which makes it a challenge to display the initial "state value", and allow the user to type normally without an onChange handler to update the state accordingly.
What are you looking for is called Uncontrolled Components.
Take a look here: https://reactjs.org/docs/uncontrolled-components.html
Your conditions will be met with this refs-based pattern ?
class App extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
}
handleSubmit = () => alert(this.textInput.getDOMNode().value);
render() {
return (
<div>
<textarea
ref={el => this.textInput = el}
>
My initial value
</textarea>
<button onClick={this.handleSubmit}type="button">Submit</button>
</div>
);
}
}
React.render(<App />, document.getElementById('app'));
<div id="app"></div>
Working codepen: https://codepen.io/anon/pen/roypOx
Because conditions are about only input field and not timers I've not included a timer in the example.

How do I go from one field to the next (without using TAB) in Redux-form 6?

I've got a form with three fields that make up a phone number input. It looks something like this:
<form>
<Field id="areaCode" name="areaCode" component={areaCode} max={3} type="text" />
<Field id="firstThree" name="firstThree" component={firstThree} max={3} type="text" />
<Field id="lastFour" name="lastFour" component={lastFour} max={4} type="text" />
</form>
The component for each Field looks like this (they are similar so I'll just show one to illustrate my point)
const areaCode = (field) => (
<input
{...field.input}
maxLength={field.max}
type="text"
onChange={(value) => {
// switch to next field (firstThree)
// after this field's length is >= 3
}}
/>
)
I want to automatically switch to the second field after the user has inputted 3 numbers in the first field. How does one switch to the next field programmatically?
I'm not sure how to reference the second field in the form to switch to when they blur away from the first field.
Am i doing this the right way? Should I be using Fields instead of Field?
Edit: To automatically switch to the next field upon hitting the maxLength, you could use onChange() and ref. The onChange() handler checks if the current input is at its max length. If it is, focus() on the next ref'd input on your react page.
Example: jsfiddle.net/4np9u17g/11
You should not need any sort of onBlur() function or have code to handle switching to the next input upon clicking tab. The browser will automatically focus on the input upon clicking tab.
It looks like you are using redux-form's Field correctly - you have defined a separate component for each part of the phone number, so you should use Field for each component (as you have already done). If, instead, you wanted to combine all of these inputs into one component, then you would need to use Fields. But, as you are now, you should be good.

Categories

Resources