I have a form using Material-ui TextField and I'm translating all my fields like this :
<TextField autoFocus={true} name='formName'
placeholder={this.context.intl.formatMessage( translations.formNameInputPlaceholder )}
value={value || ''}
fullWidth={true}
errorText={ this.shouldShowError( fieldValidity ) ? <FormattedMessage { ...translations.notValid} /> : null }
onChange={ e => onChange( e.target.value ) }/>
however errorText is never translated and keeps using default locale.
Ok this problem was solved in react 15.2.1
https://github.com/callemall/material-ui/issues/2494
Related
Basically I have a function onBlur that fetches some data, then I place the data into some fields that are being controlled with react-hook-form.
Everything but selects are being set, I don't know if there's something wrong with the libs, or it's just me not doing it right.
This would be the flow:
Filling up the CEP Field would return an object (1st is the object that returns,2nd is the object that should be set on the Form):
This is how the form data is set after the data fetch:
addressReset({
cep: res.cep,
bairro: res.bairro,
localidade: res.localidade,
address: res.logradouro,
uf: res.uf,
});
And this would be my controller component:
<Controller
control={control}
name={name}
render={({ field }) => (
<TextField
{...field}
disabled={disabled && true}
select={select ? true : false}
fullWidth={fullWidth ? true : false}
autoComplete={name}
type={type}
label={label}
error={Boolean(errors[name])}
helperText={errors[name] ? errors[name].message : ""}
variant="outlined"
required={required ? true : false}
id={name}
name={name}
InputLabelProps={InputLabelProps}
InputProps={InputProps}
size={size}
onBlur={onBlur}
>
{children && children}
</TextField>
)}
/>
It takes some props, but more importantly it's name is uf, I don't see anything wrong here.
On a Select component you need to pass an object with keys label and value.
https://mui.com/api/select/
I have tried a couple of ways in order to make the material UI's autocomplete field of type required but I am not getting the behavior that I wanted. I had encapsulated my field inside react hook form <Controller/> yet no luck. I want to trigger message 'Field is mandatory' on submit when nothing is added to the field.
Below is the code snippet, I have not removed comments so that it becomes a bit easier for others to understand the approach that I had followed earlier -
<Controller
name="displayName"
as={
<Autocomplete
value={lists}
multiple
fullWidth
size="small"
limitTags={1}
id="multiple-limit-lists"
options={moduleList}
getOptionLabel={(option) => option.displayName}
renderInput={(params,props) => {
return (
<div>
<div className="container">
<TextValidator {...params} variant="outlined" label="Display Name*" className="Display Text"
name="displayName" id="outlined-multiline-static"
placeholder="Enter Display-Name" size="small"
onChange={handleDisplay}
// validators={['required']} this and below line does throw a validation but the problem is this validation stays on the screen when user selects something in the autocomplete field which is wrong.
// errorMessages={['This field is required']}
// withRequiredValidator
/>
</div>
</div>
)
}}
/>
}
// onChange={handleDisplay}
control={control}
rules={{ required: true }}
// required
// defaultValue={options[0]}
/>
<ErrorMessage errors={errors} name="displayName" message="This is required" />
You can use the following logic to get it worked. Though this might not be the best solution but works.
<Autocomplete
renderInput={(params) => (
<TextField
{...params}
label={value.length === 0 ? title : title + " *"} //handle required mark(*) on label
required={value.length === 0}
/>
)}
/>
I tried using the built in required in textfield for autocomplete, and it works like a charm. Maybe you can use this as a reference.
<Autocomplete
renderInput={(params) => {
<TextField {...params} required />
}
// Other codes
/>
Since you are rendering <TextValidator>, you should apply mandatory(required) attribute to that component not on <AutomComplete>.
Try this if your Material UI version is v5
<TextField
{...params}
required
label="Tags"
value={value}
InputProps={{
...params.InputProps,
required: value.length === 0,
}}
/>
I have set up the following form using Formik:
const RenderForm = ({ errors, isSubmitting, isValid, touched }) => {
return (
<Form>
<h3>Sign Up</h3>
<Email
name="email"
error={touched.email && errors.email ? 'error' : null}
/>
<Password
name="password"
error={touched.password && errors.password ? 'error' : null}
/>
<Button disabled={!isValid || isSubmitting} type="submit">
Submit
</Button>
{/* {errors.firebaseErrorMessage && ( */}
{/* <Help>{errors.firebaseErrorMessage}</Help> */}
{/* )} */}
</Form>
)
}
The Email component and the Password components are just wrappers for the Formik Field Component. I want to be able to add a red border a particular field if it fails validation.
To do that, I have set up a conditional for the error prop. IF it is touched AND IF the error is passed, then it renders that prop with a value of 'error'.
Now there are a few problems with this.
FIRST PROBLEM
I don't need to render a value of 'error' (or any other value) to the error attribute. I just need to have the attribute 'error' itself (without any value) and then it will be styled appropriately.
SECOND PROBLEM
It's a bit annoying to write out the same conditional test for each field. I would like to know if there is something like the ErrorMessage component, except for a prop. Basically, something like this:
<Email name="email" errorProp />
<Password name="password" errorProp />
The idea being that errorProp will set an attribute of 'error' if an error exists and nothing if an error does not exist.
So here is my question...
How can I create my own errorProp or, at the very least, simplify what I am trying to do?
Thanks.
I have a textfield variant outlined, and there I have a dynamic label, the problem is that when it changes the top line in width remains the same as the first time
<TextField
id="debtorIin"
name="debtorIin"
label={debtorType === "pvt" ? "Ф.И.О.:" : "Наименование организации:"}
disabled={debtorFullInfo && true}
className={classes.textField}
value={debtorIin}
helperText={touched.debtorIin ? errors.debtorIin : ""}
error={touched.debtorIin && Boolean(errors.debtorIin)}
onChange={change.bind(null, "debtorIin")}
margin="normal"
variant="outlined"
/>
(source: imggmi.com)
(source: imggmi.com)
I think it happens because it won't recalculate the width on property change, you can solve that by creating two different TextField for it.
First, you need one that contains all the common props.
const MyTexField = ({ label, ...props }) => (
<TextField
id="debtorIin"
name="debtorIin"
label={props.label}
disabled={props.debtorFullInfo && true}
className={props.classes.textField}
value={props.debtorIin}
helperText={props.touched.debtorIin ? props.errors.debtorIin : ""}
error={props.touched.debtorIin && Boolean(props.errors.debtorIin)}
onChange={change.bind(null, "debtorIin")}
margin="normal"
variant="outlined"
/>
);
Then, you can use that component:
<MyTextField label="Ф.И.О.:" {...props} />
I have a TextField for phone numbers in a short form. And then i want to mask this form field like (0)xxx xxx xx xx.
I'm trying to use react-input-mask plugin with Material-UI. But if i want to change input value, this is not updating the my main TextField.
<TextField
ref="phone"
name="phone"
type="text"
value={this.state.phone}
onChange={this.onChange}
>
<InputMask value={this.state.phone} onChange={this.onChange} mask="(0)999 999 99 99" maskChar=" " />
</TextField>
Actually, I couldn't find any documentation for masking with Material-UI. I'm trying to figure out how can i use with another plugins.
Update
versions: material-ui 0.20.2, react-input-mask 2.0.4
Seems like the API changed a bit:
<InputMask
mask="(0)999 999 99 99"
value={this.state.phone}
disabled={false}
maskChar=" "
>
{() => <TextField />}
</InputMask>
Demo
Original
This should do the trick:
<TextField
ref="phone"
name="phone"
type="text"
value={this.state.phone}
onChange={this.onChange}
>
<InputMask mask="(0)999 999 99 99" maskChar=" " />
</TextField>
Demo:
For current version of Material-UI and react-input-mask, the following answer worked:
<InputMask
mask="(1)999 999 9999"
value={self.state.inputValue}
onChange={this.getTextFieldValue}
className={this.props.classes.textField}
>
{() => <TextField
id={attribute}
label={attribute}
name={attribute}
className={this.props.classes.textField}
margin="normal"
type="text"
/>}
</InputMask>
This is valid for current version of react-input-mask and material-ui:
<InputMask
mask="(0)999 999 99 99"
value={this.state.phone}
onChange={this.onChange}
>
{() => <TextField />}
</InputMask>
Question:
codesandbox.io/s/q8v1259oq6 please check this my label test floatingLabelText is hidden How I solve. – Thilina Sampath
Work Around:
You can controll Label Position with "floatingLabelFixed" prop. At your handleChange look to state input value.
...when create with value:
constructor(props) {
super(props);
let value = props && props.value ? props.value : '';
let floatingLabelFixed = !!value;
this.state = {
value,
floatingLabelFixed,
};
this.handleChange = this.handleChange.bind(this);
}
...when edit (onChange):
handleChange(event) {
let value = event && event.target && event.target.value ? event.target.value : '';
let floatingLabelFixed = !!value;
this.setState({
value,
floatingLabelFixed
});
}
...your input:
<TextField
onChange={this.handleChange}
value={this.state.value}
floatingLabelFixed={this.state.floatingLabelFixed}/>
You can also use https://github.com/text-mask/text-mask. Seems like a solid project, even though it is not maintained anymore.
It provides a demo page for testing stuff and some addons that I successfully used to create a custom price input field (with material ui TextField component).
There's also an example codesandbox that I found somethere in the docs page, I believe.
Copy/pasting the codesandbox example here (you would need to adjust the mask to your needs):
// ... React imports.
import MaskedInput from "react-text-mask";
import createAutoCorrectedDatePipe from "text-mask-addons/dist/createAutoCorrectedDatePipe";
const autoCorrectedDatePipe = createAutoCorrectedDatePipe("mm/dd/yyyy", {
minYear: 1900,
maxYear: 2099
});
function TextMaskCustom(props) {
const { inputRef, ...other } = props;
return (
<MaskedInput
{...other}
ref={ref => {
inputRef(ref ? ref.inputElement : null);
}}
mask={[/\d/, /\d/, "/", /\d/, /\d/, "/", /\d/, /\d/, /\d/, /\d/]}
placeholderChar={"\u2000"}
pipe={autoCorrectedDatePipe}
guide
keepCharPositions
/>
);
}
// ...
<div>
<TextField
label="react-text-mask"
value={values.textmask}
onChange={handleChange("textmask")}
InputProps={{
inputComponent: TextMaskCustom
}}
helperText="mm/dd/yyyy"
variant="outlined"
margin="dense"
/>
</div>
<InputMask
mask="99999" // Format you need implemented
value={cellNumber}
onChange={this.inputHandler}
placeholder="Cell Number"
name="cellNumber"
required disableUnderline
style={style.inputfeild}
maskChar= {'_'}> // To display when there is no character typed
{(inputProps) =>
<Input {...inputProps}/>}
</InputMask>
Just provide all your props to InputMask and then pass them as input props to the call back method in which you display your Textfield or Input field and it should work just fine.