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
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.
Als Voraussetzung
Installieren Sie zuerst den gewünschten Edelstein.
gem jquery-rails
bundle install
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
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
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"}
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 ...)
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.
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.
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,
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.
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.
[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