jQuery Datepicker 在选定日期后关闭 datepicker

Posted

技术标签:

【中文标题】jQuery Datepicker 在选定日期后关闭 datepicker【英文标题】:jQuery Datepicker close datepicker after selected date 【发布时间】:2014-07-25 06:20:49 【问题描述】:

html

<div class="container">
  <div class="hero-unit">
    <input type="text" placeholder="click to show datepicker" id="example1">
  </div>
</div>

jQuery:

<script type="text/javascript">
  $(document).ready(function () 
    $('#example1').datepicker(
      format: "dd/mm/yyyy"
    );
  );
</script>

我使用引导日期选择器。

当我点击日期选择器时,它会打开并选择任何日期。

我的问题:

如果我从 datepicker 中选择日期,我想关闭 datepicker 弹出窗口。

我需要使用哪个事件来在选择日期关闭日期选择器?

已编辑:

我找到了解决办法

这行得通

 $(document).mouseup(function (e) 

        $('#example1').Close();

    );

但是这个下面为什么不起作用?

 $('#example1').datepicker().on('changeDate', function (ev) 

        $('#example1').Close();

    );

【问题讨论】:

$('#example1').datepicker().on('changeDate', function (ev) $('#example1').Close(); );不起作用为什么请任何帮助 你不必替换所有的东西......看看我的帖子^^ 嗯,你的解决方案是一个很好的解决方案,但是如果你想使用很多 datepicker 组件,你需要为每个输入添加一个函数,当然还要修改 html。 【参考方案1】:

其实你不需要全部替换(@Ben Rhouma Zied answere)....

有两种方法可以做到这一点。一种是使用 autoclose 属性,另一种(替代)方法是使用在选择日期时由输入触发的 on change 属性。

HTML

<div class="container">
    <div class="hero-unit">
        <input type="text" placeholder="Sample 1: Click to show datepicker" id="example1">
    </div>
    <div class="hero-unit">
        <input type="text" placeholder="Sample 2: Click to show datepicker" id="example2">
    </div>
</div>

jQuery

$(document).ready(function () 
    $('#example1').datepicker(
        format: "dd/mm/yyyy",
        autoclose: true
    );

    //Alternativ way
    $('#example2').datepicker(
      format: "dd/mm/yyyy"
    ).on('change', function()
        $('.datepicker').hide();
    );

);

这就是你所要做的:)

HERE IS A FIDDLE 看看发生了什么。

2016 年 7 月 13 日的 Fiddleupdate:CDN 不再存在

根据您的编辑:

$('#example1').datepicker().on('changeDate', function (ev) 
    $('#example1').Close();
);

在这里,您获取输入(没有关闭功能)并创建一个 Datepicker-Element。如果元素发生变化,您想关闭它,但您仍然尝试关闭输入(没有关闭功能)。

将 mouseup 事件绑定到文档状态可能不是最好的主意,因为您将在每次点击时触发所有包含的脚本!

就是这样:)

编辑:2017 年 8 月(添加了 ***Fiddle aka Snippet。与帖子顶部相同)

$(document).ready(function () 
    $('#example1').datepicker(
        format: "dd/mm/yyyy",
        autoclose: true
    );

    //Alternativ way
    $('#example2').datepicker(
      format: "dd/mm/yyyy"
    ).on('change', function()
        $('.datepicker').hide();
    );
);
.hero-unit
  float: left;
  width: 210px;
  margin-right: 25px;

.hero-unit input
  width: 100%;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="container">
    <div class="hero-unit">
        <input type="text" placeholder="Sample 1: Click to show datepicker" id="example1">
    </div>
    <div class="hero-unit">
        <input type="text" placeholder="Sample 2: Click to show datepicker" id="example2">
    </div>
</div>

编辑:2018 年 12 月显然 Bootstrap-Datepicker 不适用于 jQuery 3.x see this to fix

【讨论】:

如果您只想在选择一天时隐藏,您可以使用 if (ev.viewMode == 'days') $(this).datepicker('hide'); 'autoclose:true' 搞定了。 它是documented in Bootstrap,但显然也适用于没有真正记录的jQuery。 @Dwza 我们如何在 ionic 2 中使用您对 datepicker 的回答,您能帮我们吗,我们需要在 ionic 2 应用程序中执行此日期选择器,所以请帮助我们......然后我们在***中也提出了问题,请注意这一点并帮助我们:-***.com/questions/41610110/… ....谢谢... @R.ManiSelvam 我知道它有点晚了,我也真的不知道 ionic 但阅读它的文档会带来一些可能有帮助的信息。见github.com/VitaliiBlagodir/cordova-plugin-datepicker 显然有两个回调函数可以被传递。一个代表成功,一个代表错误。在那里,您可以轻松处理日期选择器的行为。其实我只是猜测,因为我没有任何方法可以测试它。【参考方案2】:

