JQuery UI DatePicker для отображения только месяца

Я использую jQuery date picker, чтобы отображать календарь по всему моему приложению. Я хочу знать, могу ли я использовать его для отображения месяца и года (май 2010 г.), а не календаря?

Ответ 1

Здесь взломан (обновлен весь файл.html):

<!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.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
        $(function() {
            $('.date-picker').datepicker( {
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'MM yy',
            onClose: function(dateText, inst) { 
                $(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
            }
            });
        });
    </script>
    <style>
    .ui-datepicker-calendar {
        display: none;
    }
    </style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

EDIT jsfiddle для приведенного выше примера: http://jsfiddle.net/DBpJe/7755/

EDIT 2 Добавляет значение месяца в поле ввода только при нажатии кнопки "Готово". Также позволяет удалять значения полей ввода, что невозможно в приведенном выше поле http://jsfiddle.net/DBpJe/5103/

EDIT 3 обновил Better Solution на основе решения rexwolf.
http://jsfiddle.net/DBpJe/5106

Ответ 2

Этот код работает безупречно для меня:

<script type="text/javascript">
$(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)
        });
    });
});
</script>

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

Выход:

введите описание изображения здесь

Ответ 3

@Ben Koehler, этот префект! Я сделал небольшую модификацию, так что использование одного экземпляра сборщика дат более одного раза работает так, как ожидалось. Без этой модификации дата обрабатывается некорректно, а выбранная ранее дата не выделяется.

<!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.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
    $(function() {
        $('.date-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) {
                var datestr;
                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', 'monthNamesShort'));
                    $(this).datepicker('option', 'defaultDate', new Date(year, month, 1));
                    $(this).datepicker('setDate', new Date(year, month, 1));
                }
            }
        });
    });
    </script>
    <style>
    .ui-datepicker-calendar {
        display: none;
        }
    </style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

Ответ 4

Вышеуказанные ответы довольно хороши. Моя единственная жалоба заключается в том, что вы не можете очистить значение после его установки. Также я предпочитаю подход с расширением-jquery-like-a-plugin.

Это работает идеально для меня:

$.fn.monthYearPicker = function(options) {
    options = $.extend({
        dateFormat: "MM yy",
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        showAnim: ""
    }, options);
    function hideDaysFromCalendar() {
        var thisCalendar = $(this);
        $('.ui-datepicker-calendar').detach();
        // Also fix the click event on the Done button.
        $('.ui-datepicker-close').unbind("click").click(function() {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            thisCalendar.datepicker('setDate', new Date(year, month, 1));
        });
    }
    $(this).datepicker(options).focus(hideDaysFromCalendar);
}

Затем вызовите так:

$('input.monthYearPicker').monthYearPicker();

Ответ 5

<style>
.ui-datepicker table{
    display: none;
}

<script type="text/javascript">
$(function() {
    $( "#manad" ).datepicker({
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'yy-mm',
        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) {
                actDate = datestr.split('-');
                year = actDate[0];
                month = actDate[1]-1;
                $(this).datepicker('option', 'defaultDate', new Date(year, month));
                $(this).datepicker('setDate', new Date(year, month));
            }
        }
    });
});

Это решит проблему =) Но мне нужен timeFormat yyyy-mm

Только в FF4, но

Ответ 6

У меня была такая же потребность сегодня, и я нашел это на github, работает с jQueryUI и имеет возможность выбора месяца вместо дней в календаре

https://github.com/thebrowser/jquery.ui.monthpicker

Ответ 7

Вот что я придумал. Он скрывает календарь, не требуя дополнительного блока стиля, и добавляет четкую кнопку для решения проблемы неспособности очистить значение после нажатия на вход. Также хорошо работает с несколькими месячными пиксерами на одной странице.

HTML:

<input type='text' class='monthpicker'>

JavaScript:

$(".monthpicker").datepicker({
    changeMonth: true,
    changeYear: true,
    dateFormat: "yy-mm",
    showButtonPanel: true,
    currentText: "This Month",
    onChangeMonthYear: function (year, month, inst) {
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month - 1, 1)));
    },
    onClose: function(dateText, inst) {
        var month = $(".ui-datepicker-month :selected").val();
        var year = $(".ui-datepicker-year :selected").val();
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month, 1)));
    }
}).focus(function () {
    $(".ui-datepicker-calendar").hide();
}).after(
    $("<a href='javascript: void(0);'>clear</a>").click(function() {
        $(this).prev().val('');
    })
);

