jQuery easyui 扩展datetimebox控件,增加上午、中午、下午快速选择

使用过jQuery easyui datetimebox控件的同学都知道,默认datetimebox长这样:

对于选择时间不是很友好,要么手动输入,要么点右侧的上下按钮调节。在datetimebox原有功能基础上,可以扩展"上午"、"中午"、"下午"快速选择,类似下面的样子:

实现步骤:

javascript 复制代码
/**********************************************************************************************************************
 * 描述:时间选择框扩展(增加早上,中午,下午,此刻快速选择)
 * 创建人:zhangqs
 * 创建时间:2026-1-28 10:21:09
 * 修改记录:
 * **********************************************************************************************************************/

(function ($) {
    // 保存原始的datetimebox方法
    var originalDateTimeBox = $.fn.datetimebox;
    var originalDateTimeBoxMethods = $.extend({}, $.fn.datetimebox.methods);

    // 扩展默认配置
    $.extend($.fn.datetimebox.defaults, {
        showPeriodButtons: true,        // 是否显示快速选择按钮
        periodMorningTime: '09:00:00',  // 上午时间
        periodNoonTime: '12:00:00',     // 中午时间(新增)
        periodAfternoonTime: '17:00:00', // 下午时间
        periodShowNowButton: false,      // 是否显示此刻按钮
        periodNowButtonText: '此刻',     // 此刻按钮文本
        periodButtonStyle: 'compact'    // 按钮样式:'default'(水平排列)或 'compact'(紧凑排列)
    });

    // 创建快速选择面板
    function createPeriodPanel(opts) {
        var buttons = [];

        // 根据样式决定按钮排列方式
        if (opts.periodButtonStyle === 'compact') {
            // 紧凑排列:上午、中午、下午在同一行
            buttons = [
                '<a href="javascript:void(0)" class="period-btn" data-period="morning" title="设置时间为' + opts.periodMorningTime + '">上午(09:00)</a>',
                '<a href="javascript:void(0)" class="period-btn" data-period="noon" title="设置时间为' + opts.periodNoonTime + '">中午(12:00)</a>',
                '<a href="javascript:void(0)" class="period-btn" data-period="afternoon" title="设置时间为' + opts.periodAfternoonTime + '">下午(17:00)</a>'
            ];
        } else {
            // 默认排列:带时间显示
            buttons = [
                '<a href="javascript:void(0)" class="period-btn" data-period="morning" style="margin-right:5px;">上午(' + opts.periodMorningTime + ')</a>',
                '<a href="javascript:void(0)" class="period-btn" data-period="noon" style="margin-right:5px;">中午(' + opts.periodNoonTime + ')</a>',
                '<a href="javascript:void(0)" class="period-btn" data-period="afternoon" style="margin-right:5px;">下午(' + opts.periodAfternoonTime + ')</a>'
            ];
        }

        var panelHtml = '<div class="period-panel" style="padding:8px 10px;border-top:1px solid #ddd;background:#f5f5f5;">' +
            //'<div style="font-size:12px;color:#666;margin-bottom:5px;">快速选择:</div>' +
            '<div class="period-buttons">' +
            buttons.join('') +
            '<div style="clear:both;"></div>';

        if (opts.periodShowNowButton) {
            if (opts.periodButtonStyle === 'compact') {
                panelHtml += '<a href="javascript:void(0)" class="period-btn now-btn" data-period="now" style="float:right;">' + opts.periodNowButtonText + '</a>';
            } else {
                panelHtml += '<a href="javascript:void(0)" class="period-btn now-btn" data-period="now" style="float:right;margin-top:5px;">' + opts.periodNowButtonText + '</a>';
            }
        }

        panelHtml += '</div></div>';
        return $(panelHtml);
    }

    // 处理时间选择
    function handlePeriodSelect(target, period, opts) {
        var $target = $(target);
        var currentValue = $target.datetimebox('getValue');
        var newDateTime;
        var now = new Date();

        switch (period) {
            case 'morning':
                if (currentValue) {
                    var datePart = currentValue.split(' ')[0];
                    newDateTime = datePart + ' ' + opts.periodMorningTime;
                } else {
                    newDateTime = now.getFullYear() + '-' +
                        padZero(now.getMonth() + 1) + '-' +
                        padZero(now.getDate()) + ' ' + opts.periodMorningTime;
                }
                break;

            case 'noon':
                if (currentValue) {
                    var datePart = currentValue.split(' ')[0];
                    newDateTime = datePart + ' ' + opts.periodNoonTime;
                } else {
                    newDateTime = now.getFullYear() + '-' +
                        padZero(now.getMonth() + 1) + '-' +
                        padZero(now.getDate()) + ' ' + opts.periodNoonTime;
                }
                break;

            case 'afternoon':
                if (currentValue) {
                    var datePart = currentValue.split(' ')[0];
                    newDateTime = datePart + ' ' + opts.periodAfternoonTime;
                } else {
                    newDateTime = now.getFullYear() + '-' +
                        padZero(now.getMonth() + 1) + '-' +
                        padZero(now.getDate()) + ' ' + opts.periodAfternoonTime;
                }
                break;

            case 'now':
                newDateTime = now.getFullYear() + '-' +
                    padZero(now.getMonth() + 1) + '-' +
                    padZero(now.getDate()) + ' ' +
                    padZero(now.getHours()) + ':' +
                    padZero(now.getMinutes()) + ':' +
                    padZero(now.getSeconds());
                break;
        }

        $target.datetimebox('setValue', newDateTime);
        $target.datetimebox('hidePanel');
    }

    // 补零函数
    function padZero(num) {
        return num < 10 ? '0' + num : num;
    }

    // 重写datetimebox的创建方法
    var oldCreate = $.fn.datetimebox.methods.create;
    $.fn.datetimebox.methods.create = function (jq, options) {
        // 调用原始创建方法
        oldCreate.call(this, jq, options);

        return jq.each(function () {
            var $this = $(this);
            var opts = $this.datetimebox('options');

            // 只有启用了快速选择按钮才添加
            if (opts.showPeriodButtons !== false) {
                var panel = $this.datetimebox('panel');

                // 检查是否已经添加过快速选择面板
                if (panel.find('.period-panel').length === 0) {
                    // 创建快速选择面板
                    var periodPanel = createPeriodPanel(opts);

                    // 添加到datetimebox面板底部
                    panel.append(periodPanel);

                    // 绑定点击事件
                    periodPanel.on('click', '.period-btn', function (e) {
                        e.preventDefault();
                        var period = $(this).data('period');
                        handlePeriodSelect($this, period, opts);
                    });
                }
            }
        });
    };

    // 重写datetimebox的destroy方法
    var oldDestroy = $.fn.datetimebox.methods.destroy;
    $.fn.datetimebox.methods.destroy = function (jq) {
        return jq.each(function () {
            var $this = $(this);
            var panel = $this.datetimebox('panel');

            // 移除快速选择面板
            panel.find('.period-panel').remove();

            // 调用原始的destroy方法
            oldDestroy.call(this, $this);
        });
    };

    // 添加新方法:设置快速选择时间
    $.extend($.fn.datetimebox.methods, {
        setPeriodTimes: function (jq, times) {
            return jq.each(function () {
                var $this = $(this);
                var opts = $this.datetimebox('options');

                // times可以是对象或数组
                if ($.isPlainObject(times)) {
                    if (times.morning) opts.periodMorningTime = times.morning;
                    if (times.noon) opts.periodNoonTime = times.noon;
                    if (times.afternoon) opts.periodAfternoonTime = times.afternoon;
                } else if ($.isArray(times) && times.length >= 3) {
                    opts.periodMorningTime = times[0];
                    opts.periodNoonTime = times[1];
                    opts.periodAfternoonTime = times[2];
                }

                // 更新面板上的显示
                var panel = $this.datetimebox('panel');
                var periodPanel = panel.find('.period-panel');

                if (periodPanel.length > 0) {
                    // 重新创建面板以更新显示
                    periodPanel.remove();
                    periodPanel = createPeriodPanel(opts);
                    panel.append(periodPanel);

                    // 重新绑定点击事件
                    periodPanel.on('click', '.period-btn', function (e) {
                        e.preventDefault();
                        var period = $(this).data('period');
                        handlePeriodSelect($this, period, opts);
                    });
                }
            });
        },

        // 获取当前的时间设置
        getPeriodTimes: function (jq) {
            var opts = $(jq[0]).datetimebox('options');
            return {
                morning: opts.periodMorningTime,
                noon: opts.periodNoonTime,
                afternoon: opts.periodAfternoonTime
            };
        },

        // 显示/隐藏快速选择按钮
        showPeriodButtons: function (jq, show) {
            return jq.each(function () {
                var $this = $(this);
                var opts = $this.datetimebox('options');
                var panel = $this.datetimebox('panel');

                opts.showPeriodButtons = show !== false;

                var periodPanel = panel.find('.period-panel');
                if (opts.showPeriodButtons) {
                    if (periodPanel.length === 0) {
                        // 创建快速选择面板
                        periodPanel = createPeriodPanel(opts);
                        panel.append(periodPanel);

                        // 绑定点击事件
                        periodPanel.on('click', '.period-btn', function (e) {
                            e.preventDefault();
                            var period = $(this).data('period');
                            handlePeriodSelect($this, period, opts);
                        });
                    }
                    periodPanel.show();
                } else {
                    periodPanel.hide();
                }
            });
        },

        // 设置按钮样式
        setPeriodButtonStyle: function (jq, style) {
            return jq.each(function () {
                var $this = $(this);
                var opts = $this.datetimebox('options');
                opts.periodButtonStyle = style || 'default';

                // 更新面板
                var panel = $this.datetimebox('panel');
                var periodPanel = panel.find('.period-panel');

                if (periodPanel.length > 0) {
                    periodPanel.remove();
                    periodPanel = createPeriodPanel(opts);
                    panel.append(periodPanel);

                    // 重新绑定点击事件
                    periodPanel.on('click', '.period-btn', function (e) {
                        e.preventDefault();
                        var period = $(this).data('period');
                        handlePeriodSelect($this, period, opts);
                    });
                }
            });
        }
    });

    // 为已存在的datetimebox添加功能
    $(document).ready(function () {
        // 为页面上已有的datetimebox添加功能
        $('.easyui-datetimebox').each(function () {
            var $this = $(this);
            if ($this.data('datetimebox')) {
                var opts = $this.datetimebox('options');
                if (opts.showPeriodButtons !== false) {
                    var panel = $this.datetimebox('panel');

                    if (panel.length > 0 && panel.find('.period-panel').length === 0) {
                        var periodPanel = createPeriodPanel(opts);
                        panel.append(periodPanel);

                        periodPanel.on('click', '.period-btn', function (e) {
                            e.preventDefault();
                            var period = $(this).data('period');
                            handlePeriodSelect($this, period, opts);
                        });
                    }
                }
            }
        });
    });

})(jQuery);

