Обновите Turbo Frames с помощью выбора без отправки на Rails 7

Я изучаю Turbo Frames и Streams + Stimulus, поэтому, возможно, я не на 100% в курсе. У меня есть форма для создания нового объекта, но в форме я хотел бы иметь компонент выбора, который будет отображать определенные поля в зависимости от выбора. Важно отметить, что из-за этого я не хочу отправлять форму, пока пользователь не сделает этот выбор.

Вот что у меня есть:

_form.html.erb

      <div class="form-group mb-3">
   <%= form.label :parking, class: 'form-label' %>
   <%= form.number_field :parking, class: 'form-control' %>
</div>

<%= turbo_frame_tag "turbo_transactions" do %>
   <%= render 'property_transactions' %>
<% end %>

_property_transactions.html.erb

      <div class="form-group mb-3" data-controller="property-transaction">
    <%= label_tag :property_transactions, 'Property in:', class: 'form-label' %>
    <%= select_tag :property_transactions, options_for_select(@property_transactions.collect {|p| [p.name, p.id]}), { data: 
    { action: "property-transaction#redraw", property_transaction_target: 'transaction', turbo_frame: 'turbo_transactions' }, 
        class: 'form-control', prompt: '', autocomplete: 'off' } %>
</div>

<% if @property_transaction %>
    <%= turbo_frame_tag @property_transaction.en_translation_key do %>
        <div class="form-group mb-3">
            <%= render @property_transaction.en_translation_key %>
        </div>
    <% end %>
<% end %>

property_transaction_controller.js

      import { Controller } from "@hotwired/stimulus";
import Rails from "@rails/ujs";

export default class extends Controller {
    static targets = [ "transaction" ];

    redraw() {
        const params = { property_transaction: this.transaction };
        Rails.ajax({
            type: 'post',
            dataType: 'json',
            url: "/set_property_transaction",
            data: new URLSearchParams(params).toString(),
            success: (response) => { console.log('response', response) }
        });
    }

    get transaction() {
        return this.transactionTarget.value;
    }
}

property_controller.rb

      def set_property_transaction
    respond_to do |format|
      format.json
      format.turbo_stream do
        if @property_transactions
          @property_transaction = @property_transactions.select { |p| p.id == property_transaction_params }
        else
          @property_transaction = PropertyTransaction.find(property_transaction_params)
        end
      end
    end
  end

set_property_transaction.turbo_stream.erb

      <%= turbo_stream.replace @property_transaction.en_translation_key %>

_rent.html.erb

      <%= turbo_frame_tag "rent" do %>
    <!-- some input fields -->
<% end %>

_rent_with_option_to_buy.html.erb

      <%= turbo_frame_tag "rent-with-option-to-buy" do %>
    <!-- other input fields -->
<% end %>

_sale.html.erb

      <%= turbo_frame_tag "sale" do %>
    <!-- more input fields -->
<% end %>

При выборе опции возникает такая ошибка:

      Started POST "/set_property_transaction" for ::1 at 2022-09-07 19:49:03 -0600
Processing by PropertiesController#set_property_transaction as JSON
  Parameters: {"property_transaction"=>"2"}
Completed 406 Not Acceptable in 223ms (ActiveRecord: 0.0ms | Allocations: 1879)


  
ActionController::UnknownFormat (PropertiesController#set_property_transaction is missing a template for this request format and variant.

request.formats: ["application/json", "text/javascript", "*/*"]
request.variant: []):

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

1 ответ

Комментарий Леса Найтингилла определенно направил меня в правильном направлении. Я внесу сюда необходимые изменения.

_property_transactions.html.erb

      <div class="form-group mb-3" data-controller="property-transaction">
    <%= label_tag :property_transactions, 'Propiedad en:', class: 'form-label' %>
    <%= select_tag :property_transactions, options_for_select(@property_transactions.collect {|p| [p.name, p.id]}), { data: 
    { action: "property-transaction#redraw", property_transaction_target: 'transaction', turbo_frame: "turbo_transactions" }, 
        class: 'form-control', prompt: '', autocomplete: 'off' } %>
</div>

<%= turbo_frame_tag "dynamic_fields" %>

property_transaction_controller.js

      import { Controller } from "@hotwired/stimulus";
import { post } from "@rails/request.js";

export default class extends Controller {
    static targets = [ "transaction" ];

    async redraw() {
        const params = { property_transaction: this.transaction };
        const response = await post("/set_property_transaction", {
            body: params,
            contentType: 'application/json',
            responseKind: 'turbo-stream'
        });
        if (response.ok) {
            console.log('all good', response); // not necessary
        }
    }

    get transaction() {
        return this.transactionTarget.value;
    }
}

set_property_transaction.turbo_stream.erb

      <%= turbo_stream.update "dynamic_fields" do %>
  <%= render partial: @property_transaction.en_translation_key %>
<% end %>
Другие вопросы по тегам