Ответ 8

Мне понадобился сборщик за месяц/год для двух полей (From и To), и когда один был выбран, Max/Min был установлен на другом... a la picking авиалинии. У меня возникли проблемы с настройкой max и min... даты другого поля будут стерты. Благодаря нескольким из вышеупомянутых сообщений... Я, наконец, понял это. Вы должны установить параметры и даты в очень определенном порядке.

Смотрите эту скрипту для полного решения: Месяц/Год Picker @JSFiddle

код:

var searchMinDate = "-2y";
var searchMaxDate = "-1m";
if ((new Date()).getDate() <= 5) {
    searchMaxDate = "-2m";
}
$("#txtFrom").datepicker({
    dateFormat: "M yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    minDate: searchMinDate,
    maxDate: searchMaxDate,
    showButtonPanel: true,
    beforeShow: function (input, inst) {
        if ((datestr = $("#txtFrom").val()).length > 0) {
            var year = datestr.substring(datestr.length - 4, datestr.length);
            var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), "#txtFrom").datepicker('option', 'monthNamesShort'));
        $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            var to = $("#txtTo").val();
            $("#txtTo").datepicker('option', 'minDate', new Date(year, month, 1));
            if (to.length > 0) {
                var toyear = to.substring(to.length - 4, to.length);
                var tomonth = jQuery.inArray(to.substring(0, to.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(toyear, tomonth, 1));
                $("#txtTo").datepicker('setDate', new Date(toyear, tomonth, 1));
            }
        }
    });
    $("#txtTo").datepicker({
        dateFormat: "M yy",
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        showAnim: "",
        minDate: searchMinDate,
        maxDate: searchMaxDate,
        showButtonPanel: true,
        beforeShow: function (input, inst) {
            if ((datestr = $("#txtTo").val()).length > 0) {
                var year = datestr.substring(datestr.length - 4, datestr.length);
                var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            var from = $("#txtFrom").val();
            $("#txtFrom").datepicker('option', 'maxDate', new Date(year, month, 1));
            if (from.length > 0) {
                var fryear = from.substring(from.length - 4, from.length);
                var frmonth = jQuery.inArray(from.substring(0, from.length - 5), $("#txtFrom").datepicker('option', 'monthNamesShort'));
                $("#txtFrom").datepicker('option', 'defaultDate', new Date(fryear, frmonth, 1));
                $("#txtFrom").datepicker('setDate', new Date(fryear, frmonth, 1));
            }

        }
    });

Также добавьте это в блок стиля, как указано выше:

.ui-datepicker-calendar { display: none !important; }

Ответ 9

Я собрал многие из вышеприведенных хороших ответов и пришел к следующему:

    $('#payCardExpireDate').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).datepicker('setDate', new Date(year, month, 1)).trigger('change');
                },
                beforeShow : function(input, inst) {
                    if ((datestr = $(this).val()).length > 0) {
                        year = datestr.substring(datestr.length-4, datestr.length);
                        month = datestr.substring(0, 2);
                        $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
                        $(this).datepicker('setDate', new Date(year, month-1, 1));
                    }
                }
            }).focus(function () {
                $(".ui-datepicker-calendar").hide();
                $("#ui-datepicker-div").position({
                    my: "center top",
                    at: "center bottom",
                    of: $(this)
                });
            });

Это доказано, что он работает, но сталкивается с множеством ошибок, поэтому мне пришлось заплатить в нескольких местах datepicker:

if($.datepicker._get(inst, "dateFormat") === "mm/yy")
{
    $(".ui-datepicker-calendar").hide();
}

patch1: в _showDatepicker: для сглаживания скрыть;

patch2: in _checkOffset: для корректировки положения выбора месяца (в противном случае, когда поле находится в нижней части браузера, проверка смещения выключена);

patch3: in onClose of _hideDatepicker: в противном случае при закрытии полей даты будут мигать в течение очень короткого периода, что очень раздражает.

Я знаю, что мое исправление было далек от хорошего, но пока оно работает. Надеюсь, что это поможет.

Ответ 10

Добавьте еще одно простое решение

 $(function() {
    $('.monthYearPicker').datepicker({
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'M yy'
    }).focus(function() {
        var thisCalendar = $(this);
        $('.ui-datepicker-calendar').detach();
        $('.ui-datepicker-close').click(function() {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
thisCalendar.datepicker('setDate', new Date(year, month, 1));
        });
    });
});