样式表:

css 复制代码
/* 快速选择面板样式 */
.period-panel {
    background: #f8f8f8 !important;
    border-top: 1px solid #e6e6e6 !important;
    border-bottom: 1px solid #e6e6e6 !important;
    padding: 3px 0px !important;
}

.period-panel .period-buttons {
    margin-top: 0px;
    display: flex;
    justify-content: space-evenly;
}

/* 默认按钮样式 */
.period-btn {
    display: inline-block;
    padding: 4px 5px;
    background: #fff;
    border: 1px solid #d4d4d4;
    border-radius: 3px;
    color: #333;
    font-size: 12px;
    line-height: 1.5;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s;
}

.period-btn:hover {
    background: #e6e6e6;
    border-color: #adadad;
    color: #333;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.period-btn.now-btn {
    background: #f0f0f0;
    border-color: #ccc;
    color: #666;
}

.period-btn.now-btn:hover {
    background: #e0e0e0;
    border-color: #bbb;
}

/* 紧凑模式下的按钮样式 */
.period-panel .period-buttons.compact-buttons .period-btn {
    padding: 3px 8px;
    margin-right: 3px;
    font-size: 11px;
}

/* 按钮颜色区分 */
.period-btn[data-period="morning"] {
    border-left: 3px solid #5cb85c; /* 绿色边框表示上午 */
}