这是我编辑的版本:你只需要添加一个额外的参数“autoClose”。

示例:

 $('input[name="fieldName"]').datepicker( autoClose: true);

您也可以根据需要指定关闭回调。 :)

用这个替换 datepicker.js:

!function( $ ) 

// Picker object

var Datepicker = function(element, options , closeCallBack)
    this.element = $(element);
    this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'dd/mm/yyyy');
    this.autoClose = options.autoClose||this.element.data('date-autoClose')|| true;
    this.closeCallback = closeCallBack || function();
    this.picker = $(DPGlobal.template)
                        .appendTo('body')
                        .on(
                            click: $.proxy(this.click, this)//,
                            //mousedown: $.proxy(this.mousedown, this)
                        );
    this.isInput = this.element.is('input');
    this.component = this.element.is('.date') ? this.element.find('.add-on') : false;

    if (this.isInput) 
        this.element.on(
            focus: $.proxy(this.show, this),
            //blur: $.proxy(this.hide, this),
            keyup: $.proxy(this.update, this)
        );
     else 
        if (this.component)
            this.component.on('click', $.proxy(this.show, this));
         else 
            this.element.on('click', $.proxy(this.show, this));
        
    

    this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
    if (typeof this.minViewMode === 'string') 
        switch (this.minViewMode) 
            case 'months':
                this.minViewMode = 1;
                break;
            case 'years':
                this.minViewMode = 2;
                break;
            default:
                this.minViewMode = 0;
                break;
        
    
    this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
    if (typeof this.viewMode === 'string') 
        switch (this.viewMode) 
            case 'months':
                this.viewMode = 1;
                break;
            case 'years':
                this.viewMode = 2;
                break;
            default:
                this.viewMode = 0;
                break;
        
    
    this.startViewMode = this.viewMode;
    this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
    this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
    this.onRender = options.onRender;
    this.fillDow();
    this.fillMonths();
    this.update();
    this.showMode();
;

