React material-UI custom input for TextField - reactjs

I'm trying to integrate the material-UI TextField with react-payment-inputs library.
For example I use this library like this:
import {usePaymentInputs} from 'react-payment-inputs';
const { getCardNumberProps} = usePaymentInputs();
<input {...getCardNumberProps({
onChange: handleCardChange('number'),
onFocus: handleFocus('number'),
placeholder: ''
})}/>
I need to pass all input props using the react-payment-inputs library
I want to wrap this input with the nice TextField label effect.
I cannot see how can I send custom input element with custom props to TextField.
This is for example also not working:
<TextField label="First name"
InputProps={{
input: <input type="text" value={cardInfo.name}
onChange={handleFirstNameChange} onFocus={handleFocus('name')}/>
}}
/>
Here is the codesandbox

Related

minLength doesn't work in typescript, react

I have an input in Next, typescript. Maxlength does work but minlength doesn't work now. Does anyone how to validate this both?
Here's my code.
<input type="text" placeholder="text" required={true} minLength={2} maxLength={10} />
<button type="submit">Submit</button>
Your code is fine. However minlength works different than maxlength.
HTML maxlength prevents the user from typing keys more than the maxlength.
HTML minlength will let the user enter less keys compared to the requirement. After all, they need to be able to start from less chars to come up to more chars. That said the field will show an error if minlenght is not met.
Complete example
Use this component and press the enter key to play around with the input field:
export default function App() {
return (
<form>
<input type="text" placeholder="text" required={true} minLength={2} maxLength={10} />
<button type="submit">Submit</button>
</form>
);
}
Screenshots
Because its required:
Because minlenght is not met:
use can install Material ui Libraries npm install #material-ui/core Material ui Libraries
There have lots of components. use Textfield components . Using inputProps we set maxlength in textfield
<TextField inputProps={{ maxLength: 10 }} type="text" />
Material Ui Textfied Compoents

Use ant design input components with validation rules outside of an antd form

I don't want to use the antd Form component, but I do want to use the data entry components and I want to capture their styling when certain rules like required are not satisfied.
I am using react-hook-forms right now and I wrap a form element like
<FormContext>
<Controller
rules={{ required: 'Enter your name!' }}
name="name"
as={<Input />}
placeholder="name"/>
</FormContext>
In this manner, the rule validation does not get run.
If I change this to :
<Controller
rules={{ required: 'Enter your name!' }}
name="name"
as={<Input required />}
placeholder="name"/>
I get the default required styling on submission and things work.
If I do something like this:
<Controller
rules={[{ required:true }]}
name="name"
as={
<Form.Item >
<Input/>
<Form.Item>
}
placeholder=" name"/>
My default values that I send with a form context provider don't get recognized and data added isn't being registered through the Form.Item
I want to use the antd styling for this component separate from importing any antd Form specific code. Is there a way?

Material UI Autocomplete custom renderInput

I'm following various examples from https://material-ui.com/components/autocomplete/ to create a custom autocomplete. I'm trying to use the renderInput property to use a custom input component. All of the examples I find use the TextField component, but I'd like to use a regular input component.
Problem is, the options are never displayed. I've created a demonstration here (swap renderInput with renderInputWORKING to see working version):
https://codesandbox.io/s/epic-johnson-oxy7b?file=/src/App.tsx
with the following code in renderInput:
const renderInput = (params: AutocompleteRenderInputParams) => {
console.log(params);
const { InputLabelProps, inputProps, InputProps } = params;
return (
<div>
<label {...InputLabelProps}>foo</label>
<input {...InputProps} {...inputProps} />
</div>
);
};
How can I use the <input /> component for renderInput prop on <Autocomplete />?
UPDATE
The 4.10.1 release of Material-UI (on June 1, 2020) included a new example in the documentation for this exact case: https://material-ui.com/components/autocomplete/#custom-input.
Pull request: https://github.com/mui-org/material-ui/pull/21257
The most useful example to look at in the documentation is the Customized Autocomplete example which uses InputBase instead of TextField. This example contains the following code for renderInput:
renderInput={(params) => (
<InputBase
ref={params.InputProps.ref}
inputProps={params.inputProps}
autoFocus
className={classes.inputBase}
/>
)}
The InputProps passed to TextField are placed on a div that wraps the <input>, so most of those props are not appropriate to put directly on the <input> element as you were. In the code above from the documentation example, you can see that it only uses one thing from params.InputProps which is the ref. This ref is used for controlling the anchor element for the listbox of options. A ref is also placed on the <input> itself, but that ref is used for very different purposes. With your code, only one of those refs was getting used.
Below is a working example (based on the Combo Box example since your sandbox has a lot of other customizations that aren't directly related to this question) that uses <input> instead of TextField:
import React from "react";
import Autocomplete from "#material-ui/lab/Autocomplete";
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<div ref={params.InputProps.ref}>
<label {...params.InputLabelProps}>My Label </label>
<input {...params.inputProps} autoFocus />
</div>
)}
/>
);
}

