我在Rails应用程序中使用Twitter Bootstrap框架。我正在努力解决的是如何在窗口中呈现错误而不重新加载页面。
以下是一个例子:
#modalEvent.modal.hide
.modal-header
%button.close{"data-dismiss" => "modal", :type => "button"} ×
%h3 Schedule Form
= form_for(@schedule, :html => { :class => "form-horizontal"}) do |f|
.modal-body
- if @schedule.errors.any?
#notice.alert.alert-error
%button.close{"data-dismiss" => "alert"} ×
%strong Error:
= pluralize(@schedule.errors.count, "error")
prohibited #{event_display(@schedule.event)} from being
saved:
%ul
- @schedule.errors.full_messages.each do |msg|
%li= msg
.widget-content.nopadding
.control-group
= f.label :event_type, :class =>'control-label'
.controls
= f.select :event, Schedule::EVENT_TYPES
#3{:style => 'display:none'}
.control-group
= f.label :name, :class =>'control-label'
.controls
= f.text_field :result_id, :class => "required error"
.control-group
= f.label :date_and_time, :class =>'control-label'
.controls
= f.text_field :time, :class => "datepicker", :required => :required, :type => :datetime, "data-date-format" =>"dd/mm/yyyy"
.control-group
= f.label :duration, :class =>'control-label'
.controls
.input-append
= f.number_field :duration, :placeholder => 'Time in Minutes', :required => :required
%span.add-on
%i.icon-time
%span.help-block Duration of event in minutes
.control-group
= f.label :arrival_time, :class =>'control-label'
.controls
.input-append
= f.number_field :arrival_time, :placeholder => 'Time in Minutes', :required => :required
%span.add-on
%i.icon-time
%span.help-block Time in minutes before event
.control-group
= f.label :location, :class =>'control-label'
.controls
= select("schedule", "location_id", Location.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
.control-group
= f.label :players, :class =>'control-label'
.controls
= select(:schedule, :selected_players, @players.map { |p| [full_name(p), p.id] }, {:include_blank => false}, "data-placeholder" => 'Add Players to Lineup', :prompt => 'Add Players to Lineup', :multiple => "multiple")
#1{:style => 'display:block'}
-if current_user.admin?
.control-group
= f.label :team, :class =>'control-label'
.controls
= select("schedule", "team_id", Team.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
- else
=f.hidden_field :team_id, :value => current_user.team_id
.control-group
= f.label :opponent, :class =>'control-label'
.controls
= select("schedule", "opponent_id", Opponent.all.collect { |p| [p.name, p.id] }, {:include_blank => 'None'})
.control-group
= f.label :home_or_away, :class =>'control-label'
.controls
= f.select :home_or_away, Schedule::HOME_OR_AWAY, {:include_blank => 'None'}
.modal-footer
= f.submit 'Save Event', :class => 'btn btn-primary'
%a.btn.btn-danger{"data-dismiss" => "modal", :href => "#"} Cancel
控制器
def create
@schedule = Schedule.new(params[:schedule])
@user = User.find(current_user)
@players = User.where(:team_id => current_user[:team_id]).all
respond_to do |format|
if @schedule.save
Notifier.event_added(@user,@schedule).deliver
format.html { redirect_to(schedules_url,
:notice => "#{event_display_c(@schedule.event)} vs #{@schedule.opponent.name} was successfully created.") }
format.json { render :json => @schedule, :status => :created, :location => @schedule }
else
format.html { render :action => "new" }
format.json { render :json => @schedule.errors, :status => :unprocessable_entity }
end
end
end
答案 0 :(得分:2)
如果您想避免页面重新加载并仍然显示服务器提供的错误消息,您必须以某种方式使用AJAX。我认为仍然没有一种正确的方法。你应该从谷歌搜索PJAX开始。您应该了解的另一件事是Rails提供unobtrusive JavaScript
另外我建议您尝试使用simple_form gem,这与AJAX无关但会简化您的观点;)
答案 1 :(得分:0)
虽然使用PHP / CodeIgniter而不是Rails,但我做了类似的事情,但我在模态窗口中使用了bootstrap。
我所做的是,在表单提交时,我将表单数据写入进程脚本然后验证数据 - 如果验证失败,则返回(通过JSON对象)包含错误的控制组类和要显示的可选错误消息。如果验证成功,它将执行您希望执行的任何操作,并简单地返回一个“成功”标志,该标志表示程序显示成功消息并关闭模态。
如果此示例对您有任何用处,请告诉我。如果是,我可以提供服务器端验证和我执行的输出的样本,虽然它不会在ruby中。
这是一个示例表单,采用bootstrap模式格式:
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Add Something</h3>
</div>
<div class="modal-body">
<form id="your_form">
<fieldset class="control-group id-group">
<label>Some ID:</label><input type="text" name="SomeID" /><div class="clear"></div>
<label>Another ID:</label><input type="text" name="Another ID" /><div class="clear"></div>
</fieldset>
<fieldset class="control-group category-group">
<label>Category 1:</label><input type="text" name="Cat1" /><div class="clear"></div>
<label>Category 2:</label><input type="text" name="Cat2" /><div class="clear"></div>
</fieldset>
<fieldset class="control-group description-group">
<label>Description:</label><input type="text" name="Description" /><div class="clear"></div>
</fieldset>
<div class="clear"></div>
</form>
<div class="clear"></div>
<div class="alert alert-error" id="addError">
</div>
<div class="alert alert-success" id="addSuccess">
</div>
</div>
<div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
<a href="#" class="btn btn-primary" id="saveSomethingButton" data-loading-text="Please Wait...">Save</a>
</div>
以下是我在表单提交时调用javascript的示例:
$("#saveSomethingButton").click(function() {
//hide any previous errors should this be a second submit
$(".alert").hide();
$(".control-group").removeClass('error');
$("input").blur();
//set the save button to a "please wait" state to prevent double submission
$("#saveSomethingButton").button('loading');
//post to the validation script - if
$.post("<?php echo base_url();?>somecontroller/processfunction", $("#your_form").serialize(), function(data) {
//if we were successful, show the happiness message and close the modal
if (data.success == 1) {
$("#addSuccess").html("<strong>Success! </strong> Something successfully added to database.");
$("#addSuccess").fadeIn(300, function() {
setTimeout(function() {
$("#someModal").modal('hide');
}, 2000);
});
//otherwise, highlight the problem fields and display the error
} else {
$("#addError").html("<strong>Error: </strong> "+data.message);
$("."+data.fieldset).addClass("error");
$("#addError").fadeIn(300);
$("."+data.fieldset+":first input:first").focus();
}
//reset the button state so that they can correct errors and submit again
$("#saveSomethingButton").button('reset');
}, "json");
//return false to prevent default form submission, which would reload the page
return false;
});