Rails и JavaScript: Uncaught TypeError: Невозможно установить свойство 'onclick' для undefined в HTMLDocument. <anonymous> - PullRequest
0 голосов
/ 16 января 2020

Я очень плохо знаком с комбинацией 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">&times;</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() строке. Но я предполагаю, что есть больше ошибок, так как ничего не происходит, когда я нажимаю «зарегистрироваться» вообще.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...