ExtJS 4.2 DateField仅显示年月不显示日期的实现需求
Got it, let's get this working exactly how you want it—hiding the day selection in the DateField dropdown and formatting the final value as YYYY-MM. I've tackled this with ExtJS 4.2 a few times, so here are two solid approaches depending on your reuse needs:
Approach 1: Lightweight Quick Fix (No Full Override)
If you only need this behavior in one place, you can tweak the default DatePicker directly in the DateField config. This hides the day grid and adjusts formatting without writing a full component override:
Ext.create('Ext.form.field.Date', { renderTo: Ext.getBody(), fieldLabel: 'Select Year-Month', // Set display/submit formats to YYYY-MM format: 'Y-m', altFormat: 'Y-m', submitFormat: 'Y-m', picker: { listeners: { render: function(picker) { // Hide the day selection table and footer (if present) picker.el.down('table.x-datepicker-inner').hide(); picker.el.down('.x-datepicker-footer')?.hide(); } }, // Disable day-focused shortcuts to avoid user confusion keyNavEnabled: false, mouseWheelEnabled: false }, // Ensure the field shows YYYY-MM immediately after selection listeners: { select: function(field, selectedDate) { var formattedDate = Ext.Date.format(selectedDate, 'Y-m'); field.setRawValue(formattedDate); } } });
Approach 2: Reusable Custom Picker (Best for Multiple Uses)
If you need this year-month picker across multiple parts of your app, create a reusable override of Ext.picker.Date:
// Define a custom year-month picker component Ext.define('MyApp.picker.YearMonth', { extend: 'Ext.picker.Date', alias: 'widget.yearmonthpicker', // Rewrite the render template to remove day selection entirely renderTpl: [ '<div id="{id}-innerEl" role="grid">', '<div role="row" class="{baseCls}-header">', '<div role="column" class="{baseCls}-month" colspan="{monthColumns}">', '{monthPicker}', '</div>', '</div>', '<div role="row" class="{baseCls}-yearnav">', '<div class="{baseCls}-yearnav-prev">{prevText}</div>', '<div role="column" class="{baseCls}-year" colspan="{yearColumns}">', '{yearPicker}', '</div>', '<div class="{baseCls}-yearnav-next">{nextText}</div>', '</div>', '</div>', { compiled: true, disableFormats: true } ], // Hide any remaining day-related elements after render afterRender: function() { this.callParent(arguments); this.el.down('table.x-datepicker-inner')?.hide(); }, // Override date selection to pick the first day of the selected month handleDateClick: function(e, t) { var me = this; if (!me.disabled && t.dateValue) { var selectedDate = new Date(t.dateValue); // Normalize to first day of the month to ensure valid Date object var normalizedDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1); me.setValue(normalizedDate); me.fireEvent('select', me, normalizedDate); if (me.handler) me.handler.call(me.scope || me, me, normalizedDate); me.onSelect(); } } }); // Use the custom picker in your DateField Ext.create('Ext.form.field.Date', { renderTo: Ext.getBody(), fieldLabel: 'Select Year-Month', format: 'Y-m', altFormat: 'Y-m', submitFormat: 'Y-m', picker: { xtype: 'yearmonthpicker', keyNavEnabled: false, mouseWheelEnabled: false }, listeners: { select: function(field, date) { field.setRawValue(Ext.Date.format(date, 'Y-m')); } } });
Key Details to Note:
- Formatting: Setting
format,altFormat, andsubmitFormattoY-mensures the field displays, accepts input, and submits data in theYYYY-MMformat you need. - Date Object Handling: ExtJS DateField requires a valid
Dateobject as its value, so we normalize selections to the first day of the chosen month (this doesn't affect the displayed format). - User Experience: Disabling keyboard shortcuts for day selection prevents users from accidentally navigating to day views, keeping the dropdown focused on year/month.
Both approaches will give you that clean year/month-only dropdown you're aiming for, with the field outputting values like 2018-03 or 2018-04.
内容的提问来源于stack exchange,提问作者Nishant Bajracharya