http://jsfiddle.net/tmnasim/JLydp/
Особенности:

  • отображать только месяц/год
  • Добавляет значение месяца и года в поле ввода только при нажатии кнопки Готово
  • Нет "открыть" поведение при нажатии "Готово"
    ------------------------------------
    другое решение, которое хорошо работает для DatePicker и Monthpicker на одной странице: (также избежать ошибки многократного нажатия на предыдущую кнопку в IE, которая может возникнуть, если мы используем функцию фокусировки)
    Скриптовая ссылка JS

Ответ 11

Это только я или это не работает, как должно быть в IE (8)? Дата изменяется при нажатии, но датпикер открывается снова, пока вы на самом деле не щелкнете где-нибудь на странице, чтобы не сфокусироваться на поле ввода...

Я ищу решение этого.

<!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.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
    $('.date-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));
        }
    });
});
</script>
<style>
.ui-datepicker-calendar {
    display: none;
    }
</style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

Ответ 12

после копания jQueryUI.com для datepicker, здесь мой вывод и ответ на ваш вопрос.

Во-первых, я бы сказал нет на ваш вопрос. Вы не можете использовать jQueryUI datepicker для выбора только месяца и года. Он не поддерживается. Он не имеет функции обратного вызова для этого.

Но вы можете взломать его, чтобы отображать только месяц и год, используя css, чтобы скрыть дни и т.д. И я думаю, что не будет смысла, потому что вам нужны даты, которые нужно щелкнуть чтобы выбрать дату.

Я могу сказать, что вам просто нужно использовать другой datepicker. Как и предложил Роджер.

Ответ 13

Если кто-то хочет, чтобы и для нескольких календарей было не так сложно добавить эту функцию в jquery ui. с минимальным поиском:

x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?f:n:"")+(

добавьте это перед x

var accl = ''; if(this._get(a,"justMonth")) {accl = ' ui-datepicker-just_month';}

выполните поиск

<table class="ui-datepicker-calendar

и замените его на

<table class="ui-datepicker-calendar'+accl+'

также выполните поиск

this._defaults={

замените его на

this._defaults={justMonth:false,

для css вы должны использовать:

.ui-datepicker table.ui-datepicker-just_month{
    display: none;
}

после этого все делается, просто перейдите к вашим желаемым функциям инициализации datepicker и предоставите настройку var

$('#txt_month_chart_view').datepicker({
    changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM yy',
        justMonth: true,
        create: function(input, inst) {
            $(".ui-datepicker table").addClass("badbad");
        },
        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));
        }
});

justMonth: true является ключевым здесь:)

Ответ 14

У меня была проблема выбора даты, смешанной с сборщиком месяцев. Я решил это так.

    $('.monthpicker').focus(function()
    {
    $(".ui-datepicker-calendar").show();
    }).datepicker( {
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM/yy',
        create: function (input, inst) { 

         },
        onClose: function(dateText, inst) { 
            var month = 1+parseInt($("#ui-datepicker-div .ui-datepicker-month :selected").val());           
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();

        }
    });

Ответ 15

Если вы ищете средство выбора месяца, попробуйте этот jquery.mtz.monthpicker

Это хорошо сработало для меня.

options = {
    pattern: 'yyyy-mm', // Default is 'mm/yyyy' and separator char is not mandatory
    selectedYear: 2010,
    startYear: 2008,
    finalYear: 2012,
    monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
};

$('#custom_widget').monthpicker(options);

Ответ 16

Как и многие другие, я сталкивался с многочисленными проблемами, пытаясь это сделать, и только комбинация опубликованных решений и, в конечном итоге, большой взлом, чтобы сделать его идеальным, дали мне решение.

Проблемы с другими решениями в этой теме, которые я пробовал:

  1. Выбор новой даты в устройстве выбора даты также приведет к изменению (внутренней) даты других средств выбора даты, поэтому при повторном открытии других (или попытке получить их дату) они будут иметь другую дату, чем та, которая отображается в назначенном им входе. -field.
  2. DatePicker не будет "помнить" дату при повторном открытии.
  3. Код для манипулирования датами использовал подстроку, чтобы он не был совместим со всеми форматами.
  4. "Мой указатель месяца" изменял поле ввода только при его закрытии, а не всякий раз, когда значения изменялись.
  5. Поле ввода не обновляется правильно, если вы введете неправильно отформатированную строку ввода для даты, а затем нажмете "Закрыть" в средстве выбора даты.
  6. У меня не может быть обычных средств выбора даты, которые показывают дни, на той же странице, что и средства выбора месяца, которые не показывают дни.

