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单独保存为文件,页面引入即可,原来控件调用方式不变,对原有代码无侵入。

相关推荐
郑州光合科技余经理2 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
VT.馒头2 小时前
【力扣】2694. 事件发射器
前端·javascript·算法·leetcode·职场和发展·typescript
life码农2 小时前
HTML文本换行显示几种方法总结
前端·html
强子感冒了2 小时前
CSS基础学习:CSS选择器与优先级规则
前端·css·学习
啟明起鸣2 小时前
【Nginx 网关开发】上手 Nginx,简简单单启动一个静态 html 页面
运维·c语言·前端·nginx·html
vortex52 小时前
深度字典攻击(实操笔记·红笔思考)
前端·chrome·笔记
我是伪码农2 小时前
Vue 1.30
前端·javascript·vue.js
利刃大大3 小时前
【Vue】默认插槽 && 具名插槽 && 作用域插槽
前端·javascript·vue.js
艳阳天_.3 小时前
web 分录科目实现辅助账
开发语言·前端·javascript