'Easy way to add a date picker to a regular text field?

I'd like to add a date picker to a text field as part of an expression builder. E.g. you can enter something like:

date <= │ (where is the cursor)

then click a calendar trigger, and when a date is picked, have it insert the date at the cursor:

date <= 2019-04-23│

I looked at how date picker is implemented, and it's a lot of stuff there that I would have to copy over.

So then was thinking about piggybacking on a hidden date field, something like this:

Ext.create('Ext.form.Panel', {
    title: 'Expression Builder',
    width: 400,
    bodyPadding: 10,
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'textfield',
        fieldLabel: 'Expression',
        allowBlank: true,
        triggers: {
            calendar: {
                cls: 'x-fa fa-calendar',
                handler: function (me) {
                    var itemId = me.id + '-aux-datefield';
                    var datefield = Ext.ComponentQuery.query('#' + itemId)[0] ||
                    Ext.create({
                        itemId: itemId,
                        xtype: 'datefield',
                        hideLabel: true,
                        floating: true,
                        renderTo: me.getEl(),
                        alignTarget: me.id,
                        defaultAlign: 'tr-tr'
                    });
                    datefield.onTriggerClick();
                }
            }
        }
    }]
});

Thing is, if the date field is hidden using hidden: true then the picker won't render. Using something sneaky like style: 'display: none' and the picker aligns to the top left of the viewport. Adjusting the maxHeight and maxWidth to something small and the date field resizes.

This is just one of many issues, there's event handling, inserting at the cursor, destroying the field, etc. so it's going to be a lot of work, too.

I'm wondering if anyone has done something similar, and if maybe there's an easier way?



Solution 1:[1]

Something like this? :

    Ext.application({
        name: 'Fiddle',
        launch: function () {

            var myPicker = Ext.create('Ext.picker.Date', {
                renderTo: Ext.getBody(),
                floating: true,
                defaultAlign: 't-b',
                minDate: new Date(),
            });

            Ext.create('Ext.form.Panel', {
                title: 'Expression Builder',
                width: 500,
                bodyPadding: 100,
                renderTo: Ext.getBody(),
                items: [{
                    xtype: 'textfield',
                    fieldLabel: 'Expression',
                    width: 300,
                    allowBlank: true,
                    triggers: {
                        calendar: {
                            cls: 'x-fa fa-calendar',
                            handler: function (me) {
                                var text = this
                                myPicker.handler =  function (picker, date) {
                                        text.setValue(text.getValue() + ' ' + Ext.Date.format(this.getValue(), 'd/m/Y'));
                                        this.hide();
                                };
                                myPicker.showBy(this);

                            }
                        }
                    }
                }]
            });
        }
    });

Solution 2:[2]

Another solution would be to extend Ext.form.field.Picker, take a look at the Ext.form.field.Date to see how that does it.

Or copy the source for the Date field, see the API doc, to your own component, as that has the requisite components for the picker, style, formatting etc. You can then strip away the date validation and date formatting.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabio Barros
Solution 2 David Broad