web-dev-qa-db-fra.com

Rails 4 rendu un partiel avec ajax, jquery,: remote => true et respond_to

Il semble que le rendu dynamique d'une page avec AJAX en réponse à un formulaire soumis soit courant. Aucune des autres questions similaires ne se concentre sur la façon de procéder de manière générale.

Le meilleur article de blog que j'ai pu trouver sur le sujet était ici: http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-Ruby-on-Rails

La question: Comment coder mon Rails application pour que je puisse déclencher une vue partielle à charger via AJAX lorsque je soumets un formulaire ou clique sur un lien?)

24
emery

Plusieurs choses doivent être présentes pour que cela fonctionne, y compris le drapeau: remote => true sur l'élément déclencheur, le drapeau respond_to: js dans la définition de classe du contrôleur, la route, la vue partielle et enfin le jquery pour réellement rendre une dynamique partiel doit être contenu dans un fichier .html.js distinct.

Les exemples ci-dessous concernent une méthode fictive "render_partial_form" du contrôleur "someajax".


1) Ajoutez un indicateur: remote => true à l'élément déclencheur
placez l'indicateur: remote => true sur le lien ou la balise de formulaire dans votre fichier .html.erb (vue) pour l'élément que vous souhaitez déclencher l'appel AJAX, comme

<%= form_tag("/someajax", method: 'post', :remote => true) do %>

avec: remote => true, Rails ne changera pas automatiquement de vue, ce qui permet d'exécuter JQuery à la place. Cela peut être utilisé avec un form_tag, un link_tag ou d'autres types de balises.


2) Ajoutez "respond_to: html,: js" en haut du contrôleur

En haut de la définition de classe de votre contrôleur, vous devez maintenant spécifier que le contrôleur peut répondre aussi bien au javascript qu'au html:

class SomeajaxController < ApplicationController
   respond_to :html, :js

   ...

   def render_partial_form
      @array_from_controller = Array.new

      ...

   end
end

Dans cet exemple, une variable est passée du contrôleur à la vue: un tableau d'options de liste de sélection appelé @array_from_controller.


) Acheminez le verbe http vers la méthode de votre contrôleur

Comme je voulais qu'un formulaire POSTé déclenche l'appel AJAX, j'ai routé le verbe de publication de mon contrôleur vers la vue render_partial_form.

post 'someajax' => 'someajax#render_partial_form

La méthode du contrôleur définie par def render_partial_form correspond au nom de la vue, _render_partial_form.html.erb donc il n'est pas nécessaire d'appeler une action de rendu depuis le contrôleur.


4) Créez la vue partielle
La vue partielle doit avoir le même nom que votre méthode de contrôleur et commencer par un trait de soulignement: _render_partial_form.html.erb

<h3>Here is the partial form</h3>

<%= form_tag("/next_step", method: 'post') do %>
    <%= label_tag(:data, "Some options: ") %>
    <%= select_tag(:data, options_for_select(@array_from_controller.transpose[0].collect)) %>
    <%= submit_tag('Next') %>
<% end %>


5) Créez le fichier JQuery

Les instructions JQuery déclenchent le rendu du formulaire. Remplacez "render_partial_form" par le nom réel de votre méthode de contrôleur et de la vue partielle. L'effet slideDown est un "bonbon pour les yeux" en option. Créez un fichier avec une extension .js.erb et le même nom que votre contrôleur:

render_partial_form.js.erb

$('#render_partial_form').html("<%= escape_javascript (render partial: 'render_partial_form') %>");
$('#render_partial_form').slideDown(350);
35
emery

Vous devez utiliser les vues JS (qui ont l'extension "js.erb"), quelque chose comme "create.js.erb" pour créer l'action du contrôleur. Puis ajouter format.js au respond_to do |format| ... end bloquer. Et ajoutez le paramètre remote: true à votre formulaire. Remarque: js.erb doit inclure du code Javascript que vous devez inclure, comme:

$("tbody#items").append("<%= j render(partial: 'your_partial_path') %>")
12
Felix Borzik

Pour ce que ça vaut (parce que je trébuchais dessus dans une mise à niveau d'application de Rails 2 à 3): vous pouvez également le faire en ajoutant un gestionnaire d'événements qui ajoute le code HTML renvoyé, comme le ancienne Rails 2 bibliothèque prototype utilisée pour faire.

Si, par exemple, vous essayez de prendre ceci (préparez-vous à une phrase runon):

form_remote_tag url: {...}, update: ...

Où la réponse arrive en HTML et est ajoutée automatiquement, et remplacez-la par ceci:

form_tag {...}, remote: true

En ajoutant un gestionnaire d'événements à votre application.js fichier qui fait simplement la même chose, en ajoutant le contenu à un élément spécifique, comme ceci:

$("#myform").on('ajax:success', function(e, data, status, xhr) {
  $("#container").append(data);
)};

Alors ... vous pouvez rencontrer le même problème que moi, à savoir qu'il ne déclenche jamais le ajax:success un événement! Le problème est qu'il attend du JS ou du texte dans la réponse, mais qu'il obtient du HTML. La façon de résoudre ce problème est de lui dire que la réponse sera HTML en utilisant un attribut sur la balise de formulaire:

form_tag {...}, remote: true, data: {type: :html}

Part de gâteau!

2
mltsy