[Dialog] Bad repositioning when closing keyboard after editing a TextField on mobile
See original GitHub issueProblem Description
Hello!
So, I found the following issue: on mobile phone, when I fill a TextField inside a Dialog, I have a weird behavior appearing:
- The Dialog opens up with a TextField, everything looks good;
- When I click on the TextField, the keyboard opens up normally and the Dialog is resized as intended.
- Then, when I close the keyboard, the Dialog is not re positioned correctly, it is positioned as follows:
The code for the Dialog is the following:
import React from 'react'
import Component from 'react/lib/ReactComponent'
import PureRenderMixin from 'react-addons-pure-render-mixin'
import Moment from 'moment'
import { Map, fromJS } from 'immutable'
import Dialog from 'material-ui/Dialog'
import FlatButton from 'material-ui/FlatButton'
import RaisedButton from 'material-ui/RaisedButton'
import FloatingActionButton from 'material-ui/FloatingActionButton'
import ContentAdd from 'material-ui/svg-icons/content/add'
import TextField from 'material-ui/TextField'
import SelectField from 'material-ui/SelectField'
import MenuItem from 'material-ui/MenuItem'
import DatePicker from 'material-ui/DatePicker/DatePicker'
import TimePicker from 'material-ui/TimePicker/TimePicker'
import AutoComplete from 'material-ui/AutoComplete'
import Divider from 'material-ui/Divider'
import * as Colors from 'material-ui/styles/colors'
import { categories, minDate, maxDate } from './Event'
const createStyle = {
position: 'fixed'
,right: 16
,bottom: 16
,zIndex: 100
}
const dialogStyle = {
width: '90%'
,minWidth: '320px'
,maxWidth: '1080px'
}
export default class CreateEvent extends Component {
constructor(props) {
super(props)
this.shouldComponentUpdate = PureRenderMixin
.shouldComponentUpdate.bind(this)
this.state = {
open: false
,owner: this.props.owner
,name: this.props.name
,startDay: this.props.startTime
,startTime: this.props.startTime
,endDay: this.props.endTime
,endTime: this.props.endTime
,description: this.props.description
,location: this.props.location
,category: this.props.category
,nameError: null
,startDayError: null
,startTimeError: null
,endDayError: null
,endTimeError: null
,descriptionError: null
,locationError: null
,categoryError: null
}}
componentWillReceiveProps(newProps) {
if (newProps.owner !== this.state.owner) {
this.setState({ owner: newProps.owner });
}
}
handleOpen() {
this.setState({ open: true })
}
handleOk() {
const fields = fromJS({
name: 'name'
,startDay: 'starting day'
,startTime: 'starting time'
,endDay: 'ending day'
,endTime: 'ending time'
,description: 'description'
,location: 'location'
,category: 'category'
})
const valid = fields.keySeq().reduce((valid, field) => {
if (!this.state[field] || this.state[field] === '') {
this.setState({
[field + 'Error']: 'The event ' + fields.get(field) +
' cannot be empty'
})
return false
}
return valid
}, true)
if (valid) {
const event = fromJS({
name: this.state.name
,startTime: Moment(
Moment(this.state.startDay).format('YYYY-MM-DD ') +
Moment(this.state.startTime).format('HH:mm:ss')
,'YYYY-MM-DD HH:mm:ss'
)
,endTime: Moment(
Moment(this.state.endDay).format('YYYY-MM-DD ') +
Moment(this.state.endTime).format('HH:mm:ss')
,'YYYY-MM-DD HH:mm:ss'
)
,owner: this.state.owner
,description: this.state.description
,location: this.state.location
,category: this.state.category.get('name')
})
if (event.get('endTime') > event.get('startTime')) {
(this.props.create) ?
this.props.postEvent(event) :
this.props.updateEvent(event, this.props.eventId)
this.setState({open: false})
} else {
this.setState({
endDayError: 'The ending day should be after the starting day'
,endTimeError: 'The ending time should be after the starting time'
})
}
}
}
handleCancel() {
this.setState({open: false})
}
handleNameChange(event) {
this.setState({
nameError: null
,name: event.target.value
})
}
handleLocationChange(text) {
this.setState({
locationError: null
,location: text
})
}
handleCategoryChange(event, index, value) {
this.setState({
categoryError: null
,category: value
})
}
handleStartDayChange(event, time) {
this.setState({
startDayError: null
,startDay: time
})
}
handleStartTimeChange(event, time) {
this.setState({
startTimeError: null
,startTime: time
})
}
handleEndDayChange(event, time) {
this.setState({
endDayError: null
,endDay: time
})
}
handleEndTimeChange(event, time) {
this.setState({
endTimeError: null
,endTime: time
})
}
handleDescriptionChange(event) {
this.setState({
descriptionError: null
,description: event.target.value
})
}
render() {
const actions = [
<FlatButton
label="Ok"
primary={true}
onTouchTap={::this.handleOk}
/>
,<FlatButton
label="Cancel"
secondary={true}
onTouchTap={::this.handleCancel}
/>
]
return (
<div>
{(this.props.create) ? (
<FloatingActionButton
style={createStyle}
backgroundColor={Colors.deepOrange700}
onTouchTap={::this.handleOpen}
>
<ContentAdd />
</FloatingActionButton>
) : (
<RaisedButton
label="Edit"
fullWidth={true}
primary={true}
onTouchTap={::this.handleOpen}
/>
)}
<Dialog
title={
(
(this.props.create) ?
"Create a new" :
"Edit " + ((this.props.isOwner) ? "your" : "this")
) +
" awesome event!"
}
titleStyle={(this.state.category) ?
{backgroundColor: this.state.category.get('bgColor') || 'white'} :
null}
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={::this.handleCancel}
contentStyle={dialogStyle}
autoScrollBodyContent={true}
>
<TextField
hintText='Event title'
value={this.state.name}
errorText={this.state.nameError}
fullWidth={true}
onChange={::this.handleNameChange}
disabled={!this.props.isOwner && !this.props.create}
/>
<div className='container-fluid'>
<div className='col-sm-6 col-xs-12'>
<AutoComplete
hintText="Location"
errorText={this.state.locationError}
dataSource={[]}
onUpdateInput={::this.handleLocationChange}
searchText={this.state.location}
fullWidth={true}
/>
</div>
<div className='col-sm-6 col-xs-12'>
<SelectField
floatingLabelText="Category"
errorText={this.state.categoryError}
onChange={::this.handleCategoryChange}
value={this.state.category}
disabled={!this.props.isOwner && !this.props.create}
fullWidth={true}
labelStyle={(this.state.category) ?
{color: this.state.category.get('color') || 'white'} :
null}
>
{categories.map((category, index) => (
<MenuItem
key={index}
style={{color: category.get('color')}}
value={category}
primaryText={category.get('name')}
/>
))}
</SelectField>
</div>
</div>
<div className='col-sm-7 col-xs-12'>
<DatePicker
minDate={minDate}
maxDate={maxDate}
defaultDate={minDate}
disableYearSelection={true}
hintText="Start day"
errorText={this.state.startDayError}
fullWidth={true}
onChange={::this.handleStartDayChange}
value={this.state.startDay}
/>
</div>
<div className='col-sm-5 col-xs-offset-2 col-xs-10'>
<TimePicker
format='24hr'
hintText="Start time"
errorText={this.state.startTimeError}
fullWidth={true}
onChange={::this.handleStartTimeChange}
value={this.state.startTime}
/>
</div>
<div className='col-sm-7 col-xs-12'>
<DatePicker
minDate={minDate}
maxDate={maxDate}
defaultDate={maxDate}
disableYearSelection={true}
hintText="End day"
errorText={this.state.endDayError}
fullWidth={true}
onChange={::this.handleEndDayChange}
value={this.state.endDay}
/>
</div>
<div className='col-sm-5 col-xs-offset-2 col-xs-10'>
<TimePicker
format='24hr'
hintText="End time"
errorText={this.state.endTimeError}
fullWidth={true}
onChange={::this.handleEndTimeChange}
value={this.state.endTime}
/>
</div>
<TextField
hintText='Description'
errorText={this.state.descriptionError}
fullWidth={true}
multiLine={true}
onChange={::this.handleDescriptionChange}
value={this.state.description}
disabled={!this.props.isOwner && !this.props.create}
/>
</Dialog>
</div>
)
}
}
Versions
- Material-UI: 0.15.0-beta.1
- React: 15.0.1
- Browser: Chrome on Android (OnePlus Two)
Issue Analytics
- State:
- Created 7 years ago
- Comments:8 (3 by maintainers)
Top Results From Across the Web
[Dialog] Bad repositioning when closing keyboard after ...
Hello! So, I found the following issue: on mobile phone, when I fill a TextField inside a Dialog, I have a weird behavior...
Read more >Android - prevent dialog dimiss closing soft keyboard
I am attempting to force the soft keyboard to display when an EditText gains focus, despite whether or not the user clicked on...
Read more >jQMobile re-positions popup every time when Android ...
I've developed a PhoneGap app using Jquery Mobile 1.4.3 . My login page is a popup. And I faced with an endless process...
Read more >PySimpleGUI
A line of text, a line of text and an input area, and finally ok and cancel buttons. This makes the coding process...
Read more >Toolbar Panels & Icons
Editing the Tool Bar - The panels and Icons can be reordered in any way, undocked and docked to the top or bottom...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Try to add
repositionOnUpdate={false}
toDialog
component.We’ve had huge problems with this and generally responsiveness of Dialog. Especially when opening keyboard on mobile devices. We are writing application that is responsive and should works on every device. Second problem is that the gap between top screen and the top of dialog. It stays same for small devices.
For example in angular implementation it is smaller when the window height is smaller.

As a workaround we did some css tricks and we maximize it for small devices and it works well for mobile devices.
I expected similar behavior from mui’s Dialog. It should occupy almost 100% of visible place on small devices to works well.