Hi fellow stackoverflow:ers,
I'm using the jQuery Datepicker plugin, together with Martin Milesich Timepicker plugin. Everything works great, except for the fact that clicking a date in the datepicker, closes the widget, leaving no time to pick the time.
Question: So I'm wondering if there's a way to prevent the widget from closing when clicking a date, and instead force users to click the "Done" button (that shows up when enabling the "showButtonPanel: true" option), or clicking outside of the widget. I don't want my users having to open the widget twice! See the behavior online at the timepicker demo
Any help solving this issue, or even pointers in the right direction, is appreciated!
More info: I'm using the files supplied from Martins download link: http://milesich.com/tpdemo/timepicker-0.2.0.zip
- jquery-ui-1.7.2.custom.min.js
- timepicker.js (latest version 0.2.0)
These are the options I'm using:
$(document).ready(function(){
$(".datepicker").datepicker({
duration: '',
showTime: true,
constrainInput: false,
stepMinutes: 5,
stepHours: 1,
time24h: true,
dateFormat: "yy-mm-dd",
buttonImage: '/static/images/datepicker.png',
buttonImageOnly: true,
firstDay: 1,
monthNames: ['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December'],
showOn: 'both',
showButtonPanel: true
});
})
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!
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);
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.
来源:https://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date