datePicker acting odd when passed onBlur and onFocus

6 posts, 1 answers
  1. Jason
    Jason avatar
    6 posts
    Member since:
    Jan 2020

    Posted 10 Jan 2020 Link to this post

    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.

  2. Jason
    Jason avatar
    6 posts
    Member since:
    Jan 2020

    Posted 10 Jan 2020 in reply to Jason Link to this post

    // 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')
    );
  3. Stefan
    Admin
    Stefan avatar
    3012 posts

    Posted 13 Jan 2020 Link to this post

    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
  4. Jason
    Jason avatar
    6 posts
    Member since:
    Jan 2020

    Posted 13 Jan 2020 Link to this post

    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.

  5. Jason
    Jason avatar
    6 posts
    Member since:
    Jan 2020

    Posted 13 Jan 2020 in reply to Jason Link to this post

    Sorry this would be <DateTimePicker> not <DatePicker>.
  6. Answer
    Stefan
    Admin
    Stefan avatar
    3012 posts

    Posted 14 Jan 2020 Link to this post

    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
Back to Top