Наконец-то я нашел способ исправить все эти проблемы. Первые четыре можно исправить, просто следя за тем, как вы ссылаетесь на date- и средства выбора месяца в их внутреннем коде, и, конечно же, проводите ручное обновление ваших сборщиков. Это вы можете увидеть в примерах реализации в нижней части. Пятая проблема может быть решена добавлением некоторого пользовательского кода в функции DatePicker.

ПРИМЕЧАНИЕ. Вам НЕ нужно использовать следующие сценарии выбора месяца, чтобы исправить первые три проблемы обычного средства выбора даты. Просто используйте скрипт создания даты в нижней части этого поста.

Теперь, чтобы использовать сборщики месяцев и исправить последнюю проблему, нам нужно разделить сборщики данных и сборщики месяцев. Мы могли бы получить одно из немногих аддонов для ежемесячного выбора jQuery-UI, но некоторым не хватает гибкости/способности локализации, некоторым не хватает поддержки анимации... так что же делать? Сверните "свое" из кода DatePicker! Это дает вам полнофункциональный ежемесячный инструмент со всеми функциями DatePicker без отображения дней.

Я добавил monthpicker js-script и прилагаемый CSS-скрипт, используя метод, описанный ниже, с кодом jQuery-UI v1.11.1. Просто скопируйте эти фрагменты кода в два новых файла, monthpicker.js и monthpicker.css соответственно.


Вот процесс, который я прошел, чтобы клонировать исходный сборщик дат и сделать его сборщиком месяцев

Если вас не волнует, как я это сделал, прокрутите этот раздел и перейдите к строке "Теперь, чтобы добавить средства выбора даты и месяца на страницу!"

Я взял весь код javascript из jquery-ui-1.11.1.js, относящийся к их средству выбора даты, вставил его в новый js файл и заменил следующие строки:

  • "datepicker" ==> "monthpicker"
  • "Datepicker" ==> "Monthpicker"
  • "Выбор даты" ==> "Выбор месяца"
  • "Выбор даты" ==> "Выбор месяца"

Затем я удалил часть цикла for, которая создает весь div ui-datepicker-calendar (остальные решения скрываются с помощью CSS). Это можно найти в функции _generateHTML: (inst).

Найдите строку с надписью:

"</div><table class='ui-datepicker-calendar'><thead>" +

Пометить все, начиная с после закрывающего тега div и заканчивая (и не включая) строкой, где написано:

drawMonth++;

Теперь это будет несчастным, потому что нам нужно закрыть некоторые вещи. После этого закрывающего тега div добавьте следующее:

";

Код теперь должен быть красиво соединен вместе. Вот фрагмент кода, показывающий, что вы должны были закончить:

...other code...

