JQuery日期时间选择器 - 需要仅选择月份和年份

10
我仔细阅读了这篇文章jQuery UI DatePicker to show month year only,对我改造日期时间选择器的UI非常有帮助。
但是,在同一个表单上有几个日期时间选择器时,会出现以下问题。CSS属性display:none的目的是“隐藏”不需显示的天数。但是,如果在同一个表单上有多个日期时间选择器,而我只想将其中一个设置为月份选择器,该怎么办?由于CSS将更改.ui-datepicker-calendar的属性,因此它会使所有日期时间日历界面上的天数都消失。欢迎提出任何建议。
7个回答

9

目前,日期选择器每页只创建一个元素,所有“datepicker”输入都共享该元素,因此链接问题的答案无效。 beforeShow事件不允许使用.addClass()或.css()编辑datepicker元素(因为在显示时从datepicker脚本刷新元素结构)。

为了解决这个问题,我发现输入元素的focus事件似乎在datepicker显示后运行代码。 这是一个简单的解决方法,可以解决令人沮丧的问题。

以下是我的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
    $('.month-picker').datepicker( {
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM yy',
        onClose: function(dateText, inst) { 
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).datepicker('setDate', new Date(year, month, 1));
        },
        beforeShow : function(input, inst) {
            if ((datestr = $(this).val()).length > 0) {
                year = datestr.substring(datestr.length-4, datestr.length);
                month = jQuery.inArray(datestr.substring(0, datestr.length-5), $(this).datepicker('option', 'monthNames'));
                $(this).datepicker('option', 'defaultDate', new Date(year, month, 1));
                $(this).datepicker('setDate', new Date(year, month, 1));
            }
        }
    });
    $('.date-picker').datepicker();
    $('.month-picker').focus(function () {
        $('.ui-datepicker-calendar').addClass('hideDates');
    });
});
</script>
<style>
.hideDates {
    display: none;
}
</style>
</head>
<body>
    <label for="startDate">Date:</label>
    <input name="startDate" id="startDate" class="date-picker" />
    <label for="endMonth">End Month:</label>
    <input name="endMonth" id="endMonth" class="month-picker" />
</body>
</html>

调用带有空参数的日期选择器是做什么用的?它有什么作用? - Nap
@Nassign - 此页面上有两个日期选择器。使用空参数调用datepicker仅是为了创建具有默认功能的第二个日期选择器。 - Ben Koehler
谢谢。我找到了一个网站,可以将自定义按钮添加到按钮面板中。但是每次更改月份和现在按钮时,该按钮都会消失。有什么建议吗?这是网站链接:http://csharptechies.blogspot.com/2010/12/adding-custom-buttons-to-jquery.html - Nap
@Nassign - 如果您创建一个新问题,可能会更快地得到更好的答案。 - Ben Koehler
运行良好,但当日期选择器试图出现在输入框上方时,我遇到了一个CSS定位问题。我在这里提出了一个新的问题:https://dev59.com/o1bUa4cB1Zd3GeqPAqYx - benb
这个解决方案在IE中有一个bug。<br/> jsfiddle链接 尝试快速连续两次点击“结束月份”日期选择器的上一个按钮。日历将不再隐藏。原因是当您快速连续两次单击上一个(或下一个)按钮时,焦点事件在IE中不会触发。 - Chinh Phan

3
我使用了Ben发布的代码的稍微不同版本。我没有依赖于焦点事件,而是添加了
inst.dpDiv.addClass('monthonly');

将其放入beforeShow方法中

inst.dpDiv.removeClass('monthonly');

在onClose中添加和删除通用div上的类。这会增加或移除所有日期选择器小部件使用的通用div上的类。然后可以使用CSS定位日期日历div。

.monthonly#ui-datepicker-div .ui-datepicker-calendar
{
    display: none;
}