.period-btn[data-period="noon"] {
    border-left: 3px solid #f0ad4e; /* 橙色边框表示中午 */
}

.period-btn[data-period="afternoon"] {
    border-left: 3px solid #337ab7; /* 蓝色边框表示下午 */
}

.period-btn[data-period="now"] {
    border-left: 3px solid #999; /* 灰色边框表示此刻 */
}

/* 确保datetimebox面板高度适应 */
.datebox .combo-panel {
    padding-bottom: 0 !important;
}

.datetimebox .combo-panel {
    max-height: none !important;
}

/* 小屏幕适配 */
@media (max-width: 480px) {
    .period-panel .period-buttons .period-btn {
        display: block;
        width: 100%;
        margin-bottom: 5px;
        margin-right: 0;
        text-align: center;
        box-sizing: border-box;
    }

    .period-btn.now-btn {
        float: none !important;
        width: 100%;
        margin-top: 5px;
    }
}

将上面的js和css单独保存为文件,页面引入即可,原来控件调用方式不变,对原有代码无侵入。

相关推荐
zach10 小时前
前端落地实战:Next.js 项目 Nginx + PM2 生产部署全流程(附踩坑总结)
前端·pm2·next.js
overmind10 小时前
oeasy教h5前端001 修改的乐趣_直接修改在线网页
前端
只睡四小时10 小时前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航
恋猫de小郭10 小时前
Android 原生的 Compose A2UI 也来了,你还抱着 XML 养老吗?
android·前端·flutter
庄园特聘拆椅狂魔10 小时前
从连连看到粒子消散——前端小游戏与视觉特效的技术选型
前端
JudithHuang10 小时前
React 常用 Hooks
前端·react.js·前端框架
sycmancia11 小时前
Qml——Window元素使用
前端
每天都好困11 小时前
03 AR 投影与误差修正:把地图上的点贴到视频画面上
前端
每天都好困11 小时前
04 地图图层封装:像管理 Photoshop 图层一样管理地图元素
前端
去伪存真12 小时前
构建你的第一个 DevOps AI Agent:自动化捕获、分析并修复 CI 故障
前端·agent