Datepicker.prototype = 
    constructor: Datepicker,

    show: function(e) 
        this.picker.show();
        this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
        this.place();
        $(window).on('resize', $.proxy(this.place, this));
        if (e ) 
            e.stopPropagation();
            e.preventDefault();
        
        if (!this.isInput) 
        
        var that = this;
        $(document).on('mousedown', function(ev)
            if ($(ev.target).closest('.datepicker').length == 0) 
                that.hide();
            
        );
        this.element.trigger(
            type: 'show',
            date: this.date
        );
    ,

    hide: function()
        this.picker.hide();
        $(window).off('resize', this.place);
        this.viewMode = this.startViewMode;
        this.showMode();
        if (!this.isInput) 
            $(document).off('mousedown', this.hide);
        
        //this.set();
        this.element.trigger(
            type: 'hide',
            date: this.date
        );
    ,

    set: function() 
        var formated = DPGlobal.formatDate(this.date, this.format);
        if (!this.isInput) 
            if (this.component)
                this.element.find('input').prop('value', formated);
            
            this.element.data('date', formated);
         else 
            this.element.prop('value', formated);
        
    ,

    setValue: function(newDate) 
        if (typeof newDate === 'string') 
            this.date = DPGlobal.parseDate(newDate, this.format);
         else 
            this.date = new Date(newDate);
        
        this.set();
        this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
        this.fill();
    ,

    place: function()
        var offset = this.component ? this.component.offset() : this.element.offset();
        this.picker.css(
            top: offset.top + this.height,
            left: offset.left
        );
    ,

    update: function(newDate)
        this.date = DPGlobal.parseDate(
            typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
            this.format
        );
        this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
        this.fill();
    ,

    fillDow: function()
        var dowCnt = this.weekStart;
        var html = '<tr>';
        while (dowCnt < this.weekStart + 7) 
            html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
        
        html += '</tr>';
        this.picker.find('.datepicker-days thead').append(html);
    ,

    fillMonths: function()
        var html = '';
        var i = 0
        while (i < 12) 
            html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
        
        this.picker.find('.datepicker-months td').append(html);
    ,

    fill: function() 
        var d = new Date(this.viewDate),
            year = d.getFullYear(),
            month = d.getMonth(),
            currentDate = this.date.valueOf();
        this.picker.find('.datepicker-days th:eq(1)')
                    .text(DPGlobal.dates.months[month]+' '+year);
        var prevMonth = new Date(year, month-1, 28,0,0,0,0),
            day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
        prevMonth.setDate(day);
        prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
        var nextMonth = new Date(prevMonth);
        nextMonth.setDate(nextMonth.getDate() + 42);
        nextMonth = nextMonth.valueOf();
        var html = [];
        var clsName,
            prevY,
            prevM;
        while(prevMonth.valueOf() < nextMonth) zs
            if (prevMonth.getDay() === this.weekStart) 
                html.push('<tr>');
            
            clsName = this.onRender(prevMonth);
            prevY = prevMonth.getFullYear();
            prevM = prevMonth.getMonth();
            if ((prevM < month &&  prevY === year) ||  prevY < year) 
                clsName += ' old';
             else if ((prevM > month && prevY === year) || prevY > year) 
                clsName += ' new';
            
            if (prevMonth.valueOf() === currentDate) 
                clsName += ' active';
            
            html.push('<td class="day '+clsName+'">'+prevMonth.getDate() + '</td>');
            if (prevMonth.getDay() === this.weekEnd) 
                html.push('</tr>');
            
            prevMonth.setDate(prevMonth.getDate()+1);
        
        this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
        var currentYear = this.date.getFullYear();

        var months = this.picker.find('.datepicker-months')
                    .find('th:eq(1)')
                        .text(year)
                        .end()
                    .find('span').removeClass('active');
        if (currentYear === year) 
            months.eq(this.date.getMonth()).addClass('active');
        

        html = '';
        year = parseInt(year/10, 10) * 10;
        var yearCont = this.picker.find('.datepicker-years')
                            .find('th:eq(1)')
                                .text(year + '-' + (year + 9))
                                .end()
                            .find('td');
        year -= 1;
        for (var i = -1; i < 11; i++) 
            html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
            year += 1;
        
        yearCont.html(html);
    ,

    click: function(e) 
        e.stopPropagation();
        e.preventDefault();
        var target = $(e.target).closest('span, td, th');
        if (target.length === 1) 
            switch(target[0].nodeName.toLowerCase()) 
                case 'th':
                    switch(target[0].className) 
                        case 'switch':
                            this.showMode(1);
                            break;
                        case 'prev':
                        case 'next':
                            this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
                                this.viewDate,
                                this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) + 
                                DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
                            );
                            this.fill();
                            this.set();
                            break;
                    
                    break;
                case 'span':
                    if (target.is('.month')) 
                        var month = target.parent().find('span').index(target);
                        this.viewDate.setMonth(month);
                     else 
                        var year = parseInt(target.text(), 10)||0;
                        this.viewDate.setFullYear(year);
                    
                    if (this.viewMode !== 0) 
                        this.date = new Date(this.viewDate);
                        this.element.trigger(
                            type: 'changeDate',
                            date: this.date,
                            viewMode: DPGlobal.modes[this.viewMode].clsName
                        );
                    
                    this.showMode(-1);
                    this.fill();
                    this.set();
                    break;
                case 'td':
                    if (target.is('.day') && !target.is('.disabled'))
                        var day = parseInt(target.text(), 10)||1;
                        var month = this.viewDate.getMonth();
                        if (target.is('.old')) 
                            month -= 1;
                         else if (target.is('.new')) 
                            month += 1;
                        
                        var year = this.viewDate.getFullYear();
                        this.date = new Date(year, month, day,0,0,0,0);
                        this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
                        this.fill();
                        this.set();
                        this.element.trigger(
                            type: 'changeDate',
                            date: this.date,
                            viewMode: DPGlobal.modes[this.viewMode].clsName
                        );
                        if(this.autoClose === true)
                            this.hide();
                            this.closeCallback();
                        

                    
                    break;
            
        
    ,

    mousedown: function(e)
        e.stopPropagation();
        e.preventDefault();
    ,

    showMode: function(dir) 
        if (dir) 
            this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
        
        this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
    
;

$.fn.datepicker = function ( option, val ) 
    return this.each(function () 
        var $this = $(this);
        var datePicker = $this.data('datepicker');
        var options = typeof option === 'object' && option;
        if (!datePicker) 
            if (typeof val === 'function')
                $this.data('datepicker', (datePicker = new Datepicker(this, $.extend(, $.fn.datepicker.defaults,options),val)));
            else
                $this.data('datepicker', (datePicker = new Datepicker(this, $.extend(, $.fn.datepicker.defaults,options))));
            
        
        if (typeof option === 'string') datePicker[option](val);

    );
;

$.fn.datepicker.defaults = 
    onRender: function(date) 
        return '';
    
;
$.fn.datepicker.Constructor = Datepicker;