calender += "<div class='ui-monthpicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
                (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
                (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
                this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
                    row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
                "</div>";
            drawMonth++;
            if (drawMonth > 11) {
                drawMonth = 0;
                drawYear++;
            }

...other code...

Затем я скопировал/вставил код из jquery-ui.css, относящийся к указателям даты, в новый CSS файл и заменил следующие строки:

  • "datepicker" ==> "monthpicker"

Теперь добавьте на страницу указатели даты и месяца!

Эти следующие фрагменты кода javascript работают с несколькими сборщиками дат и/или сборщиками месяцев на странице без вышеупомянутых проблем! Как правило, исправляется с помощью $ (this). много :)

Первый сценарий предназначен для обычного средства выбора дат, а второй - для "новых" средств выбора месяца.

.after с комментариями, который позволяет вам создать какой-то элемент для очистки поля ввода, украден из ответа Пола Ричардса.

Я использую формат "MM yy" в моем месячном средстве выбора и формат "yy-mm-dd" в моем указателе даты, но он полностью совместим со всеми форматами, поэтому вы можете использовать любой из них тот, который вы хотите. Просто измените параметр dateFormat. Стандартные параметры 'showButtonPanel', 'showAnim' и 'yearRange', конечно, являются необязательными и настраиваются в соответствии с вашими пожеланиями.


Добавление указателя даты

Создание экземпляра Datepicker. Этот идет от 90 лет назад и до наших дней. Это поможет вам сохранить правильность поля ввода, особенно если вы установите параметры defaultDate, minDate и maxDate, но может справиться с этим, если вы этого не сделаете. Он будет работать с любым форматом даты, который вы выберете.

        $('#MyDateTextBox').datepicker({
            dateFormat: 'yy-mm-dd',
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            showMonthAfterYear: true,
            showWeek: true,
            showAnim: "drop",
            constrainInput: true,
            yearRange: "-90:",
            minDate: new Date((new Date().getFullYear() - 90), new Date().getMonth(), new Date().getDate()),
            maxDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
            defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),

            onClose: function (dateText, inst) {
                // When onClose is called after we have clicked a day (and not clicked 'Close' or outside the datepicker), the input-field is automatically
                // updated with a valid date-string. They will always pass, because minDate and maxDate are already enforced by the datepicker UI.
                // This try is to catch and handle the situations, where you open the datepicker, and manually type in an invalid date in the field,
                // and then close the datepicker by clicking outside the datepicker, or click 'Close', in which case no validation takes place.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the default date, because the date seems valid.
                    // We do not need to manually update the input-field, as datepicker has already done this automatically.
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    console.log("onClose: " + err);
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // Instead, we set the current date, as well as the value of the input-field, to the last selected (and
                    // accepted/validated) date from the datepicker, by getting its default date. This only works, because
                    // we manually change the default date of the datepicker whenever a new date is selected, in both 'beforeShow'
                    // and 'onClose'.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            },

            beforeShow: function (input, inst) {
                // beforeShow is particularly irritating when initializing the input-field with a date-string.
                // The date-string will be parsed, and used to set the currently selected date in the datepicker.
                // BUT, if it is outside the scope of the minDate and maxDate, the text in the input-field is not
                // automatically updated, only the internal selected date, until you choose a new date (or, because
                // of our onClose function, whenever you click close or click outside the datepicker).
                // We want the input-field to always show the date that is currently chosen in our datepicker,
                // so we do some checks to see if it needs updating. This may not catch ALL cases, but these are
                // the primary ones: invalid date-format; date is too early; date is too late.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the input-field, and the default date, because the date seems valid.
                    // We also manually update the input-field, as datepicker does not automatically do this when opened.
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), typedDate));
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // We want the same behavior when opening the datepicker, so we set the current date, as well as the value
                    // of the input-field, to the last selected (and accepted/validated) date from the datepicker, by getting
                    // its default date. This only works, because we manually change the default date of the datepicker whenever
                    // a new date is selected, in both 'beforeShow' and 'onClose', AND have a default date set in the datepicker options.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            }
        })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

Добавление ежемесячного сборщика

Включите файл monthpicker.js и файл monthpicker.css на страницу, которую вы хотите использовать, указатели месяца.

Создание экземпляра Monthpicker Значение, полученное из этого средства выбора месяца, всегда является ПЕРВЫМ днем выбранного месяца. Начинается с текущего месяца и варьируется от 100 лет назад до 10 лет в будущем.

    $('#MyMonthTextBox').monthpicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showMonthAfterYear: true,
        showAnim: "drop",
        constrainInput: true,
        yearRange: "-100Y:+10Y",
        minDate: new Date(new Date().getFullYear() - 100, new Date().getMonth(), 1),
        maxDate: new Date((new Date().getFullYear() + 10), new Date().getMonth(), 1),
        defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), 1),

        // Monthpicker functions
        onClose: function (dateText, inst) {
            var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
            $(this).monthpicker('option', 'defaultDate', date);
            $(this).monthpicker('setDate', date);
        },

        beforeShow: function (input, inst) {
            if ($(this).monthpicker("getDate") !== null) {
                // Making sure that the date set is the first of the month.
                if($(this).monthpicker("getDate").getDate() !== 1){
                    var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
                    $(this).monthpicker('option', 'defaultDate', date);
                    $(this).monthpicker('setDate', date);
                }
            } else {
                // If the date is null, we reset it to the defaultDate. Make sure that the defaultDate is always set to the first of the month!
                $(this).monthpicker('setDate', $(this).monthpicker('option', 'defaultDate'));
            }
        },
        // Special monthpicker function!
        onChangeMonthYear: function (year, month, inst) {
            $(this).val($.monthpicker.formatDate($(this).monthpicker('option', 'dateFormat'), new Date(year, month - 1, 1)));
        }
    })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

