Использование js.erb в рельсах - PullRequest
0 голосов
/ 08 января 2019

В приложении Rails 5 с devise мне нужно использовать файл new.js.erb для обновления тега select в моем представлении регистрации и контроллере. Кажется, я не могу понять, почему мой new.js.erb файл не работает.

Я пытался использовать respond_to в контроллере, как показано ниже,

регистрация-controller.rb

 def new
   super 
   @cities = CS.get(:us,params[:state]) 
   respond_to do |format|
     format.js { render '/new.js.erb' }# layout: false }          
     format.html 
   end
 end

new.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), :remote => true) do |f| %>
   <div class="signup-input-container">
     <div class="field">
        <%= f.text_field :firstname, autofocus: true, autocomplete: "firstname", placeholder: "First name", class: "signup-input-container--input" %>
     </div>
     <div class="field">
        <%= f.select :state, options_for_select(CS.states(:us).map { |code, name| [name, code] }),{:prompt => "State"}, {:class => "signup-input-container--input", :id => "state-picker"} %>
     </div>
     <div class="field">
        <%= f.select :city, options_for_select([]),{}, {:class => "signup-input-container--input", :id => "city-picker"} %> 
     </div>
  </div>
<% end %>

new.js.erb

  var city = document.getElementById("city-picker");

  while (city.firstChild) city.removeChild(city.firstChild);

  var placeholder = document.createElement("option");
  placeholder.text = "Choose a city";
  placeholder.value = "";
  city.appendChild(placeholder);

 <% @cities.each do |c| %>
   city.options[city.options.length] = new Option('<%= c %>');
 <% end %>

main.js

  var state = document.getElementById("state-picker");
  state.addEventListener("change", function() {
     $.ajax({
        url: "/states?state=" + state.value,
        type: "GET"
     })
  })

Я ожидаю, что это создаст опции выбора тегов с моим массивом городов в контроллере. Кто-нибудь знает, как заставить это работать?

1 Ответ

0 голосов
/ 08 января 2019

Чтобы решить эту проблему, вам нужно просто установить отдельный контроллер, где вы можете извлекать данные из асинхронно, а также есть несколько бесплатных API, которые можно использовать для географического поиска, таких как Googles Geocoding API и * 1004 географических названий *.

Чтобы настроить отдельный контроллер, вы можете сделать это:

# /config/routes.rb
get '/states/:state_id/cities', to: 'cities#index'

# /app/controllers/cities_controller.rb
class CitiesController < ApplicationController
  # GET
  def index
    @cities = CS.get(:us, params[:state_id]) 
    respond_to do |f|
      f.json { render json: @cities }
    end
  end
end

Я бы вообще пропустил использование шаблона .js.erb и просто возвратил данные JSON, которые можно использовать непосредственно в JS или с одним из многих существующих решений автозаполнения. .js.erb имеет смысл только для обширных шаблонов HTML (например, для рендеринга целой формы), где вы хотите повторно использовать свои серверные шаблоны - это значительно увеличивает сложность и обычно создает беспорядок в вашем javascript, который не стоит просто выводить список тегов параметров.

// If you are using jQuery you might as well setup a delegated
// handler that works with turbolinks, 
$(document).on('change', '#state-picker', function(){
  $.getJSON("/states/" + $(this).value() + "/cities", function(data){
    // using a fragment avoids updating the DOM for every iteration.
    var $frag = $('<select>');
    $.each(data, function(city){
      $frag.append$('<option>' + data + '</option>');
    });
    $('#city-picker').empty()
                  .append($('frag').children('option'));
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...