This is a migrated thread and some comments may be shown as answers.

datePicker acting odd when passed onBlur and onFocus

5 Answers 6086 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Jason
Top achievements
Rank 1
Jason asked on 10 Jan 2020, 09:07 PM

When I add onBlur and onFocus with setStates to datePicker in the blitz demo provided for the component I was able to create an infinite loop  with this code 

https://zvfckz.run.stackblitz.io/

-Steps to reproduce with following code, click outside component of opened one so they are all close
-Click on Format and WeekColumn calendar icon to have it open and then click Default Show(edited) icon and this will create an infinite loop

This create a setState loop but I am curious to why as these component are separate.

5 Answers, 1 is accepted

Sort by
0
Jason
Top achievements
Rank 1
answered on 10 Jan 2020, 09:17 PM
// if link does not work here is the code

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DatePicker,DateTimePicker } from '@progress/kendo-react-dateinputs';
import { DropDownList } from '@progress/kendo-react-dropdowns';
import { IntlProvider, load, loadMessages, LocalizationProvider } from '@progress/kendo-react-intl';
import likelySubtags from 'cldr-core/supplemental/likelySubtags.json';
import currencyData from 'cldr-core/supplemental/currencyData.json';
import weekData from 'cldr-core/supplemental/weekData.json';
import numbers from 'cldr-numbers-full/main/es/numbers.json';
import caGregorian from 'cldr-dates-full/main/es/ca-gregorian.json';
import dateFields from 'cldr-dates-full/main/es/dateFields.json';
import timeZoneNames from 'cldr-dates-full/main/es/timeZoneNames.json';
load(
    likelySubtags,
    currencyData,
    weekData, numbers,
    caGregorian,
    dateFields,
    timeZoneNames
);
import esMessages from './es.json';
loadMessages(esMessages, 'es-ES');
class App extends React.Component {
    locales = [
        {
            language: 'en-US',
            locale: 'en'
        },
        {
            language: 'es-ES',
            locale: 'es'
        }
    ]
    state = { selectedLocale: this.locales[0], value: new Date(),showIt:true };
    render() {
        return (
            <LocalizationProvider language={this.state.selectedLocale.language}>
                <IntlProvider locale={this.state.selectedLocale.locale}>
                    <div className="example-wrapper row">
                        <div className="col-xs-12 col-md-12 example-config">
                            <h6>Locale: <DropDownList
                                value={this.state.selectedLocale}
                                data={this.locales}
                                textField={'locale'}
                                onChange={(e) => {
                                    this.setState({ selectedLocale: e.target.value });
                                }}
                                />
                            </h6>
                        </div>
                        <div className="col-xs-12 col-md-6 example-col">
                            <p>Default Show</p>
                            <DateTimePicker value={this.state.value} show={this.state.showIt}
                            onFocus={()=>{this.setState({showIt:true})}}
                            onBlur={()=>{this.setState({showIt:false})}}
                            onChange={(e)=>{this.setState({value:e.target.value})}}/>
                            <p>Format and WeekColumn</p>
                            <DatePicker defaultValue={new Date()} format="dd/MMM/yyyy" weekNumber={true} />
                            <p>Disabled</p>
                            <DatePicker disabled defaultValue={new Date()} format="dd/MMMM/yyyy" />
                        </div>
                    </div>
                </IntlProvider>
            </LocalizationProvider>
        );
    }
}
ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);
0
Stefan
Telerik team
answered on 13 Jan 2020, 12:26 PM

Hello, Jason,

Thank you for your example.

The issue occurs because when the second DatePicker is opened its Calendar is also focused. This caused the first DatePicker to blur and starts the endless loop.

This could be resolved by using a custom Calendar in the second DatePicker that will not focus automatically

https://stackblitz.com/edit/react-rps4zt-uq9mkx?file=app/main.jsx

In general, we do not recommend using the focus and blur events for opening and closing the DatePicker as they are synchronous events and cause different issues.

Please let me know the main desired result as we may be able to suggest an alternative approach.

Regards,
Stefan
Progress Telerik

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Jason
Top achievements
Rank 1
answered on 13 Jan 2020, 09:11 PM

Thank you for the quick reply.

 

The main reason I am passing onBlur and onFocus to the DatePicker is because I have added a clear button that shows up onFocus but hide it onBlur. This fixes the issue of the loop by passing it a Calendar prop but now I am having an issue where the Now, Set and Cancel buttons seem to no longer close the modal. here is a rough skeleton of my component

// I understand that this is still due to onFocus being on the component but could not find a child component for the time picker or confirmation buttons 

<DatePicker
//value
//format
onChange={this.setDate} // sets values where needed
Calendar={Calendar} // passed import Calendar -- thanks again
show={this.state.showCalendar}// state of show due so when clicked input box shows calendar pop up
onFocus={() => {
this.openCancel(true); // this method changes the state of this.state.showCalendar and showClearButton state
}}
onBlur={() => {
this.openCancel(false); // reverse of onFocus as i no longer need the clear button or to show the calendar as show is prop based
}}
/>
// this.state.showCancel ? // show clearButton which clears values onMouseDown as onClick and onBlur fire at the same time.

0
Jason
Top achievements
Rank 1
answered on 13 Jan 2020, 09:14 PM
Sorry this would be <DateTimePicker> not <DatePicker>.
0
Accepted
Stefan
Telerik team
answered on 14 Jan 2020, 08:36 AM

Hello, Jason,

Thank you for the clarification.

For the set and now buttons I can suggest the following:

- Close the DateTimePicker when the value is changed(clicking the now and set buttons).

- Add a flag to see if the value was just changed, as otherwise, this will trigger a focus on the input, that will open the DateTimePicker again:

https://stackblitz.com/edit/react-rps4zt-uq9mkx?file=app%2Fmain.jsx

As for the cancel button, I can suggest voting for this feature, as it will allow using a custom button and controlling what its click event is doing:

https://feedback.telerik.com/kendo-react-ui/1446512-cancel-button-on-datetimepicker-render-prop

Still, I can suggest using the focus and blue logic only to control the clear button, instead of controlling the component open and closed state.

Regards,
Stefan
Progress Telerik

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
General Discussions
Asked by
Jason
Top achievements
Rank 1
Answers by
Jason
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or