#ruby-on-rails #formtastic
#ruby-on-rails #formtastic
Вопрос:
У меня есть форма formtastic, подобная следующей:
= semantic_form_for @record, :remote => true, :id => 'my_form', :url => ...
Поскольку я использую:remote => true, я обрабатываю ответ от контроллера в 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){
});
С помощью:remote => false моя форма автоматически отображает ошибки проверки полей, возникающие при попытке сохранить запись в контроллере, вот так:
@record = Record.new(params[:record])
@record.save
Как мне сделать так, чтобы ошибки проверки полей formtastic отображались с помощью:remote => true, где я сам обрабатываю ответ в javascript?
Ответ №1:
Поместите formtastic form в представление отдельно.
В действии контроллера, которое обрабатывает опубликованную форму, вы можете повторно «отобразить» представление при сбое сохранения записи. Когда представление будет отрисовано, formtastic просмотрит поле ошибок в @record и отобразит ошибки проверки. Если сохранение выполнено успешно, вы можете отобразить пустую строку, указывающую на успех. (Возможна более сложная схема ответа в зависимости от того, что вам нужно.)
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
Затем, в клиентском javascript, когда запись не удается сохранить, вы можете заменить существующую форму отображаемым видом, переданным обратно из контроллера.
// 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();
Ответ №2:
Поскольку вы используете javascript для публикации формы, я бы предложил выполнить проверку на стороне клиента перед отправкой каких-либо данных. Проверьте https://github.com/bcardarella/client_side_validations
Комментарии:
1. Большое спасибо за ссылку на такой приятный камень 🙂 Работает как шарм 🙂 1 🙂
Ответ №3:
Ответ Эдвардса — лучший способ сделать это, поскольку он использует Formtastic для добавления ошибок. В случае, если у вас (как и у меня) есть очень динамичная форма, которая добавляет поля во время заполнения и извлекает изображения и данные на основе значений, которые вводит пользователь, это не вариант.
Я нашел эту суть, которая прекрасно показывает, как добавлять ошибки таким же образом, как их добавлял бы Formtastic: https://gist.github.com/2083155/172ce92caa8d4ee738c32e72e27945e17c909428
Однако имейте в виду, что это дублирует логику, содержащуюся в Formtastic, что никогда не является оптимальным решением. Если способ отображения ошибок в Formtastic изменится в какой-то момент в будущем, вам придется скорректировать этот код вручную.