admin管理员组文章数量:1134553
I'm using Material UI in a React application and trying to implement an entity update page. In this, we would need to set the exiting values of the entity to let the user update them. The existing values have been set using the defaultValue attribute of the input fields:
<div className="input-field">
<input type="text" name="name" ref="name" defaultValue={this.state.name} />
<label htmlFor="name" >Name</label>
</div>
With this approach, the intended functionality works fine. However, the labels of all text fields overlaps with their values. Please see below screenshot:
If I click on each field, the label moves up as expected. However, at the page load, labels do not move up. I tried using the value attribute of the input fields together with the onChange() event handler but experienced the same problem. Really, appreciate your thoughts on this.
The complete source code of this application can be found here:
This particular page can be found here: .js
Github Issue:
I'm using Material UI in a React application and trying to implement an entity update page. In this, we would need to set the exiting values of the entity to let the user update them. The existing values have been set using the defaultValue attribute of the input fields:
<div className="input-field">
<input type="text" name="name" ref="name" defaultValue={this.state.name} />
<label htmlFor="name" >Name</label>
</div>
With this approach, the intended functionality works fine. However, the labels of all text fields overlaps with their values. Please see below screenshot:
If I click on each field, the label moves up as expected. However, at the page load, labels do not move up. I tried using the value attribute of the input fields together with the onChange() event handler but experienced the same problem. Really, appreciate your thoughts on this.
The complete source code of this application can be found here: https://github.com/imesh/react-examples/tree/master/meetups/meetups-web-client
This particular page can be found here: https://github.com/imesh/react-examples/blob/master/meetups/meetups-web-client/src/components/UpdateMeetup.js
Github Issue: https://github.com/Dogfalo/materialize/issues/5995
Share Improve this question edited Dec 13, 2020 at 8:13 Sultan Aslam 6,2182 gold badges40 silver badges48 bronze badges asked Jun 20, 2018 at 19:21 imeshimesh 1,6341 gold badge18 silver badges18 bronze badges 5- could you confirm you see the same glitch in this sandbox codesandbox.io/s/rwyj71lvx4 ? – Evgeny Timoshenko Commented Jun 20, 2018 at 20:12
- Thanks Evgeny for the quick response! Yes, I could see the same issue in the above sandbox. However, I found a workaround. Adding class active to the labels solved the problem. Thanks! – imesh Commented Jun 21, 2018 at 8:48
- Still I see the problem when the page is refreshed or rather if directly opened the update page URL. The problem does not occur if navigated through a React Link. – imesh Commented Jun 21, 2018 at 8:54
- I can see correct labels in chrome and ff on windows. can it be browser related? – Evgeny Timoshenko Commented Jun 21, 2018 at 8:58
- So is it materialize or material-ui? – Marson Mao Commented Jun 21, 2018 at 10:18
17 Answers
Reset to default 132This is due to the undefined state of the value.
This workaround works for me as a fallback:
value= this.state.name || '';
e.g. for Material-UI
<div className="input-field">
<input type="text" name="name" ref="name" value={this.state.name || ''} />
<label htmlFor="name">Name</label>
</div>
InputLabel has a prop shrink
. you can use in TextField like below:
<TextField
// ... rest
InputLabelProps={{ shrink: true }}
/>
OR
<TextField
// ... rest
InputLabelProps={{ shrink: !!this.state.name }}
/>
I fixed it by adding the condition on shrink based on a text field value.
Just add this code in the text field: Updated (2022)
InputLabelProps={{ shrink: field.value }}
Example:
<Controller
name="formatted_phone_number"
control={control}
render={({ field }) => (
<TextField
{...field}
className=""
id="formatted_phone_number"
label="Phone"
type="text"
variant="outlined"
fullWidth
InputLabelProps={{ shrink: field.value }}
/>
)}
/>
I solved this by using a condition if it is not null && undefined then assign the value otherwise "". Here use the Formik
<TextField
type="text"
label="Ending Month"
variant="outlined"
fullWidth
size="small"
name="endingMonth"
value={values.endingMonth ?? ""}
helperText={touched.endingMonth && errors.endingMonth}
error={Boolean(touched.endingMonth && errors.endingMonth)}
/>
I had the same issue; however it was inconsistent - meaning sometimes I have the labels displayed properly and sometimes overlapped
I tried the following and it worked fine. Basically the form is first rendered empty without data; then the useEffect was fetching the data and populating the data. I set a isLoading state variable - this will be initially set to true and set to false after the data is fetched by API.
Display all the data only after isLoading is false - this works well.
Code Snippet
export default function UserProfile(props) {
const classes = useStyles();
const [user, setUser] = React.useState({});
const [isLoading, setIsLoading] = React.useState(true);
const getUser = async () => {
const requestOptions = {
method: 'GET',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
};
const response = await axios.request(
"/api/userprofile",
requestOptions
);
const responseData = await response.data;
setUser( responseData.userProfile );
setIsLoading(false);
}
React.useEffect(() =>{
getUser();
console.log(user);
})
return(
<div style={{padding:"10px"}}>
<Grid container className={classes.card}>
<Container component="main" maxWidth="xs">
<>{ isLoading ? <div> </div> :
<div className={classes.paper}>
<Typography variant="h6">User Profile</Typography>
<TextField
key="Name"
variant="outlined"
margin="normal"
fullWidth
id="Name"
label="Name"
value={user.name}
InputProps={{
readOnly: true,
}}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="email"
label="Email Address"
value={user.email}
InputProps={{
readOnly: true,
}}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="phone"
label="Phone"
value={user.phone_number}
InputProps={{
readOnly: true,
}}
/>
</div>
}</>
</Container>
</Grid>
</div>
);
}
It's 2022 and I still have this error; I have changed the wrapper element around TextField
component from grid
to div
and it solved the issues for me.
I have been trying to resolve this for my login page and it got resolved using these. Just add : For Username :
<TextField
// ... rest
InputLabelProps={{ shrink: true }}
/>
For Password Feild :
<InputLabel shrink={true}
>Password</InputLabel>
I had this problem but I solved it by adding shrink
return (
<Controller
name={name}
control={control}
defaultValue={defaultValue || ''}
render={({ field, fieldState: { error } }) => (
<TextField
{...field}
select
fullWidth
label={label}
value={field.value || ''}
SelectProps={{ native: true, defaultValue: defaultValue || '' }}
InputLabelProps={{ shrink: field.value }}
error={!!error}
helperText={error?.message}
{...other}
>
{children}
</TextField>
)}
/>
);
**Solution 1:** Set Shrink Attribute Based on Field Value if you want to move the label to outline only when it has value
<TextField
**key="title"**
required
id="title"
label="Story Title"
name="title"
fullWidth
value={this.state.title}
InputLabelProps={{
shrink: this.state.title?true:false,
}}
/>
Solution 2: Set Shrink attribute as true If you are fine to display the label always at the outline of TextBox
<TextField
id="outlined-number"
label="Number"
type="number"
**InputLabelProps={{
shrink: true,
}}**
/>
I can say whatever works for me try this out .
This is for Functional based Component.
const Example = () =>{
const [name, setName] = useState("");
const editName = (name) =>{
setName(name);
}
return(
<TextField
required
variant="outlined"
margin="normal"
fullWidth
value={name}
onChange={e => setName(e.target.value)}
label="Enter Name"
/>
)
}
Below worked:
<InputLabel shrink={true}>Select A Role</InputLabel>
InputLabelProps
gave error in functional component in react.
Utilizing InputLabelProps={{shrink: true}}, you can add a state and an onSelect to toggle the shrink state
const [shrink1, setShrink1] = useState(false)
<TextField
fullWidth
id='filled-basic'
label='Name'
variant='filled'
value={formState.name}
onChange={(event) => setFormState({ name: event.target.value })}
onSelect={() => setShrink1(true)}
InputLabelProps={{ shrink: shrink1 }}
/>
My RHF hook for MUI:
// hooks.js
function useMUI(useFormObject) {
const register = (name, options) => ({
...useFormObject.register(name, options),
InputLabelProps:{ shrink:!!useFormObject.watch(name) }
});
return {
...useFormObject,
register
};
}
Usage example:
const { register, handleSubmit } = useMUI(useForm());
return (
<TextField label="First name" {...register('firstName')} />
);
Result:
I made it work by setting the value to null
for the first render when the state value is undefined.
Here's an example:
<TextField
label={errors.email || "Email"}
name={'adminEmail'}
error={!!errors.email}
onChange={handleChange}
value={values.email || null}
variant="outlined"
className={`mb-8 `}
autoComplete="new-password"
/>
After lot research I found solution. In input styles please use marginTop:10, Below I have added code snippet.
<TextInput
label="Description"
variant="standard"
value={descTextValue}
inputStyle={{
marginTop:10
}}
onChangeText={value => setDescTextValue(value)}
color="#B3B3B3"
multiline
numberOfLines={4}
maxLength={250}
/>
I hope it will works.
10/2024 answer
Your label doesn't move up because the label can't determine whether it should move out of the way (shrink). To tell the label to shrink, you can assign the truthiness of this.state.name
to the shrink
prop like this:
<div className="input-field">
<input type="text" name="name" ref="name" defaultValue={this.state.name} />
<label htmlFor="name" shrink={!!this.state.name}>Name</label>
</div>
Assuming Materialize is converting label
to InputLabel
this will work.
The !!
is a common way to get the truthiness of a value (the first !
(logical NOT) operator converts the value to its boolean opposite, the second !
(logical NOT) operator converts it back to the original boolean value).
More info on label shrinking in the Material UI docs: https://mui.com/material-ui/react-text-field/#shrink
If you were using Material UI directly (which is a more common scenario), you would have a TextField
component and tell the label to move in the same way as above:
<TextField
label="Name"
variant="outlined"
name="name"
defaultValue={this.state.name}
slotProps={{ inputLabel: { shrink: !!this.state.name } }}
/>
You may be wondering what slotProps
is. Because the TextField
component is made up of sub-components (Input
, InputLabel
, FormHelperText
etc), you have to specify that it's the InputLabel
that you want to add the shrink
prop to. Each sub-component of TextField
is referred to as a 'slot', hence the name slotProps
. This is the current recommended way to pass props to Material UI sub-components.
More info on slotProps in the Material UI docs: https://mui.com/material-ui/api/text-field/#text-field-prop-slotProps
If you are using Material UI's TextField and the label overlaps with the value when the field is filled, it is usually because the variant of the TextField is not set. By default, the label is positioned above the field for the "outlined" or "filled" variants.
To fix this, simply add the variant prop to your TextField:
variant="outlined" // Use "outlined" or "filled" variant to prevent label overlap
本文标签: javascriptReact Material UI Label Overlaps with TextStack Overflow
版权声明:本文标题:javascript - React Material UI Label Overlaps with Text - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736779770a1952531.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论