Вот оно! Это все, что вам нужно, чтобы сделать ежемесячный сборщик.

Я не могу заставить jsfiddle работать с этим, но он работает для меня в моем проекте ASP.NET MVC. Просто сделайте то, что вы обычно делаете, чтобы добавить средство выбора даты на свою страницу и включить вышеупомянутые сценарии, возможно, изменив селектор (то есть $ ("# MyMonthTextBox")) на то, что вам подходит.

Надеюсь, это кому-нибудь поможет.

Ссылки на пастбины для некоторых дополнительных date- и месячных настроек:

  1. Сборщик месяцев работает в последний день месяца. Дата, которую вы получаете от этого средства выбора месяца, всегда будет последним днем месяца.

  2. Два сотрудничающих сборщика месяцев; "start" работает с первым месяцем, а "end" работает с последним месяцем. Они оба ограничены друг другом, поэтому выбор месяца в конце, предшествующего выбранному месяцу в начале, изменит начало на тот же месяц, что и конец. И наоборот. ДОПОЛНИТЕЛЬНО: При выборе месяца для "начала" значение "minDate" для "конца" устанавливается на этот месяц. Чтобы удалить эту функцию, закомментируйте одну строку в onClose (прочитайте комментарии).

  3. Два сотрудничающих сборщика дат; Они оба ограничены друг другом, поэтому выбор даты в конце, предшествующей выбранной дате в начале, изменит начало на тот же месяц, что и конец. И наоборот. ДОПОЛНИТЕЛЬНО: При выборе даты "начало", "minDate" на "конец" устанавливается на эту дату. Чтобы удалить эту функцию, закомментируйте одну строку в onClose (прочитайте комментарии).

Ответ 18

Сделал несколько уточнений для BrianS почти идеального ответа выше:

  • Я переопределял значение, установленное в шоу, потому что я думаю, что в этом случае он делает его немного читабельнее (хотя я новичок в немного другом формате)

  • Мой клиент не нуждался в календаре, поэтому я добавил добавление класса show/hide для этого, не затрагивая других датпикеров. Удаление класса происходит по таймеру, чтобы избежать свертывания таблицы, когда датпикер исчезает, что кажется очень заметным в IE.

РЕДАКТИРОВАТЬ: Одна проблема, оставленная для решения этой проблемы, заключается в том, что нет способа опорочить датупиксера - очистить поле и щелкнуть, и он будет повторно заполнен выбранной датой.

EDIT2: мне это не удалось решить (т.е. без добавления отдельной кнопки Clear рядом со входом), поэтому он просто использовал это: https://github.com/thebrowser/jquery.ui.monthpicker - если кто-то может получить стандартный пользовательский интерфейс, чтобы это было потрясающе.

    $('.typeof__monthpicker').datepicker({
        dateFormat: 'mm/yy',
        showButtonPanel:true,
        beforeShow: 
            function(input, dpicker)
            {                           
                if(/^(\d\d)\/(\d\d\d\d)$/.exec($(this).val()))
                {
                    var d = new Date(RegExp.$2, parseInt(RegExp.$1, 10) - 1, 1);

                    $(this).datepicker('option', 'defaultDate', d);
                    $(this).datepicker('setDate', d);
                }

                $('#ui-datepicker-div').addClass('month_only');
            },
        onClose: 
            function(dt, dpicker)
            {
                setTimeout(function() { $('#ui-datepicker-div').removeClass('month_only') }, 250);

                var m = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                var y = $("#ui-datepicker-div .ui-datepicker-year :selected").val();

                $(this).datepicker('setDate', new Date(y, m, 1));
            }
    });

Вам также нужно это правило стиля:

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

Ответ 19

Мне понравился ответ @user1857829 и его подход "расширение-jquery-like-a-plugin". Я просто сделал модификацию litte, так что, когда вы меняете месяц или год каким-либо образом, сборщик фактически записывает дату в поле. Я обнаружил, что мне понравится это поведение после его использования.

