Afficher les erreurs d'un formulaire en AJAX avec Twitter Bootstrap et Rails

  • javascript
  • jquery
  • rails
  • ruby
  • twitter-bootstrap-3

Published at 2017-09-22

Interested about building and API using Node.js / Typescript ? Take a look on my brand new Book: REST-API.ts. You can grab a free PDF version on Github. If you like my work, you can buy a paid version on Leanpub.

Voici mon controller avec deux simples actions (j'ai volontairement simplifié l'exemple).

# app/controllers/dishes_controller.rb

class DishesController < ApplicationController

  # affiche le formulaire
  def edit
    render '_form', locals: {dish: @dish}, layout:  false
  end

  # met à jour le plat
  def update
    if @dish.update(dish_params)
      # renvoie la liste des plats avec la modification
      render 'dishes/_list', locals: {dishes: @restaurant.dishes_ordered}, layout: false
    else
      # renvoie le formulaire avec un status d'erreur
      render '_form', locals: {dish: @dish}, layout:  false, status: :unprocessable_entity
    end
  end
end

Et voici mon formulaire

<!-- app/views/dishes/_form.html.erb -->
<%= bootstrap_form_for dish, remote: true do |f| %>
  <%= render 'shared/errors_form', model: dish %>
  <%= f.text_field :name, hide_label: true, placeholder: 'Nom' %>
  <!-- d'autres champs ici -->
  <%= f.submit 'Confirmer' %>
<% end %>

Rails nous simplifie largement la vie car l'attribut remote: true gère pour nous l'envoie du formulaire en AJAX. Il nous reste donc "juste" à implémenter les actions à effectuer lorsque

  • le plat est mis à jour
// app/assets/javascripts/dishes.js
$(document).on(
  "ajax:success",
  "form.edit_dish",
  function (e, data, status, xhr) {
    // le formulaire a été envoyé correctement et le plat a été mis à jour
    // on récupère donc le résultat et on met à jour la liste des plats
    $("#dishes-list").html(xhr.responseText);
    // on ferme le jquery-ui dialog
    $(".ui-dialog").remove();
  }
);
  • le formulaire contient une erreur.
// app/assets/javascripts/dishes.js
$(document).on(
  "ajax:error",
  "form.edit_dish",
  function (e, xhr, status, error) {
    // le plat n'a pas été mis à jour, sûrement à cause d'une erreur de donnée,
    // on récupère donc le formulaire renvoyé par notre controlleur et on écrase l'ancien
    var form = $(this);
    form.parent().html(xhr.responseText);
  }
);

Ruby on Rails est magique!

Related posts