Rails: javascript addEventListener не находит элемент в динамической форме - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь реализовать динамическую форму в приложении Rails через AJAX и сделал несколько учебных пособий, но безуспешно.

Часть Javascript из файла js моего приложения в папке ресурсов

var land = document.getElementById("cart_land_id");
land.addEventListener("change", function(){
  Rails.ajax({
    url: "/carts?land=" + land.value,
    type: "GET"
  })
})

Для этой формы в представлении:

<%= form_for @cart, :url => {:action => "show_shipping"}, :html => {:method => "get"} do |f| %>
  <%= f.select :land_id, options_for_select(@lands.map { |l| [l.name.titleize, l.id] }, {:id => 'lands_select', :prompt => "select a country"}) %><br>
  <%= f.select :shippingservice_id, options_for_select([]) %><br>
  <%= f.submit "Calculate shipping" %>
<% end %>

, который отображается как:

<form accept-charset="UTF-8" action="/carts/show_shipping/4" class="edit_cart" id="edit_cart_4" method="get">
  <div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
  <select id="cart_land_id" name="cart[land_id]"><option value="1">Afghanistan</option>
  ...
  <select id="cart_shippingservice_id" name="cart[shippingservice_id]"></select><br>
  <input name="commit" type="submit" value="Calculate shipping" />
</form>

производит

TypeError: null is not an object (evaluating 'land.addEventListener')         

У меня есть jQuery вмой каталог Javascript.

Почему это происходит и как я могу это решить?

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Добавить слушателя можно двумя способами:

  1. Добавить слушателя к какому-либо конкретному элементу: document.getElementById("...").addEventListener(type, fn) или document.querySelector("...").addEventListener(type, fn).

  2. Добавьте слушателя к родительскому элементу с помощью сопоставления: document.addEventListener(type, fn), где fn проверяет, существует ли event.target.closest('#cart_land_id'), прежде чем продолжить.

В вашем случае наличие jquery помогает, потому чтоэто сокращение:

$(document).on("change", "#cart_land_id", function(event){
  Rails.ajax({
    url: "/carts?land=" + event.target.value,
    type: "GET"
  })
})

Слушатель настроен на документ (нет другого доступного элемента для цели), но только события, которые всплывают из #cart_land_id, отправляются слушателю.


ОБНОВЛЕНИЕ

Чтобы сделать ajax-запрос, вы определенно можете использовать fetch - который изначально поддерживается в большинстве браузеров и может быть заполнен по-разному.

fetch("/carts?land=" + event.target.value).
  then(function(resp) { return resp.text(); }).
  then(function(text) {
    // do something with text
    // for instance replace the content of some element:
    someEl.innerHTML = text;
  });

См. https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch для получения дополнительной информации

0 голосов
/ 18 декабря 2018

Поскольку у вас есть jQuery, вы можете использовать следующий код

$("body").on("change", "#cart_land_id", function(event){
    var landValue = $("#cart_land_id").val();
    $.ajax({
        url: "/carts?land=" + landValue,
        type: "GET",
        success: function(response) {
            // handle response here
        }
    })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...