I know, big surprise, something stops working in facebox. In this case, it’s datepicker, which is actually a pretty nice little date selection plugin. Unfortunately, it uses HTML element ID attributes in order to function, and that means it all falls apart when facebox clones the HTML. After fiddling with it for a while, I figured out the following:
First, you have to deal with that pesky ID problem. Thankfully, you can use jQuery selectors to find the datepicker fields, and then the plugin will determine the IDs dynamically. Which means you don’t have to know the IDs before hand. So, you just bind a method to the facebox.reveal event to change the IDs, like so:
jQuery(document).bind('reveal.facebox', function() {
jQuery('#facebox .datepicker').each( function(intIndex){
jQuery(this).attr('id',jQuery(this).attr('id') + '-2')
});
});
Of course, it is possible that those field IDs are important to you, In which case, when you need to refer to them you should remember that you appended that ‘-2′ to the end of the ID.
The next problem is that datepicker initiates after the page loads, which means that when facebox clones the HTML to display, the new date field won’t have initialized. This is simply solved by adding some more code to the binding the initialize method to the facebox.reveal event, instead of the page load. Like so:
jQuery(document).bind('reveal.facebox', function() {
jQuery('#facebox .datepicker').each( function(intIndex){
jQuery(this).attr('id',jQuery(this).attr('id') + '-2')
});
jQuery('#facebox .datepicker').datepick({
alignment: 'bottomLeft',
buttonImageOnly: true,
buttonImage: '/images/calendar_date_select/calendar.gif',
showOn: 'both',
showStatus: true
});
jQuery('#facebox [name=field_name]').datepick('option', 'onSelect', function(value, date) {
jQuery('#facebox [name=field_name]').val(value);
});
});
There you go, now it initializes when the facebox loads. Problem solved.
Or is it?
It just happens that my particular implementation involved more than one facebox, each with it’s own datepicker. Suddenly, all of my well thought out hacks fall apart, and nothing works again.
There’s probably a prettier way to fix this, but I needed the solution to be modular. A given facebox might appear on one page by itself, and on another page with several others. I needed to solve the conflict without breaking the independence, so I ended up wrapping the whole script in an if statement that checks for an element on a given form.
jQuery(document).bind('reveal.facebox', function() {
if(jQuery('#facebox [name=model[field]]').length>0){
jQuery('#facebox .datepicker').each( function(intIndex){
jQuery(this).attr('id',jQuery(this).attr('id') + '-2')
});
jQuery('#facebox .datepicker').datepick({
alignment: 'bottomLeft',
buttonImageOnly: true,
buttonImage: '/images/calendar_date_select/calendar.gif',
showOn: 'both',
showStatus: true
});
jQuery('#facebox [name=field_name]').datepick('option', 'onSelect', function(value, date) {
jQuery('#facebox [name=field_name]').val(value);
});
}
});
Not pretty, I know. Especially, since the above code is replicated everywhere a facebox with a datepicker field appears on the page, sometimes multiple times on one page. It works, though. That’s the important thing, right?