Implement inputRef prop with Material UI TextField custom component

I'm trying to hook up Material UI TextField with an input component of my own. The code utilizing the TextField looks like this:
<Autocomplete
id="inputData"
options={inputData}
getOptionLabel={option => option.text}
renderInput={params => (
<TextField
{...params}
label="inputData"
InputProps={{
inputComponent: () => <Input name="inputData" />
}}
/>
)}
/>
and the Input component code is simple:
const Input = () => <input />
It will become more complicated but for now I'd like to get this simple code to work. The error I get is that inputRef.current is null which is probably caused by the lack of InputElement interface implementation in the Input component. Please see the Material UI docs below the code snippet for the info on InputElement interface. In other words my Input component doesn't handle the inputRef prop Material UI needs.
How do I properly integrate a custom Input component with Material UI TextField ?
Here's a Sandbox: https://codesandbox.io/s/fervent-bash-pxqq0.

How to use react-hook-form with ant design or material UI

I'm trying to use react-hook-form library to validate a form. When I render view using ant design or material UI, it does not work correctly.
<Input name="firstName" ref={register({ required: true })} />
{errors.firstName && 'First name is required'}
Some warning happened: "Missing name at.....".
For Material-UI you can pass register through the TextField component prop inputRef (I'm also using Yup for validation schemas)
import React, { useState } from 'react';
import { Button, TextField } from '#material-ui/core';
import useForm from 'react-hook-form';
import { object, string } from 'yup';
const Form: React.FC = () => {
const schema = object().shape({
username: string().required('Username is required'),
password: string().required('Password is required'),
});
const { register, handleSubmit, errors } = useForm({ validationSchema: schema });
const onSubmit = (data: any) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField
name="username"
error={!!errors.username}
label="Username"
helperText={errors.username ? errors.username.message : ''}
type="email"
inputRef={register}
fullWidth
/>
<TextField
name="password"
error={!!errors.password}
label="Password"
inputRef={register}
helperText={errors.password ? errors.password.message : ''}
type="password"
fullWidth
/>
<Button
color="primary"
type="submit"
variant="contained"
fullWidth
>
Submit
</Button>
</form>
);
};
react hook form author here. React Hook Form embrace uncontrolled components and native inputs, however it's hard to avoid working with external controlled component such as React-Select, AntD and Material-UI. So I have built a wrapper component to help you integrate easier.
https://github.com/react-hook-form/react-hook-form-input
Ok you may wonder what’s the point of doing this, and what are you gettin out from react hook form with controlled components? Firstly, you still benefit from our in build validation or schema validation at your choice. Secondary this will improve your app or form performance by isolating your input state update to itself, which means ur form root can be resulted with 0 re-render even with controlled component.
Here is codesandbox example:
https://codesandbox.io/s/react-hook-form-hookforminput-rzu9s
Hopefully those make sense and that extra component Which I have created helps you too.
On top this, i have also built a wrapper component to make things a bit easier:
import React from 'react';
import useForm from 'react-hook-form';
import { RHFInput } from 'react-hook-form-input';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
function App() {
const { handleSubmit, register, setValue, reset } = useForm();
return (
<form onSubmit={handleSubmit(data => console.log(data))}>
<RHFInput
as={<Select options={options} />}
rules={{ required: true }}
name="reactSelect"
register={register}
setValue={setValue}
/>
<button
type="button"
onClick={() => {
reset({
reactSelect: '',
});
}}
>
Reset Form
</button>
<button>submit</button>
</form>
);
}
https://github.com/react-hook-form/react-hook-form-input
update
React-hook-form v4, react-hook-form-input has been merged into the main repo and renamed to Controller.
https://react-hook-form.com/api#Controller
The latest advice for V4 is to use the built-in <Controller /> component (docs). You don't need to install the extra dependency of react-hook-form-input.
From the README.md of react-hook-form-input:
This component is now a part of React Hook Form V4, and renamed to Controller with much simpler API.
Example:
<Controller
as={<TextField />}
name="firstName"
control={control}
defaultValue=""
/>
Note that the #Bill, the author of the accepted answer, now also says that the answer is outdated and to "please use controller instead."
Using the inputRef should be enough to the TextField component and for any default value the react-hook-form (useForm) provide the defaultValue in case that you want to use some default value or material-ui has the defaultValue in their TextField API
const { register, handleSubmit, errors, watch } = useForm({ mode: 'onChange' });
<TextField
inputRef={register({ required: true })}
label="Email Address"
name="email"
type="email"
autoComplete="email"
onChange={handleUpdate}
error={errors.email}
helperText={errors.email && 'email required'}
/>
I've had 0 issues using the TextField inputRef approach that some others have mentioned.
<TextField
inputRef={register}
id="name"
name="name"
/>
I posted a full working version here: https://seanconnolly.dev/react-hook-form-material-ui

Resources