I have a formtastic form like the following:
= semantic_form_for @record, :remote => true, :id => 'my_form', :url => ...
Since I'm using :remote => true, I handle the response from the controller in javascript:
$('#my_form')
.bind("ajax:beforeSend", function(evt, xhr, settings){
})
.bind("ajax:success", function(evt, data, status, xhr){
$('#response').append(xhr.responseText);
})
.bind('ajax:complete', function(evt, xhr, status){
});
With :remote => false, my form automatically displays field validation errors resulting from trying to save the record in the controller like so:
@record = Record.new(params[:record])
@record.save
How do I make the formtastic field validation errors appear with :remote => true, where I'm handling the response myself in javascript?
Put the formtastic form in a view by itself.
In the controller action that handles the posted form, you can re-"render" the view when the record save fails. When the view is rendered, formtastic will look at the errors field in @record and display the validation errors. If the save succeeds, you can render an empty string to indicate success. (A more complex response scheme is possible depending on what you need.)
def save_record
if request.xhr? # form submitted using remote => true
respond_with do |format|
format.html do
if @record.save
# record saved successfully
render :text => "" # indicate success with empty response
else # error saving record; send back form with validation errors marked
render :template => '/path/to/record_form_view', :layout => false
end
end
end
return
end
#...
end
Then, in the client-side javascript, when the record fails to save, you can replace the existing form with the rendered view passed back from the controller.
// reference: http://www.alfajango.com/blog/rails-3-remote-links-and-forms/
function setup_record_form_bindings() {
$('#record_form_id')
.bind("ajax:beforeSend", function(evt, xhr, settings){
var $submitButton = $(this).find('input[name="commit"]');
$submitButton.get(0).value = "Submitting...";
})
.bind("ajax:success", function(evt, data, status, xhr){
if (xhr.responseText === "") { // successful save
// do somethign appropriate here
} else { // error saving
$('#record_form_id').remove(); // remove old form, to replace with form in responseText
$('#record_form_parent_id').append(xhr.responseText); // should be the newly rendered form (with validation errors shown)
setup_record_form_bindings();
}
})
.bind('ajax:complete', function(evt, xhr, status){
});
}
setup_record_form_bindings();