[RUBY] Implementierung eines Kategorieauswahlformulars mit JS bei der Erstellung von Frima-Apps

Einführung

Ich mache einen Klon der Furima-App für die letzte Aufgabe einer bestimmten Programmierschule. Ich werde den Inhalt der Arbeit bei der Implementierung der "Kategorieauswahlfunktion" beschreiben, die für die Produktlistenfunktion erforderlich ist.

--Erstellen eines Pulldown-Auswahlformulars mit JavaScript

Was Sie in diesem Artikel sehen können

Ziele, die Sie mit dieser Funktion erreichen möchten

Wenn das übergeordnete Element (Damen) wie unten gezeigt ausgewählt ist, wird das untergeordnete Elementauswahlformular angezeigt, und wenn das untergeordnete Element ausgewählt ist, wird das Enkelelementelementauswahlformular ** durch asynchrone Kommunikation ** angezeigt. Wenn Sie die Auswahl von Kindern und Enkelkindern ändern, wird der Formularinhalt initialisiert oder das Formular selbst verschwindet. Image from Gyazo

Entwicklungsumgebung

Rauer Fluss

  1. Installieren Sie gem
  2. Erstellen Sie einen Controller und eine JS-Datei für die Verwendung von JS und beschreiben Sie den Aufruf.
  3. Routing hinzufügen.
  4. Stellen Sie die Funktion #search so ein, dass Daten auf dem Controller gesucht werden.
  5. Bearbeiten Sie die js-Datei.
  6. Bearbeiten Sie die für die Ajax-Kommunikation verwendete Datei json.jbuilder.
  7. Wiederholen Sie 4-6 oben mit untergeordneten Elementen und Enkelelementen.
  8. Fügen Sie eine Aktion hinzu, wenn das untergeordnete Element / Enkelelement geändert wird.
  9. Fertigstellung

Als Voraussetzung

Spezifisches Montageverfahren

0. Installieren Sie gem

Installieren Sie zuerst den gewünschten Edelstein.

gem jquery-rails
bundle install

1. Schreiben Sie, um JavaScript zu verwenden

app/javascript/packs/application.js


require('jquery')
require('item/category')

config/webpack/environment.js


const { environment } = require('@rails/webpacker')
const webpack = require('webpack')

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
  })
)

module.exports = environment

Worauf ich hier sofort gestoßen bin, war, dass meine Entwicklungsumgebung Rails6 war. Die meisten Artikel, die ich im Internet gesucht habe, sind Informationen vor Rails5, In Rails6 scheinen der Generierungsspeicherort der Datei application.js und die Beschreibung für den Aufruf unterschiedlich zu sein. Ich war verwirrt, weil es zuerst nicht gut geladen wurde.

Überprüfen Sie bei der Entwicklung die Version und beschreiben Sie sie entsprechend Ihrer eigenen Umgebung.

Ich habe auf diesen Artikel für die Einführung von jquery in Rails6 verwiesen. => So installieren Sie jquery in Rails6

2. Routing hinzufügen

So fügen Sie dem Element-Controller später eine Suchaktion hinzu Fügen Sie das Routing zur Suchaktion hinzu.

routes.rb


Rails.application.routes.draw do
  resources :items do
    collection do
      get :search
    end
  end
end

3. Erstellen Sie in der Ansicht ein Kategorieauswahlformular

Dies ist nur als Referenz für meine Beschreibung. Auf diese Weise habe ich zuerst ein Formular für die übergeordnete Kategorie erstellt.

ruby:qpp/view/items/new.html.haml


=form_with model @item do |f|
= f.collection_select :category_id, @parents, :id, :name, {prompt: "Bitte auswählen"}, {class: "categoryForm", id: "category_form"}

4. Fügen Sie dem Controller eine Suchaktion hinzu

Holen Sie sich den Datensatz mit der neuen Aktion.

items_controller


  def new 
    @item = Item.new
    @item_image = ItemImage.new
  end

Außerdem setze ich before_action, weil ich die Informationen des übergeordneten Elements vor der neuen Aktion abrufen und eine Aktion erstellen möchte.

ite,s_controller.rb


  before_action :set_parents, only: [:new, :create]

  def set_parents
    @parents = Category.where(ancestry: nil)
  end