var DPGlobal = 
    modes: [
        
            clsName: 'days',
            navFnc: 'Month',
            navStep: 1
        ,
        
            clsName: 'months',
            navFnc: 'FullYear',
            navStep: 1
        ,
        
            clsName: 'years',
            navFnc: 'FullYear',
            navStep: 10
    ],
    dates:
        days: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"],
                    daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"],
                    daysMin: ["D", "L", "Ma", "Me", "J", "V", "S", "D"],
                    months: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
                    monthsShort: ["Jan", "Fév", "Mar", "Avr", "Mai", "Jui", "Jul", "Aou", "Sep", "Oct", "Nov", "Déc"],
                    today: "Aujourd'hui",
                    clear: "Effacer",
                    weekStart: 1,
                    format: "dd/mm/yyyy"
    ,
    isLeapYear: function (year) 
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
    ,
    getDaysInMonth: function (year, month) 
        return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
    ,
    parseFormat: function(format)
        var separator = format.match(/[.\/\-\s].*?/),
            parts = format.split(/\W+/);
        if (!separator || !parts || parts.length === 0)
            throw new Error("Invalid date format.");
        
        return separator: separator, parts: parts;
    ,
    parseDate: function(date, format) 
        var parts = date.split(format.separator),
            date = new Date(),
            val;
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setMilliseconds(0);
        if (parts.length === format.parts.length) 
            var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
            for (var i=0, cnt = format.parts.length; i < cnt; i++) 
                val = parseInt(parts[i], 10)||1;
                switch(format.parts[i]) 
                    case 'dd':
                    case 'd':
                        day = val;
                        date.setDate(val);
                        break;
                    case 'mm':
                    case 'm':
                        month = val - 1;
                        date.setMonth(val - 1);
                        break;
                    case 'yy':
                        year = 2000 + val;
                        date.setFullYear(2000 + val);
                        break;
                    case 'yyyy':
                        year = val;
                        date.setFullYear(val);
                        break;
                
            
            date = new Date(year, month, day, 0 ,0 ,0);
        
        return date;
    ,
    formatDate: function(date, format)
        var val = 
            d: date.getDate(),
            m: date.getMonth() + 1,
            yy: date.getFullYear().toString().substring(2),
            yyyy: date.getFullYear()
        ;
        val.dd = (val.d < 10 ? '0' : '') + val.d;
        val.mm = (val.m < 10 ? '0' : '') + val.m;
        var date = [];
        for (var i=0, cnt = format.parts.length; i < cnt; i++) 
            date.push(val[format.parts[i]]);
        
        return date.join(format.separator);
    ,
    headTemplate: '<thead>'+
                        '<tr>'+
                            '<th class="prev">&lsaquo;</th>'+
                            '<th colspan="5" class="switch"></th>'+
                            '<th class="next">&rsaquo;</th>'+
                        '</tr>'+
                    '</thead>',
    contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
;
DPGlobal.template = '<div class="datepicker dropdown-menu">'+
                        '<div class="datepicker-days">'+
                            '<table class=" table-condensed">'+
                                DPGlobal.headTemplate+
                                '<tbody></tbody>'+
                            '</table>'+
                        '</div>'+
                        '<div class="datepicker-months">'+
                            '<table class="table-condensed">'+
                                DPGlobal.headTemplate+
                                DPGlobal.contTemplate+
                            '</table>'+
                        '</div>'+
                        '<div class="datepicker-years">'+
                            '<table class="table-condensed">'+
                                DPGlobal.headTemplate+
                                DPGlobal.contTemplate+
                            '</table>'+
                        '</div>'+
                    '</div>';

( window.jQuery );

【讨论】:

【参考方案3】:

还有另一个代码对我有用(jQuery)。

$(".datepicker").datepicker(
    format: "dd/mm/yyyy",
    autoHide: true
    )
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.css" />
Date: <input type="text" readonly="true" class="datepicker">

【讨论】:

自动隐藏:对我来说。没有大写字母。【参考方案4】:

上面的答案在 Chrome 上对我不起作用。在我单击某个字段之外的某个字段后,更改事件被触发,这没有帮助,因为当您单击该字段时,日期选择器窗口也关闭了。

我确实使用了这段代码,而且效果很好。拨打.datepicker();后即可放置

HTML

<input type="text" class="datepicker-input" placeholder="click to show datepicker" />

JavaScript

$(".datepicker-input").each(function() 
    $(this).datepicker();
);

$(".datepicker-input").click(function() 
    $(".datepicker-days .day").click(function() 
        $('.datepicker').hide();
    );
);

【讨论】:

【参考方案5】:

只需将此选项添加到 Datepicker 组件:

forceParse: 假

例子:

 $('.datepicker').datepicker(
    format: 'mm/dd/yyyy',
    defaultDate: 'now',
    forceParse: false,
    endDate: "today"
  );

【讨论】:

以上是关于jQuery Datepicker 在选定日期后关闭 datepicker的主要内容,如果未能解决你的问题,请参考以下文章

防止在选定的 Jquery Datepicker 日期上选择日期

jQuery:在 Datepicker 中为选定的日期添加样式

突出显示两个选定日期之间的日期 jQuery UI Datepicker

JQuery Datepicker 获取选定日期

如何从 jquery datepicker 中获取选定的日期

jQuery UI Datepicker - 选定日期之后的颜色日期