jQuery.fn.monthYearPicker = function(options) {
  options = $.extend({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    onChangeMonthYear: writeSelectedDate
  }, options);
  function writeSelectedDate(year, month, inst ){
   var thisFormat = jQuery(this).datepicker("option", "dateFormat");
   var d = jQuery.datepicker.formatDate(thisFormat, new Date(year, month-1, 1));
   inst.input.val(d);
  }
  function hideDaysFromCalendar() {
    var thisCalendar = $(this);
    jQuery('.ui-datepicker-calendar').detach();
    // Also fix the click event on the Done button.
    jQuery('.ui-datepicker-close').unbind("click").click(function() {
      var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
      var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
      thisCalendar.datepicker('setDate', new Date(year, month, 1));
      thisCalendar.datepicker("hide");
    });
  }
  jQuery(this).datepicker(options).focus(hideDaysFromCalendar);
}

Ответ 20

У меня были определенные трудности с принятым ответом, и никто другой не мог быть использован с минимальными усилиями в качестве базы. Итак, я решил настроить последнюю версию принятого ответа, пока он не удовлетворит хотя бы минимальные стандарты кодирования/повторного использования JS.

Вот способ гораздо более чистого решения, чем 3-я (последняя) версия Бен Кёлер принял ответ. Более того, он будет:

  • работают не только с форматом mm/yy, но и с любым другим, включая OP MM yy.
  • не скрывать календарь других датпикеров на странице.
  • не косвенно загрязняет глобальный объект JS с помощью datestr, month, year и т.д.

Проверьте это:

$('.date-picker').datepicker({
    dateFormat: 'MM yy',
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function (dateText, inst) {
        var isDonePressed = inst.dpDiv.find('.ui-datepicker-close').hasClass('ui-state-hover');
        if (!isDonePressed)
            return;

        var month = inst.dpDiv.find('.ui-datepicker-month').find(':selected').val(),
            year = inst.dpDiv.find('.ui-datepicker-year').find(':selected').val();

        $(this).datepicker('setDate', new Date(year, month, 1)).change();
        $('.date-picker').focusout();
    },
    beforeShow: function (input, inst) {
        var $this = $(this),
            // For the simplicity we suppose the dateFormat will be always without the day part, so we
            // manually add it since the $.datepicker.parseDate will throw if the date string doesn't contain the day part
            dateFormat = 'd ' + $this.datepicker('option', 'dateFormat'),
            date;

        try {
            date = $.datepicker.parseDate(dateFormat, '1 ' + $this.val());
        } catch (ex) {
            return;
        }

        $this.datepicker('option', 'defaultDate', date);
        $this.datepicker('setDate', date);

        inst.dpDiv.addClass('datepicker-month-year');
    }
});

И все, что вам нужно, это следующий CSS где-то рядом:

.datepicker-month-year .ui-datepicker-calendar {
    display: none;
}

Что это. Надеюсь, что это поможет сэкономить время для дальнейших читателей.

Ответ 21

Я знаю немного позднего ответа, но за пару дней до этого у меня была такая же проблема, и я пришел с хорошим и гладким решением. Сначала я нашел этот отличный выбор даты здесь

Затем я только что обновил класс CSS (jquery.calendarPicker.css), который поставляется с примером вроде этого:

.calMonth {
  /*border-bottom: 1px dashed #666;
  padding-bottom: 5px;
  margin-bottom: 5px;*/
}

.calDay 
{
    display:none;
}

Плагин запускает событие DateChanged при изменении чего-либо, поэтому не имеет значения, что вы не нажимаете на день (и он подходит как год и месяц)

Надеюсь, что это поможет!

Ответ 23

Я попробовал различные решения, предоставленные здесь, и они отлично работали, если вы просто хотели пару падений.

