Search code examples
extjsextjs6extjs6-classic

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

  • 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);
    
                                }
                            }
                        }
                    }]
                });
            }
        });