真希望我早点看到这个。这种方法可以防止在出现在输入框上方时,日历定位错误。(参见:https://dev59.com/o1bUa4cB1Zd3GeqPAqYx) - benb

2

以前的解决方案不能处理不同的格式。同时在 beforeShow 中使用 setDate 也没有效果。正确的方式是:

beforeShow: function(input, inst) {
    var dateString = $(this).val();
    var options = new Object();
    if (dateString.length > 0) {
        options.defaultDate = $.datepicker.parseDate("dd-" + $(this).datepicker("option", "dateFormat"), "01-" + dateString);
    }
    inst.dpDiv.addClass("ui-monthpicker");
    return options;
},
onClose: function(dateText, inst) {
    var month = inst.dpDiv.find(".ui-datepicker-month").val();
    var year = inst.dpDiv.find(".ui-datepicker-year").val();
    $(this).datepicker("setDate", new Date(year, month, 1));
    inst.dpDiv.removeClass("ui-monthpicker");
}

我使用日期选择器中的parseDate函数来处理不同的日期格式,并将其返回为默认日期选项的日期字段。
所需CSS:
#ui-datepicker-div.ui-monthpicker {
    padding: 0.2em;
}
#ui-datepicker-div.ui-monthpicker .ui-datepicker-calendar {
    display: none;
}

我在移除ui-monthpicker类时添加了一个超时,否则在隐藏日期选择器之前,日历会“闪烁”。setTimeout(function () { inst.dpDiv.removeClass("ui-monthpicker"); }, 200); - user2444499

2
我有另一种基于上述方法的解决方案,其中包含一些改进。在我的HTML中,我通过添加以下内容来隐藏日期选择器,因为页面上只有一个日期选择器:
<style>
    .ui-datepicker-calendar {
        display: none;
    }
</style>

我像其他人一样初始化了我的日期选择器,并在onChangeMonthYear事件中添加了一些代码:

$n(this).datepicker({
    defaultDate: 0,
    changeMonth: true,
    changeYear: true,
    onChangeMonthYear: function(year, month, inst) {
        $(this).datepicker('setDate', new Date(year, month - 1, 1));
    }
});

注意:

月份 - 1

如果你不加这个,由于这个函数接收的是基于1的索引月份,而setDate使用的是基于0的月份,所以会导致堆栈溢出。


1

Ben的解决方案完美地工作了,只是进行了一些小的修改,我使用了onChangeMonthYear而不是onClose:

onChangeMonthYear: function(year, month, inst) {
  var date = new Date(year, month - 1, 1);
  $(this).val($.datepicker.formatDate(format, date));
  $(this).datepicker('setDate', date);
}

1
我曾经做过类似的事情,但是我制作了一个单独的“版本”日期选择器脚本,并称其为月份选择器,拥有自己的CSS选择器和CSS文件。这意味着您可以在同一页上使用其中一个或两个。

谢谢您的回复,能否再详细解释一下呢?好的,我从jquery.ui.datetimepicker.js中复制了另一个.js文件,名为monthpicker.js,那么接下来应该怎么做呢?您能否解释一下“拥有自己的CSS选择器和CSS文件”是什么意思? - Darren
@Darren - 你需要仔细查看代码,并查看脚本如何为创建的项目分配选择器/ID,然后将它们更改为使用“monthpicker”而不是“datepicker”,例如。 然后,您需要复制CSS文件并进行相应的更改。 - Paddy
我想知道是否可以使用CSS继承来选择属于<input type="text" id="monthPicker"/>的唯一日期选择器类.ui-datepicker-calendar? - Darren

0

这个代码在我这里运行得非常完美:

$(document).ready(function()
{   
    $(".monthPicker").datepicker({
        dateFormat: 'MM yy,
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,

        onClose: function(dateText, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).val($.datepicker.formatDate('MM yy', new Date(year, month, 1)));
        }
    });

    $(".monthPicker").focus(function () {
        $(".ui-datepicker-calendar").hide();
        $("#ui-datepicker-div").position({
            my: "center top",
            at: "center bottom",
            of: $(this)
        });
    });
});

<label for="month">Month: </label>
<input type="text" id="month" name="month" class="monthPicker" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接