Я очень плохо знаком с комбинацией Rails и JavaScript, и я пытаюсь отобразить сообщения об ошибках во всплывающем окне. Я работаю с devise, и моя пользовательская регистрационная форма является многошаговой. Users_controller создать действие выглядит следующим образом:
def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
redirect_to user_steps_path
else
respond_to do |format|
format.js do
render template: 'registrations/failed_modal.js.erb',
layout: false,
locals: { error_messages: @modal.errors }
end
end
end
У меня есть форма в views / devise / registrations / new. html .erb. В этой форме вы также можете видеть, что я уже определил мое модальное окно, inkl. стили в CSS, которые, я думаю, здесь не актуальны.
<div class="container">
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<div class="modal-body">
// errors will display here with javascript code
</div>
</div>
</div>
<div class="center-items-register">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), remote: true) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="row 1">
<div class="column">
<div class="field">
<%= f.label :first_name, class: 'required' %><br />
<%= f.text_field :first_name, class: 'form-control' %>
</div>
</div>
<div class="column">
<div class="field">
<%= f.label :last_name, class: 'required' %><br />
<%= f.text_field :last_name, class: 'form-control' %>
</div>
</div>
</div>
<div class="row 2">
<div class="column">
<div class="field email">
<%= f.label :email, class: 'required' %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control' %>
</div>
</div>
</div>
<div class="row 3">
<div class="column">
<div class="field">
<%= f.label :password, class: 'required' %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %>
<%= f.password_field :password, autocomplete: "new-password", class: 'form-control' %><br />
</div>
</div>
<div class="column">
<div class="field">
<%= f.label :password_confirmation, class: 'required' %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control' %>
</div>
</div>
</div>
<div class="row buttons">
<div class="column buttons">
<div class="actions">
<%= f.submit "Sign up", class: 'btn form margin' %>
</div>
</div>
<% end %>
<div class="column buttons">
<% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>
<%= link_to fa_icon("facebook", text: "Sign up with facebook"), user_facebook_omniauth_authorize_path, class: "btn btn-lg btn-social btn-facebook" %>
</div>
</div>
</div>
</div>
В папке devise / shared у меня есть _error_messages. html .erb.
<% if resource.errors.any? %>
<div id="error_explanation">
<h2>
<%= I18n.t("errors.messages.not_saved",
count: resource.errors.count,
resource: resource.class.model_name.human.downcase)
%>
</h2>
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
В папке views / devise / registrations я создал failed_modal. js .erb, к которому я обращаюсь в моем Users_Controller с этой строкой:
render template: 'registrations/failed_modal.js.erb',
failed_modal . js .erb имеет следующее содержимое:
var errors = <%= error_messages.to_json.html_safe %>;
var errorForm = document.querySelector('#myModal');
Object.keys(errors).forEach(function(prop) {
var modalBody = error_form.querySelector('.modal-body');
var errElement = document.createElement('div');
errElement.classList.add('alert');
errElement.classList.add('alert-danger');
errElement.innerText = prop + ':' + errors[prop][0];
modalBody.appendChild(errElement)
})
errorForm.style.display = "block";
Также я создал новый файл в assets / javascripts / new. js и у меня есть // = require_tree в моем приложении. js , Содержимое моего нового. js файла выглядит следующим образом:
document.addEventListener("DOMContentLoaded", function() {
var span = document.getElementsByClassName("close")[0];
var modal = document.getElementById("myModal");
var modalBody = document.querySelector(".modal-body");
span.onclick = function() {
modal.style.display = "none";
modalBody.innerHTML = "";
};
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
modalBody.innerHTML = "";
}
};
});
Когда я сейчас нажимаю на кнопку «зарегистрироваться» в моей форме, я получаю сообщение об ошибке, описанное в заголовке вопроса. Что я делаю неправильно? Этот код был создан с некоторой помощью копирования-вставки, и я вроде понимаю, что происходит. Однако есть некоторые мысли по этому поводу, у меня есть:
locals: { error_messages: @modal.errors }
Я пробовал @user.errors
, а также resource.errors
- кажется, не влияет ни на что. Так что я не знаю, если @modal.errors
прямо здесь.
В failed_modal.js.erb
есть var errorForm = ...
, но в строке ниже код:
var modalBody = error_form.querySelector('.modal-body');
Может ли это быть ошибкой?
Когда я запускаю это в браузер, консоль говорит мне, что ошибка в span.onclick = function()
строке. Но я предполагаю, что есть больше ошибок, так как ничего не происходит, когда я нажимаю «зарегистрироваться» вообще.