The easiest way that I've found to get AJAX working with forms in SS is to use the jquery form plugin. In the init() function of your controller, add:
Requirements::block('jsparty/prototype.js');
Requirements::javascript('jsparty/jquery/jquery.js');
Requirements::javascript("jsparty/jquery/plugins/form/jquery.form.js");
Now you have the form plugin functions at your fingertips. You don't have to change the Form() function in your controller at all (or any of the functions that you're using to create forms) - jquery will handle it all. You should take a look at the jquery form plugin docs and sample code:
http://malsup.com/jquery/form/#getting-started
The basic idea is that you'll also include (i.e. Requirements::javascript(...) in the init()) another file that contains the custom ajax behaviors for your particular case. The syntax is very simple, using the jquery form plugin. It might look something like this:
$(document).ready(function() {
var options = {
target: '#FormContainer', // target element(s) to be updated with server response
beforeSubmit: showLoading, // pre-submit callback
success: showResponse, // post-submit callback
// other available options:
//url: url // override for form's 'action' attribute
//type: type // 'get' or 'post', override for form's 'method' attribute
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
//clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
// $.ajax options can be used here too, for example:
//timeout: 3000
};
$('#Form_Form').ajaxForm(options);
});
function showLoading(formData, jqForm, options) {
$("#FormStatus").html("Loading...");
}
function showResponse(formData, jqForm, options) {
$("#FormStatus").html("The first step has been saved. Please continue:");
}
By default the .ajaxForm() function will send all the form fields to the action defined by the form, in other words the $action you passed to the Form() in your controller. All of the form data can be accessed by your controller via a single parameter, so your action might look like this:
function doForm($params) {
//for example, if one of the form fields was FirstName
$member = new Member();
$member->FirstName = $params["FirstName"];
if($member->write()) {
if(Director->is_ajax()) {
return "Thanks, you've completed the form!";
} else {
return Array(); //returns the normal template - you could do something else here.
}
}
return Array("Title"=>"Error", "Content"=>"Houston, we have a problem saving the member.", "Form"=>"");
}
Ok? So if the action has been called via ajax, whatever value gets returned will be displayed in the DOM element you specified in your options in the javascript (the 'target' option).
I do wish the documentation for ajax use in SS was a bit better... for that matter, I wish there were Javascript/AJAX helper classes in the SilverStripe core that would eliminate some of the actual javascript one needed to write (like the symfony framework, for instance). Until then, this method seems to work well for handling form data with AJAX. Good luck!