Today, I spent 2-hours trying to figure out the correct way to implement an AJAX based call with the wonderful Calendar Date Select plugin. Now I’m sure it’s totally my fault for being a Rails noob, but I couldn’t come up with squat on Google for how to use this plugin with an server side AJAX call. So here’s my write up on how to do it using remote_function.
According to the documentation, if I want to use an AJAX style call, I should use the onchange attribute, which executes some JavaScript for you. That’s cool, I can do that. But that’s not really that helpful for trying to update the server unless you use the Ajax.Updater() like these guys did. Alrighty, so now I’ve got to figure out my controller URL, build that in and then pass in some parameters to my JavaScript I’m writing inside my Rails code.
WRONG!
The first time I saw that I had to be writing JavaScript, I should have know I was trolling the wrong websites. I started to think and remembered that I used an AJAX call somewhere else in my code to sort a list. No dice. The implements sortable hides everything from me and again wasn’t even close to what I was looking for. More searching and I finally … FINALLY … found some bastion of sanity that said you are supposed to use remote_function to make AJAX based calls. I knew this was exactly what I was looking for when I saw the name and when I read that you don’t have to write JavaScript to make it work … it writes it for you.
Only there was a snag. Calendar Date Select’s onchange gives you the function $F(this) to retrieve the date. But it’s a JavaScript function, not a Rails function … so you have to some how get the JavaScript variable to be a Rails variable … going the other way is cake:
So now, I started search for how to make a JavaScript variable part of a Rail’s POST request. It’s the :with parameter. So now my call looks like:
< %= calendar_date_select_tag "show[date]",
date_no_time_format(@show.date).to_s,
:time => false,
:popup => "force", :hidden => true,
:onchange => remote_function(:update => "current_show_date",
:url => {:action => "update_show_date", :id => @show.id},
:with => "’date=’+$F(this)" )
%>
</span>
After 2-hours of trying to find this, I find the “F(this)” so true :-). Well, now another problem … the date is coming across as “Monday, January 1 2009.” Which I’m sure I can do all sorts of fun conversions on inside of the ruby code … but I don’t want to. It’s going in the database as a DateTime, it should be passed as an ISO date. But of course, there is no ISO date formate for Calendar Date Select. Fortunately, you can extend it and someone took the time to write an ISO formate for it … but they left it all busted to hell in the comments section. So I fixed it. Then I fixed all the jslint problems with it so it would actually work in IE. You can download it here, or copy it from here:
var hour;
var str = this.getFullYear() + "-" + Date.padded2(this.getMonth() + 1) + "-" +Date.padded2(this.getDate());
if (include_time) {
hour = this.getHours();
str += " " + this.getHours() + ":" + this.getPaddedMinutes();
}
return str;
};
Date.parseFormattedString = function (string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"( ([0-9]{1,2}):([0-9]{2})?" +
"?)?)?)?";
var d = string.match(new RegExp(regexp, "i"));
if (d === null) {
return Date.parse(string); // at least give javascript a crack at it.
}
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[0]) {
date.setSeconds(d[0]);
}
if (d[2]) {
date.setMilliseconds(Number("0." + d[2]));
}
if (d[4]) {
offset = (Number(d[6])) + Number(d[8]);
offset = ((d[5] == ‘-’) ? 1 : -1);
}
return date;
};
Drop in your as [project]/public/javascript/calendar_date_select/format_iso_date.js. Then add the following lines to your environment.rb:
CalendarDateSelect::FORMATS[:iso_date] = {
# Here’s the code to pass to Date#strftime
:date => "%Y-%m-%d",
:time => " %I:%M %p", # notice the space before time. If you want date and time to be seperated with a space, put the leading space here.
:javascript_include => "format_iso_date"
}
CalendarDateSelect.format = :iso_date
Lesson learned … if the path looks complex, it’s probably not the wrong way … but it’s more than likely not the right way.
Popularity: 71% [?]

Rick Altherr says:
Yes, I went down this same path when writing my first Rails app. After getting all of the site functional, but ugly as sin, I gave up. If you read enough guides and stumble onto the correct functions, Rails can be easy. The main problem is that there is no definitive guide for what everything does. The documentation is designed as a reference which means you need to know what you want to use before you can see what it does.
Then I started looking at what happens on the server side. Running CGIs directly from apache is generally a poor performer. There was a mod_ruby project similar to mod_perl, but they decided this was a bad direction and subsequently stopped development. FastCGI is purported to be a great savior for performance, but when I was playing with Rails, Apache 2.0 had no FastCGI support and it didn’t look like it was going to happen anytime soon. So, if you don’t mind a few seconds between pages, Rails is fine. I’m now headed in a direction designed more around having a dynamic backend that generates static pages. For things like blogs, calendars, etc, that puts the dynamic portion in the correct place, at the time of change, not on every view. Clearly for some types of sites, you still need all the dynamic pages for every view. I’m not sure what the best option there is, but I doubt I would choose Rails, PHP, or Perl ever again.
29 March 2008, 7:45 pmMike says:
@wyatt: Agreed about the docs. The recipes book may be more what you’re looking for.
@rick: Mongrel cluster behind Apache mod_proxy FTW.
30 March 2008, 8:05 am