Même si vous utilisez form_with
sans local: true
, la partie du message d'erreur n'est généralement pas asynchrone.
J'ai essayé de l'afficher de manière asynchrone, je vais donc résumer la méthode.
Si vous n'ajoutez pas local: true
à form_with
, la communication se produira de manière asynchrone.
erb:app/views/tests/new.html.erb
<%= form_with model: @test do |f| %>
<%= f.text_field :name %>
<%= render 'shared/err_msg' %>
<%= f.submit %>
<% end %>
erb:app/views/shared/err_msg.html.erb
<div id='err_container' style='display: none'>
<ul id='err_ul'>
<!--Je reçois un message d'erreur ici-->
</ul>
</div>
Controller
Lorsque @ test.save
échoue, normalement render: new
est utilisé pour afficher le fichier de vue pour la nouvelle action, mais ici il est décrit dans ʻapp / views / shared / err_msg.js.erb`. J'essaye d'exécuter JavaScript.
app/controller/tests_controller.rb
def index
@test = Test.new
end
def create
@test = Test.new(test_params)
respond_to do |format|
if @test.save
format.js { redirect_to tests_url, notice: 'créé' }
else
@object = @test
format.js { render 'shared/error', status: :unprocessable_entity } #Statut dans le navigateur_Renvoie le code 422
end
end
end
private
def test_params
params.require(:test).permit(:name)
end
Le style du message d'erreur entier est changé de display: none
à display: block
, et le message d'erreur est enveloppé dans li
et affiché.
js:app/views/shared/err_msg.js.erb
let err_container = document.getElementById('err_container');
err_container.style.display = 'block';
let err_ul = document.getElementById('err_ul');
<% @object.errors.full_messages.each do |msg| %>
err_ul.insertAdjacentHTML('afterbegin', '<li><%= msg %></li>');
<% end %>
Recommended Posts