Динамический выпадающий в рельсах simple_form - PullRequest
0 голосов
/ 18 сентября 2018

В моем приложении rails есть простые отношения has_many и own_to.Я использую simple_form и хочу динамически изменять параметры выпадающего меню в зависимости от значения, выбранного пользователем.

Модели

 class Processor < ApplicationRecord
   has_many :processor_bank_accounts
 end

 class ProcessorBankAccount < ApplicationRecord
   belongs_to :processor
 end

Входные данные формы

<%= simple_form_for [@customer, @transaction] do |f| %>
<%= f.error_notification %>

<div class="form-inputs">
  <%= f.input :status, :collection => ["payment request"], include_blank: false %>
  <%= f.input :processor, collection: @processors ,label_method: :name,value_method: :id,label: "Processor" , include_blank: false %>
  <%= f.input :processor_bank_account, collection: @bank_accounts , label_method: :bank_name, value_method: :id, label: "Processor Bank Account" , include_blank: true %>
  <%= f.input :tcurrency, collection: @currencies, include_blank: false, label: 'currency' %>
  <%= f.input :amount, as: :decimal, label: 'amount' %>
</div>

<div class="form-actions text-center">
  <%= f.button :submit, "Add transaction", class: "form-button"%>
</div>
<% end %>

Поэтому, по сути, мне нужно, чтобы выпадающий список processor_bank_account заполнялся на основе процессора, выбранного пользователем.В консоли это будет просто: ProcessorBankAccount.where (процессор: процессор).

Необходимо загрузить параметры с помощью JS и подумать, что мне нужно использовать JSON, но не уверен, куда идти дальше

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Я предложил следующее решение:

1) Добавьте новый метод в мой контроллер процессоров, чтобы отобразить входные данные для второго (динамического) раскрывающегося списка в формате JSON:

def processor_bank_accounts
 render json: @processor.processor_bank_accounts.each do |bap|
 { id: bap.id, name: bap.name }
 end
end

2) Присвойте эту новую функцию новому маршруту в config / route:

get 'api/bankaccounts', to: 'processors#processor_bank_accounts', as: 'bankaccounts'

3) Создайте функцию JS для доступа к маршруту с идентификатором процессора, выбранного в первом раскрывающемся списке, и заполните второй.раскрывающийся список с элементами из массива JSON:

// select first dropdown
const processor = document.getElementById("transaction_processor");
// select second dropdown
const bapSelect = document.getElementById("transaction_processor_bank_account");

function update_baps(processor_id) {
 const url = `INSERTWEBURLHERE/api/bankaccounts?id=${processor_id}`;
 fetch(url)
 .then(response => response.json())
 .then((data) => {
  bapSelect.innerHTML = ""; // clear second dropdown
  data.forEach((bap) => { // go through all the BAPs
  const elem = `<option value="${bap.id}">${bap.bank_name}</option>`; // create option elements to insert into the second dropdown, bank_name is the chosen label method in the form
  bapSelect.insertAdjacentHTML("beforeend", elem); // insert options into the dropdown
  });
 });
}

4) Запуск JS при изменении первого раскрывающегося поля:

processor.addEventListener('change', function () {
 update_baps(parseInt(processor.value));
});
0 голосов
/ 18 сентября 2018

Вы должны добавить id к выборкам, чтобы вы могли идентифицировать их из скрипта.

$('select#processor').on('change', function() {
      var processor_id = this.value;
      var processor_bank_account = $('select#processor_bank_account')

      $.ajax({
        type: "GET", 
        url: <%= your_path %> ,
        data: { processor_id: processor_id },
        success: function(data, textStatus, jqXHR){
          processor_bank_account.empty();
          var option = new Option(data.bank_name, data.id, false, false);
          processor_bank_account.append(option);
        },
        error: function(jqXHR, textStatus, errorThrown){...}
      })
 });
0 голосов
/ 18 сентября 2018

Один из способов сделать это - использовать jQuery, чтобы вызвать AJAX-вызов для действия контроллера, а затем позволить Rails обрабатывать остальное через шаблон erb.

Итак, на вашей странице, с формой, вызовите действие через AJAX, используя что-то вроде:

<script>
    $(document).ready(function() {
        $('#processor_id').on('change', function() {
            $.ajax({
                url: '/transactions/get_processor_bank_accounts',
                type: 'GET',
                data: {
                    processor_id: this.value
                },
                dataType: 'script',
                error: function() {
                    alert('An error occurred retrieving bank accounts for the selected processor.');
                }
            });
        });
    });
</script>

NB, #processor_id - это идентификатор вашего выпадающего элемента управления.

Далее, создайте экземпляры банковских счетов в вашем действии в контроллере:

def get_processor_bank_accounts
  @processor_bank_accounts = ProcessorBankAccount.where(processor_id: params[:processor_id])
end

И, наконец, просто создайте представление, которое будет отвечать за повторное заполнение вашего раскрывающегося списка:

$select_list = $('#processor_id');
$select_list.empty();

<% @processor_bank_accounts.each do |pba| %>
  $select_list.append($('<option value="<%= pba.id %>"><%= pba.name %></option>'));
<% end %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...