jQuery Datepicker: Prevent closing picker when clicking a date

不羁岁月 提交于 2019-11-27 01:58:29

rather than changing the source it's best to use the existing events

onSelect: function() {
    $(this).data('datepicker').inline = true;                               
},
onClose: function() {
    $(this).data('datepicker').inline = false;
}

For reference, and since people have asked me this through mail. Here's a code chunk that needs to be added to timepicker.js:

/**
 * Don't hide the date picker when clicking a date
 */
$.datepicker._selectDateOverload = $.datepicker._selectDate;
$.datepicker._selectDate = function(id, dateStr) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    inst.inline = true;
    $.datepicker._selectDateOverload(id, dateStr);
    inst.inline = false;
    this._updateDatepicker(inst);
}

Good luck in getting it working on your site!

redsquare

You will have to hack the datepicker yourself. This is the code it uses. If it is not inline it will hide when you select a date.

You could pass in your own onSelect method and quickly change the datePicker instance to be inline and then change it back without having to change the datepicker internals but it is a very hacky solution.

if (inst.inline)
        this._updateDatepicker(inst);
else {
      this._hideDatepicker(null, this._get(inst, 'duration'));
      this._lastInput = inst.input[0];
      if (typeof(inst.input[0]) != 'object')
      inst.input[0].focus(); // restore focus
      this._lastInput = null;
}

Here is a solution :

onSelect: function ( dateText, inst ) {
    ..... // Your code like $(this).val( dateText );`


    //Set inline to true to force "no close"
    inst.inline = true;
},
onClose: function(date,inst){
    //Set inline to false => datapicker is closed
    // onClose is called only if you click outside the datapicker, onSelect will not
    // trig onClose due to inline = true
   inst.inline = false;
}

`

Why all comments provide workaround? it is straigtfarword:

Use inline calendar with altField :)

    <input type="text" id="alternate" size="30" />
    <div id="datepicker"></div>

    <script>
       $("#datepicker").datepicker({
          altField: "#alternate"
       });
    </script>

check this fiddle: http://jsfiddle.net/menocomp/y2s662b0/1/

Cool, if you are using jquery-ui-1.8.5.custom.min.js and jquery-ui.multidatespicker.js, you could modify the jquery-ui-1.8.5.custom.min.js: from:

if(a.inline)this._updateDatepicker(a);

into:

if(a.inline || !this._get(a, 'closeOnSelect'))this._updateDatepicker(a);

well this a dirty workaround...but it works for me...even with showButtonPanel: true

  $(function() {
    var dp_c = null, dp_once = false;
    $( '#datepicker' ).datepicker({
      showButtonPanel: true,
      onSelect: function() {
        $(this).data('datepicker').inline = true;  
        setTimeout(function () {
          $('#ui-datepicker-div').find('.ui-datepicker-buttonpane').append(dp_c);
        }, 1);

      },
      onClose: function() {
        $(this).data('datepicker').inline = false;
      }
    }).click(function () {
      if(!dp_once) {
        setTimeout(function () {
          dp_c = $('#ui-datepicker-div').find('.ui-datepicker-close').clone();
        }, 500);
        dp_once = !!1;
      }
    });

    $('#ui-datepicker-div').on('click', '.ui-datepicker-close', function () {
      $('#datepicker').datepicker( "hide" );
    });

  });

You should override native js function:

 /* Update the input field with the selected date. */
        _selectDate: function(id, dateStr) {
            var target = $(id);
            var inst = this._getInst(target[0]);
            dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
            if (inst.input)
                inst.input.val(dateStr);
            this._updateAlternate(inst);
            var onSelect = this._get(inst, 'onSelect');
            if (onSelect)
                onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
            else if (inst.input)
                inst.input.trigger('change'); // fire the change event
            if (inst.inline)
                this._updateDatepicker(inst);
            else {
                if(inst.settings.hideOnSelect != false){
                    this._hideDatepicker();
                }
                this._lastInput = inst.input[0];
                if (typeof(inst.input[0]) != 'object')
                    inst.input.focus(); // restore focus
                this._lastInput = null;
            }
        },

And add appropriate option to datepicker configuration, as example:

var defaultDatePickerOptions = {
        hideOnSelect: false,
        ...
    }; 
 var birthDate = jQuery.extend({}, defaultDatePickerOptions);
 $('#birthdate').datepicker(birthDate);
FernandoEscher

Following with what Emil suggested, I found a nicer and easier way to modify the widget to support a not closing widget on select event.

First, I added another property to the defaults dict on the widget:

closeOnSelect:true //True to close the widget when you select a date

Second, find this statement in the _selectDate method:

if (inst.inline)
        this._updateDatepicker(inst);
else {
        ...
    }

And change the condition to be like this:

var closeOnSelect = this._get(inst, "closeOnSelect");        
if (inst.inline || !closeOnSelect)
        this._updateDatepicker(inst);
else {
        ...
    }

Give it a try, it is working for me. I did it over the JQuery UI 1.8.5 version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!