Я создал форму для назначения встреч. Форма содержит разные группы: первая группа - приглашенный и хост, а затем доступны доступные даты. Для доступных дат пользователь должен иметь возможность добавить одну дату, затем дата будет содержать список доступных дат выше, и он может продолжать добавлять даты таким образом. Когда он закончил добавлять даты, публикация формы отправляет данные в базу данных. Для частичного обновления формы, я использовал JQuery для отправки обратно даты ввода формы в контроллер, который добавляет его в массиве available_dates сессии:Как обновить часть формы перед отправкой
в назначениях/new.html.erb:
<section id="invitee, host... />
<section id="available_dates-section">
<ol id="available-dates" >
<%= @available_dates.each do |date| %>
<%= render 'available_date', :date => date%>
<% end %>
</ol>
<%= render 'form' %>
</section>
в назначениях/_form.html.erb
<form id="new_appointment">
<div class="col-sm-6 form-group">
<%= date_field(:appointments, :date, class: "form-control") %>
</div>
<div id="add_date">
<%= link_to "add_date", "#", remote: true %>
</div>
</form>
Тогда в appointments_controller.rb:
def new
binding.pry # goes here after clicking on "add date" the first time instead of in add_dates
# after session[:available_dates] is set in add_date, the flow then comes here and session[:available_dates] is now nil
@appointment = Appointment.new
@available_dates = session[:available_dates] || []
end
def create
binding.pry
params[:appointment][dates] = session[:available_dates]
@appointment = Appointment.create_with_param(params[:appointment])
respond_to do |format|
format.html { redirect_to "/appointments/show" }
format.js # render /appointments/create.js
end
end
def add_date
session[:available_dates] ||= []
session[:available_dates] << params[:appointments][:date]
binding.pry # session[:available_dates] is correctly set
end
И в назначениях/new.js.erb:
$("#add_date").on("click", function(event){
event.preventDefault();
alert("coucou"); # works
$.ajax({
url: "/appointments/add_date",
type: "POST",
data: $("#new_appointment").serialize(),
success: function(data){
alert(data);
}
});
})
и в routes.rb, у меня есть:
resources :appointments
post 'appointments/add_date', to: 'appointments#add_date'
После фиксации опечатка в routes.rb, проблема в том, что в настоящее время сессия теряется в AppointmentsController::new
после available_dates
установлена в AppointmentsController::add_date
.
Первый по какой-то причине, когда я нажимаю на ссылку, js не вызывается, а вместо него вызывается new. Во второй раз, когда я нажимаю, js вызывается и session[:available_dates]
устанавливается в AppointmentsController::add_date
, как и ожидалось. Затем, однако, AppointmentsController::new
вызывается снова, и session[:available_dates]
потерял свою ценность.
Любая идея, почему AppointmentsController::new
называется так (до & после AppointmentsController::add_dates
)? И как я могу это предотвратить?
Кроме того, у меня есть <%= csrf_meta_tags %>
в application.html.erb, и я получаю это поведение даже после комментариев protect_from_forgery with: :exception
в ApplicationController в любом случае.
Я очень новичок в рубине, рельсах и jquery, поэтому, если у вас есть какие-либо предложения по достижению того, что я пытаюсь сделать, а также предложения по стилю, я бы хотел их прочитать!
Спасибо!
Причина, по которой я помещаю это "#", заключается в том, что я не хочу использовать это как ссылку, но как триггер для javascript. В new.js.erb я вызывал 'event.preventDefault();', чтобы предотвратить использование ссылки как таковой или я не понял ее? Он входит в функцию javascript, потому что я добавил предупреждение после 'event.preventDefault();' и он показывает. Тем не менее, попытка оповещения в post post не работает. Я хотел опубликовать в add_date.Но, я думаю, я мог бы попробовать. – Sissi
Не будет 'javascript: void (0);' в 'link_to' заменить поведение new.js.erb ничего не делать вместо публикации в'/add_date', как это делается там? – Sissi
Для использования функции javascript вы должны использовать «javascript: void (0);» в ссылке. И добавьте код javascript в обычный js-файл, например файл custom.js.erb, а не new.js.erb. Тогда будет также работать предупреждение и не нужно вызывать event.prevendefault. – user3506853