jQuery Datepicker: Prevent hide on date select
A user from PHP User Group Philippines posted a question on the forum asking how to prevent the jQuery Datepicker dialog from closing upon selection of a date. The date picker had the button panel enabled where clicking “Done” closes the dialog. It seems that the Datepicker plugin didn’t have a readily available way of enforcing the behavior.
Other users posted solutions – all making use of the onSelect callback. I tried to solve it too using the onSelect callback, but to no avail. I even tried to fool the datepicker to make it think that it was configured to be displayed inline (calling it on div instead of an input element makes it inline – always visible) but didn’t work (even if it did, I wouldn’t advice it since it is ugly). A solution from another user seemed to work but it was gave an error.
Feeling that I might need the same functionality (I’ve been working on projects that are quite jQuery UI heavy), I started digging into the plugin’s code to check what’s really going on. I found out that inside the onSelect callback, you cannot do anything about the date picker dialog closing. With the exception of inline datepickers – the dialog will always close after the onSelect callback is executed. Of course, introducing errors inside the callback would halt the entire process and prevent the dialog from closing – that’s what happened on the solution that almost worked. We’d like to avoid introducing another problem to solve a problem.
What I did was to patch the plugin: introduce a new configuration parameter to enable/disable the behavior and override the method responsible for processing the date selection to make use of this new parameter.
==
// Add new parameter called hideOnSelect // Defaults to true so we keep the original behavior // (always closing on select) $.datepicker._defaults.hideOnSelect = true; // Override the _selectDate method // Basically, I just copied the method from the // plugin source and added/edited some lines $.datepicker._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'); var hideOnSelect = this._get(inst, 'hideOnSelect'); 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 || !hideOnSelect) this._updateDatepicker(inst); else { this._hideDatepicker(); this._lastInput = inst.input[0]; if (typeof(inst.input[0]) != 'object') inst.input.focus(); // restore focus this._lastInput = null; } }
==
This one worked for me. Just include it after the plugin source, before any code the uses the plugin.
Note that the code is applicable for jQuery UI Datepicker 1.8.5. This might break when used on other versions so just check the _selectDate (or similar) method and make the necessary changes. I also suggest putting it in a separate javascript file and give it an obvious name like “datepicker.hideOnSelectPatch.js”. Doing so can give other developers (and yourself, in case you forget about the patch) an idea that something might break if a version change is made.
Thanks works. Not enough opportunities, change the date (day) by selecting another month (year), if the date (day) have been selected before. Or the ability to disable the OK button when changed a month or a year, but have not chosen a new day.
Sorry for my english
HI ,I tried the way that is being given above. I am using Inline Datepicker, I want require the solution for datepicker to be hide when date is selected. i.e it should redirect to another html.jsp.
plz. sugget me
@yogesh:
You can either use the onClose or onSelect callbacks.
@Dmitriy:
You can use a combination of onChangeMonthYear and onSelect callback for that. As for disabling the OK button, you might need to apply some modification on the datepicker code itself just like what was done in the post.