Лучший (по внешнему виду и т.д.) 'picker' (https://github.com/thebrowser/jquery.ui.monthpicker), предложенный здесь, в основном представляет собой копию старой версии jquery- ui datepicker с _generateHTML переписан. Тем не менее, я нашел, что он больше не играет хорошо с текущим jquery-ui (1.10.2) и имеет другие проблемы (не закрывается на esc, не закрывается при открытии другого виджета, имеет жестко закрепленные стили).

Вместо того, чтобы пытаться исправить этот monthpicker и вместо того, чтобы повторно выполнить тот же процесс с последним datepicker, я пошел с подключением к соответствующим частям существующего выбора даты.

Это включает переопределение:

  • _generateHTML (для создания разметки месяца)
  • parseDate (поскольку он не нравится, когда нет компонента дня),
  • _selectDay (поскольку datepicker использует .html(), чтобы получить значение дня)

Поскольку этот вопрос немного старый и уже хорошо ответил, здесь только _selectDay переопределяет, чтобы показать, как это было сделано:

jQuery.datepicker._base_parseDate = jQuery.datepicker._base_parseDate || jQuery.datepicker.parseDate;
jQuery.datepicker.parseDate = function (format, value, settings) {
    if (format != "M y") return jQuery.datepicker._hvnbase_parseDate(format, value, settings);
    // "M y" on parse gives error as doesn't have a day value, so 'hack' it by simply adding a day component
    return jQuery.datepicker._hvnbase_parseDate("d " + format, "1 " + value, settings);
};

Как было сказано, это старый вопрос, но я счел его полезным, поэтому хотел добавить обратную связь с альтернативным решением.

Ответ 24

для monthpicker, используя JQuery v 1.7.2, у меня есть следующий javascript, который делает именно это

$l("[id$=txtDtPicker]").monthpicker({
showOn: "both",
buttonImage: "../../images/Calendar.png",
buttonImageOnly: true,
pattern: 'yyyymm', // Default is 'mm/yyyy' and separator char is not mandatory
monthNames: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
});

Ответ 25

Каждый здесь получает значение месяца, года, подобного этому,

var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var month = $("#ui-datepicker-div .ui-datepicker-year :selected").val();

Но сейчас я сталкиваюсь с проблемой при извлечении значений из > и <. Потому что оно дает нам значение выбранного значения в выпадающем списке, поэтому оно дает нам значения old not new.

Итак, согласно документу JQuery UI: - http://api.jqueryui.com/datepicker/. Мы можем напрямую получать год, месяц из функции. Для других значений, таких как day и т.д., мы можем легко получить к ним доступ через inst объект функции jqueryUI. Мы можем получить доступ к inst, как показано ниже,

 var day = inst.selectedDay;

Итак, используя onChangeMonthYear, мы можем получать текущие значения месяца, года и дня непосредственно из функции, поэтому нет необходимости выработать выбранное значение.

HTML: -

<input type='text' class='monthpicker'>

Script: -

$( function() {
    $(".monthPicker").datepicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        beforeShow: true,
        onChangeMonthYear: function(year , month , inst) {

            setTimeout(function() {
               $('.ui-datepicker-calendar').hide();
            });
            var day = inst.selectedDay;
            month = month;
            year = year;
            var current_date =  year + "-" + month + "-" + day ;                
        }
    });
    $(".monthPicker").focus(function () {
        $(".ui-datepicker-calendar").hide();
        $("#ui-datepicker-div").position({
            my: "center top",
            at: "center bottom",
            of: $(this)
        });
    });
});

Примечание: - Это может быть полезно, когда мы хотим встроить месяцпиксера. Просто замените поле ввода на деление, и мы можем использовать его inline при использовании inline, убедитесь, что вы используете onChangeMonthYear,

Для Inline MonthPicker: -

<div class="monthpicker">  </div>

Ответ 26

Спасибо за решение Бен Кёлер.

Тем не менее, у меня была проблема с несколькими экземплярами datepickers, некоторые из которых были необходимы при выборе дня. Решение Ben Koehler (в редакции 3) работает, но скрывает выбор дня во всех случаях. Вот обновление, которое решает эту проблему:

$('.date-picker').datepicker({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function(dateText, inst) {
        if($('#ui-datepicker-div').html().indexOf('ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all ui-state-hover') > -1) {
            $(this).datepicker(
                'setDate',
                new Date(
                    $("#ui-datepicker-div .ui-datepicker-year :selected").val(),
                    $("#ui-datepicker-div .ui-datepicker-month :selected").val(),
                    1
                )
            ).trigger('change');
            $('.date-picker').focusout();
        }
        $("#ui-datepicker-div").removeClass("month_year_datepicker");
    },
    beforeShow : function(input, inst) {
        if((datestr = $(this).val()).length > 0) {
            year = datestr.substring(datestr.length-4, datestr.length);
            month = datestr.substring(0, 2);
            $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
            $(this).datepicker('setDate', new Date(year, month-1, 1));
            $("#ui-datepicker-div").addClass("month_year_datepicker");
        }
    }
});

Ответ 27

Используйте onSelect перезвонить и удалить часть года вручную и вручную установить текст в поле