ancestry = nil, dh der Wert des übergeordneten Elements wird erfasst und der Variablen @parents zugewiesen. Der Grund, warum set_parents nicht nur für new, sondern auch für create erforderlich ist, ist Ich habe auf den Artikel in [hier] verwiesen (https://qiita.com/kaito_program/items/3755f071625f9f5bbaba). (Ehrlich gesagt, als ich den Code schrieb, wusste ich es, ich wusste es nicht ...)


Legen Sie dann die Suchaktion für die Kategoriesuche von Kindern und Enkelkindern fest.

items_controller.rb



  def search
    respond_to do |format|
      format.html
      #Ajax-Kommunikation gestartet
      format.json do
          #Informationen zur untergeordneten Kategorie@Ersatz für Kinder
          @childrens = Category.find(params[:parent_id]).children
      end
    end
  end

Abgesehen davon fühlte ich mich unwohl, wenn ich dem Plural "Kinder" "s" hinzufügte. Ich dachte, es wäre schwierig zu verstehen, wie man Kinder und Kinder richtig benutzt, also entschied ich mich, Kinder zu benutzen.

5. Erstellen Sie die Datei json.jbulder

ruby:app/view/items/search.json.jbuilder


json.array! @childrens do |children|
  json.id children.id
  json.name children.name
end

Derzeit werden nur die untergeordneten Elemente aufgelistet.

6. Bearbeiten Sie die js-Datei und empfangen Sie die von der obigen Aktion gesendeten Daten

  1. Erstellen Sie zunächst ein "untergeordnetes Elementauswahlformular", das nach Auswahl des übergeordneten Elements angezeigt wird.

category.js


//Formular zur Auswahl untergeordneter Elemente
function add_childSelect_tag() {
  let child_select_form = `
              <select name="item[category_id]" id="item_category_id" class="child_category_id">
              <option value="">Wählen Sie eine Kategorie</option>
              </select>
            `
  return child_select_form;
}

Ich bin nicht gut darin, diesen HTML-Teil zu schreiben, aber ich denke, dass es am einfachsten ist, zu schreiben, indem man die Form des übergeordneten Elements mit dem Ansichtsüberprüfungstool betrachtet.

name = "item [category_id] ist das Ziel der Daten.

Später möchte ich die Form des untergeordneten Elements löschen oder initialisieren (wenn das übergeordnete Element geändert wird usw.), daher habe ich auch den Klassennamen hinzugefügt, der für das untergeordnete Element spezifisch ist.
2. Beschreiben Sie die Option zum Erfassen der Daten im angezeigten Auswahlformular.

category.js


function add_Option(children) {
  let option_html = `
                    <option value=${children.id}>${children.name}</option>
                    `
  return option_html;
}


3. Legen Sie das Ereignis fest, das nach Auswahl der übergeordneten Kategorie auftritt.

category.js


//Ereignisse nach Auswahl einer übergeordneten Kategorie
$("#category_form").on("change", function() {
  let parentValue = $("#category_form").val();
  if (parentValue.length !== 0) {
    $.ajax({
      url: '/items/search',
      type: 'GET',
      data: { parent_id: parentValue},
      dataType: 'json'
    })
    .done(function (data){
      let child_select_form = add_childSelect_tag
      $(".ItemInfo__category--form").append(child_select_form);
      data.forEach(function(d){
        let option_html = add_Option(d)
        $(".child_category_id").append(option_html);
      });
    })
    .fail(function (){
      alert("Die Kategorie konnte nicht abgerufen werden");
});

Als rauer Fluss,

  1. Rufen Sie die Daten des übergeordneten Elements ab und weisen Sie sie parentValue zu.
  2. Wenn die Daten nicht der Anfangswert in if ~ sind, Ajax-Kommunikation.
  3. Verwenden Sie in .done anhängen, um das untergeordnete Elementformular anzuzeigen, das im vorherigen Schritt nach dem übergeordneten Elementformular erstellt wurde.
  4. Extrahieren Sie die nach Option extrahierten Daten nacheinander und zeigen Sie sie an.

Damit ist die Anzeige der untergeordneten Elemente abgeschlossen!
Wählen Sie das übergeordnete Element aus, um das untergeordnete Elementformular anzuzeigen.

4. Erstellen Sie eine Anzeige mit Enkelelementen.

Wiederholen Sie einfach die Schritte für die untergeordneten Elemente.

ruby:app/views/items/search.json.jbuilder


json.array! @grandchildrens do |grandchildren|
  json.id grandchildren.id
  json.name grandchildren.name
end

category.js


//Auswahlformular für Enkelelemente
function add_grandchildSelect_tag(){
  let grandchild_select_form = `
              <select name="item[category_id]" id="item_category_id" class="grandchild_category_id">
              <option value="">Wählen Sie eine Kategorie</option>
              </select>
            `
  return grandchild_select_form
}

categroy.js


//Ereignisse nach Auswahl einer untergeordneten Kategorie
$(document).on("change", ".child_category_id", function(){
  let childValue = $(".child_category_id").val();
  if (childValue.length !=0){
    $.ajax({
      url: '/items/search',
      type: 'GET',
      data: { children_id: childValue},
      dataType: 'json'
    })
    .done(function (gc_data){
      let grandchild_select_form = add_grandchildSelect_tag
      $(".ItemInfo__category--form").append(grandchild_select_form);
      gc_data.forEach(function (gc_d){
        let option_html = add_Option(gc_d);
        $(".grandchild_category_id").append(option_html);
      })
    })
    .fail(function (){
      alert("Die Kategorie konnte nicht abgerufen werden");
    });
})

Wenn Sie nun ein untergeordnetes Element auswählen, wird das Auswahlformular für Enkelelemente angezeigt.

5. Fügen Sie eine Beschreibung hinzu, um das Formular zu initialisieren.

Auf den ersten Blick sieht es so aus, als wäre es in den Schritten 1 bis 4 abgeschlossen worden. Wenn dies unverändert bleibt, treten die folgenden Probleme auf.

Kurz gesagt, wenn Sie mit den Kategorien Kind und Enkel spielen, wird das Formular endlos hinzugefügt.

Also als wünschenswertes Verhalten

Dieses Verhalten muss erreicht werden. Daher wurde die folgende Beschreibung hinzugefügt.

category.js


//Ereignisse nach Auswahl einer übergeordneten Kategorie
$("#category_form").on("change", function() {
  let parentValue = $("#category_form").val();
  if (parentValue.length !== 0) {
    $.ajax({
      url: '/items/search',
      type: 'GET',
      data: { parent_id: parentValue},
      dataType: 'json'
    })
    .done(function (data){
      $(".child_category_id").remove();
      $(".grandchild_category_id").remove();
      let child_select_form = add_childSelect_tag
      $(".ItemInfo__category--form").append(child_select_form);
      data.forEach(function(d){
        let option_html = add_Option(d)
        $(".child_category_id").append(option_html);
      });
    })
    .fail(function (){
      alert("Die Kategorie konnte nicht abgerufen werden");
    })
  }else{
    $(".child_category_id").remove();
    $(".grandchild_category_id").remove();  
  }
});

Ich habe diese beiden Zeilen nach ①.done hinzugefügt

      $(".child_category_id").remove();
      $(".grandchild_category_id").remove();

(2) Dieser Teil wird nach .fail durch else geteilt.

else{
    $(".child_category_id").remove();
    $(".grandchild_category_id").remove();  
  }

Jedes Mal, wenn sich der Inhalt der übergeordneten Kategorie in ① ändert, wird die Kategorie Kind / Enkel einmal gelöscht, und dann wird die Kategorie Kind angezeigt. Nach der else-Anweisung in ②, wenn das übergeordnete Element den Anfangswert auswählt.

Ich habe dem Ereignisteil denselben Code hinzugefügt, nachdem ich die untergeordnete Kategorie ausgewählt habe.

Und um diese JS nach dem Laden aller Seiten zu aktivieren

category.js


window.addEventListener('load', function () {
}

Damit ist der gesamte Code abgeschlossen.

Das ist wirklich komplett! !!


Danach habe ich versehentlich vergessen, den Teammitgliedern "db: seed" zu sagen, Es gab eine Situation wie "Ich kann keine Kategorie auswählen !! Warum ?!", Aber ich konnte sie sicher lösen.

Artikel, auf die verwiesen wird

[Rails] So implementieren Sie die Kategoriefunktion einer bestimmten Frima-App Kategoriefunktion der Furima-App ~ Gem verwenden: Abstammung ~ [Rails] Erstellen eines Kategoriefelds mithilfe der Ajax-Kommunikation

Recommended Posts

Implementierung eines Kategorieauswahlformulars mit JS bei der Erstellung von Frima-Apps
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Erstellungsformular"
Implementierung der Zifferngruppierung in der Furima App
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Edit Form Edition"
CSRF-Gegenmaßnahmenrichtlinie und Implementierungsbeispiel in einer REST-Anwendung unter Verwendung von "Spring Boot" + "EXT JS"
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der "Seed Edition" der Vorfahren
[Rails] Implementierung der Kategoriefunktion
Implementierung der Kategorie-Pulldown-Funktion
Java-Implementierung von Tri-Tree
Implementierung von HashMap mit Kotlin
[Rails] Implementierung einer neuen Registrierungsfunktion im Assistentenformat mit devise
Lassen Sie uns eine TODO-App in Java 4 erstellen. Implementierung der Buchungsfunktion
Lassen Sie uns eine TODO-App in Java 6 erstellen. Implementierung der Suchfunktion
Lassen Sie uns eine TODO-App in Java 8 erstellen. Implementierung von Bearbeitungsfunktionen