Wir haben eine Funktion implementiert, um die Auswahlmöglichkeiten mithilfe der von Vorfahren erstellten Kategoriedaten dynamisch zu ändern.
Post als Lernnotiz. Ich bin immer noch nicht damit vertraut, aber ich hoffe es hilft!
Vollständiges Formular
https://gyazo.com/8a5adc080698873d544b8665855c0901
Unten ist der fertige Code!
routes
resources :products, except: [:index] do
get 'new/children_category', to: 'products#children_category'
get 'new/grandchildren_category', to: 'products#grandchildren_category'
end
puroducts_controller
before_action :set_categories, only: [:edit, :update]
~ Abkürzung ~
def children_category
@children_category = Category.where(ancestry: params[:parent_category_id])
render json: @children_category
end
def grandchildren_category
@grandchildren_category = Category.where(ancestry: "#{params[:parent_category_id]}/#{params[:children_category_id]}")
render json: @grandchildren_category
end
puroducts/new_html_haml
.input-field__contents
.input-field__contents-data
%p.subline
Produktdetails
.input-field__contents-image__headline
.headlabel
= f.label :category_id, "Kategorie"
%span.necessary
Verpflichtend
.sell__about__right__wrap-box.parent
%select.select-box1#parent
%option{value: 0} ---
- @parents.each do |parent|
%option{value: "#{parent.id}"} #{parent.name}
.child
%select.select-box2#child
.grand_child
.select-box3
= f.collection_select(:category_id, [], :id, :name, {prompt: "---"}, {id: "grand_child"})
category_js
$(function(){
let buildPrompt = `<option value>---</option>`
let buildHtmlOption = function(parent) {
let option = `<option value ="${parent.id}">${parent.name}</option>`
return option
}
$('#parent').change(function() {
let parent_id = $(this).val();
$.ajax({
type: 'GET',
url: 'products/new/children_category',
data: {parent_category_id: parent_id},
dataType: 'json'
})
.done(function(parent) {
$('.child').css('display', 'block');
$('#child').empty();
$('.grand_child').css('display', 'none');
$('#child').append(buildPrompt);
parent.forEach(function(child) {
var html_option = buildHtmlOption(child);
$('#child').append(html_option);
});
})
.fail(function() {
alert('Error')
});
});
$(this).on("change", "#child", function() {
let parent_id = $("#parent").val();
let child_id = $("#child").val();
$.ajax({
type: 'GET',
url: 'products/new/grandchildren_category',
data: {
parent_category_id: parent_id,
children_category_id: child_id
},
dataType: 'json'
})
.done(function(parent) {
$('.grand_child').css('display', 'block');
$('#grand_child').empty();
$('#grand_child').append(buildPrompt);
parent.forEach(function(child) {
var html_option = buildHtmlOption(child);
console.log(buildHtmlOption(html_option));
$('#grand_child').append(html_option);
});
})
});
})
・ Fügen Sie nach Auswahl der übergeordneten Kategorie und Auslösen des Ereignisses die Kategorie ** untergeordnet ** hinzu. ・ Fügen Sie nach Auswahl der untergeordneten Kategorie und Auslösen des Ereignisses die Kategorie ** Enkel ** hinzu. · Verwenden Sie Ajax, um einen ** Pfad ** für die anzuzeigenden Kinder- und Enkelkategorien zu erstellen ・ Schließlich wird der Wert der Enkelkategorie gespeichert.
Es ist ungefähr so.
Werfen wir einen Blick auf jeden einzelnen!
Zeigen Sie als Prozessablauf des Programms schließlich die untergeordnete Kategorie und die übergeordnete Kategorie in der Ansicht an. Die Verarbeitung wird tatsächlich mit dem Controller und js durchgeführt, sodass ein Pfad zum Controller erstellt wird, wenn die Anforderung erfüllt wird.
routes
resources :products, except: [:index] do
#children_Kategorie Pfad zum Handeln
get 'new/children_category', to: 'products#children_category'
#grandchildren_Kategorie Pfad zum Handeln
get 'new/grandchildren_category', to: 'products#grandchildren_category'
end
Da eine Ajax-Verarbeitung durchgeführt wird, gehen Sie zur Steuerung, nachdem die Ajax-Verarbeitung von js durchgeführt wurde. Zu diesem Zeitpunkt muss der Controller den Wert der Kategorie finden und an js zurückgeben. Schreiben Sie daher wie folgt.
puroducts_controller
before_action :set_categories, only: [:edit, :update]
~ Abkürzung ~
def children_category
#.Verwenden Sie, wo Sie den Wert aus der Abstammung suchen und ihn der Instanzvariablen zuweisen
@children_category = Category.where(ancestry: params[:parent_category_id])
#Ich werde den von Abstammung gesuchten Wert an js zurückgeben
render json: @children_category
end
def grandchildren_category
#.Verwenden Sie, wo Sie den Wert aus der Abstammung suchen und ihn der Instanzvariablen zuweisen
@grandchildren_category = Category.where(ancestry: "#{params[:parent_category_id]}/#{params[:children_category_id]}")
#Ich werde den von Abstammung gesuchten Wert an js zurückgeben
render json: @grandchildren_category
end
In js wird das Ereignis jedes Mal ausgelöst, wenn eine Kategorie ausgewählt wird. Speziell ・ Wenn die Kategorie ** Eltern ** ausgewählt ist, wird das Ereignis ausgelöst und die Elementkategorie ** Kind ** wird angezeigt. ・ Wenn die Kategorie ** Kind ** ausgewählt ist, wird das Ereignis ausgelöst und die Elementkategorie ** Enkel ** wird angezeigt.
Als Prozess erhält Ajax beim Auslösen eines Ereignisses den Wert vom Controller und ** für jeden ** drückt alles aus.
category_js
//①=====Definieren Sie die Ansicht, die in HTML angezeigt werden soll ===========================
$(function(){
let buildPrompt = `<option value>---</option>`
let buildHtmlOption = function(parent) {
let option = `<option value ="${parent.id}">${parent.name}</option>`
return option
}
//=================================================
//②=====Verarbeitung zum Auswählen der übergeordneten Kategorie und Aufrufen der untergeordneten Kategorie ============
$('#parent').change(function() {
let parent_id = $(this).val();
//Mit Ajax an den Controller senden
$.ajax({
type: 'GET',
url: 'products/new/children_category',
data: {parent_category_id: parent_id},
dataType: 'json'
})
//Das Folgende ist die Verarbeitung nach der Antwort von der Steuerung
.done(function(parent) {
$('.child').css('display', 'block');
$('#child').empty();
$('.grand_child').css('display', 'none');
$('#child').append(buildPrompt);
//Holen Sie sich alle vom Controller erhaltenen Werte mit forEach,.Zum HTML-Element mit Anhängen hinzufügen
parent.forEach(function(child) {
var html_option = buildHtmlOption(child);
$('#child').append(html_option);
});
})
.fail(function() {
alert('Error')
});
});
//=============================================
//②=====Verarbeitung zum Auswählen einer untergeordneten Kategorie und Aufrufen einer Enkelkategorie ============
$(this).on("change", "#child", function() {
let parent_id = $("#parent").val();
let child_id = $("#child").val();
//Mit Ajax an den Controller senden
$.ajax({
type: 'GET',
url: 'products/new/grandchildren_category',
data: {
parent_category_id: parent_id,
children_category_id: child_id
},
dataType: 'json'
})
//Das Folgende ist die Verarbeitung nach der Antwort von der Steuerung
.done(function(parent) {
$('.grand_child').css('display', 'block');
$('#grand_child').empty();
$('#grand_child').append(buildPrompt);
//Holen Sie sich alle vom Controller erhaltenen Werte mit forEach,.Zum HTML-Element mit Anhängen hinzufügen
parent.forEach(function(child) {
var html_option = buildHtmlOption(child);
console.log(buildHtmlOption(html_option));
$('#grand_child').append(html_option);
});
})
});
//=============================================
})
Bei HTML ist nur zu beachten, ob das ID-Attribut von js und das ID-Attribut von HTML inkonsistent sind.
Es ist jedoch ein kleiner Trick erforderlich, um den Wert der letzten Enkelkategorie zu speichern.
puroducts/new_html_haml
.input-field__contents
.input-field__contents-data
%p.subline
Produktdetails
.input-field__contents-image__headline
.headlabel
= f.label :category_id, "Kategorie"
%span.necessary
Verpflichtend
.sell__about__right__wrap-box.parent
%select.select-box1#parent
%option{value: 0} ---
#Alle Werte in der übergeordneten Kategorie anzeigen
- @parents.each do |parent|
%option{value: "#{parent.id}"} #{parent.name}
.child
# #Die in js definierte Ansicht wird anstelle von child eingefügt
%select.select-box2#child
.grand_child
.select-box3
# id:grand_Die in js definierte Ansicht wird anstelle von child eingefügt
#Um den Wert der ausgewählten Enkelkategorie korrekt zu speichern, schreiben Sie wie folgt.
= f.collection_select(:category_id, [], :id, :name, {prompt: "---"}, {id: "grand_child"})
Als Ergänzung überprüfen Sie bitte die folgende Seite, da ich auf die folgende Beschreibung verwiesen habe
f.collection_select(:category_id, [], :id, :name, {prompt: "---"}, {id: "grand_child"})
#Referenzbeschreibung
#collection_select(Objektname,Methodenname,Array von Elementen,Wertelementattribut,Textelement[,Optionen oder HTML-Attribute oder Ereignisattribute])
Referenzartikel: https://railsdoc.com/page/collection_select
Der Prozess ist nicht so kompliziert, also habe ich jeden überprüft und es hat funktioniert!
Wenn Sie eine Fehlermeldung erhalten oder den Wert nicht richtig erhalten, überprüfen Sie ** binding.pry **, ** console.log (); **, ** debugger **!
Vielen Dank!