・ Rubis: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ Système d'exploitation: macOS Catalina
Ce qui suit a été mis en œuvre.
・ Présentation mince ・ Introduction de Bootstrap 3 ・ Introduction de Font Awesome
category.rb
category.rb
def self.category_parent_array_create
category_parent_array = ['---']
Category.where(ancestry: nil).each do |parent|
category_parent_array << [parent.name, parent.id]
end
return category_parent_array
end
category_parent_array = ['---']
Category.where(ancestry: nil).each do |parent|
category_parent_array << [parent.name, parent.id]
end
** * Les points importants **
[parent.name, parent.id]
➡︎ Lors de l'affichage de la catégorie parente dans la zone de sélection de la vue
Le premier argument (parent.name) devient la valeur affichée sur le navigateur,
Le deuxième argument (parent.id) est la valeur à envoyer en tant que paramètre.
①
comme valeur de retour.return category_parent_array
book_category.rb
book_category.rb
def self.maltilevel_category_create(book, parent_id, children_id, grandchildren_id)
if parent_id.present? && parent_id != '---'
category = Category.find(parent_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
if children_id.present? && children_id != '---'
category = Category.find(children_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
if grandchildren_id.present? && grandchildren_id != '---'
category = Category.find(grandchildren_id)
BookCategory.create(book_id: book.id, category_id: category.id)
end
end
(book, parent_id, children_id, grandchildren_id)
book
: Données du livre à créer
parent_id
: ID de la catégorie parent
children_id
: ID de la catégorie enfant
petitchildren_id
: ID de la catégorie de petit-enfant
if parent_id.present? && parent_id != '---'
category = Category.find(parent_id)
BookCategory.create(book_id: book.id, category_id: category.id)
books_controller.rb
def create
@book = Book.new(book_params)
@book.user_id = current_user.id
if @book.save
BookCategory.maltilevel_category_create(
@book,
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
)
redirect_to books_path
else
@books = Book.all
@category_parent_array = Category.category_parent_array_create
render 'index'
end
end
def index
@book = Book.new
@books = Book.all
@category_parent_array = Category.category_parent_array_create
end
def get_category_children
@category_children = Category.find(params[:parent_id]).children
end
def get_category_grandchildren
@category_grandchildren = Category.find(params[:children_id]).children
end
maltilevel_category_create
et exécutez-la.BookCategory.maltilevel_category_create(
@book,
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
)
** ◎ Recevez les paramètres envoyés par la communication Ajax. ** **
params[:parent_id],
params[:children_id],
params[:grandchildren_id]
category_parent_array_create
à la variable d'instance.@category_parent_array = Category.category_parent_array_create
def get_category_children
@category_children = Category.find(params[:parent_id]).children
end
def get_category_grandchildren
@category_grandchildren = Category.find(params[:children_id]).children
end
fichier json.jbuilder
Terminal
$ touch app/views/books/get_category_children.json.jbuilder
ruby:books/get_category_children.json.jbuilder
json.array! @category_children do |children|
json.id children.id
json.name children.name
end
Terminal
$ touch app/views/books/get_category_grandchildren.json.jbuilder
ruby:books/get_category_grandchildren.json.jbuilder
json.array! @category_grandchildren do |grandchildren|
json.id grandchildren.id
json.name grandchildren.name
end
get_category_children
pour créer un tableau.json.array! @category_children do |children|
①
.json.id children.id
json.name children.name
** ◎ Valeur renvoyée lorsque la catégorie parente (entreprise) est sélectionnée **
[
{
"id": 2,
"name": "La finance"
},
{
"id": 6,
"name": "Économie"
},
{
"id": 9,
"name": "la gestion"
},
{
"id": 13,
"name": "commercialisation"
},
]
** ◎ Lorsque la catégorie enfant (finance) est sélectionnée **
[
{
"id": 3,
"name": "Stock"
},
{
"id": 4,
"name": "échange"
},
{
"id": 5,
"name": "impôt"
},
]
routes.rb
#Postscript
get 'get_category/children', to: 'books#get_category_children', defaults: { format: 'json' }
get 'get_category/grandchildren', to: 'books#get_category_grandchildren', defaults: { format: 'json' }
slim:books/index.html.slim
.category-form
= label_tag 'Genre'
= select_tag 'parent_id', options_for_select(@category_parent_array), id: 'parent-category', class: 'form-control'
i.fas.fa-chevron-down
br
parent_id
.= select_tag 'parent_id', options_for_select(@category_parent_array), id: 'parent-category', class: 'form-control'
Terminal
$ touch app/assets/javascripts/category_form.js
category_form.js
$(function() {
function appendOption(category) {
let html = `<option value='${category.id}' data-category='${category.id}'>${category.name}</option>`;
return html;
}
function appendChidrenBox(insertHTML) {
let childrenSelectHtml = '';
childrenSelectHtml = `
<div id='children-wrapper'>
<select id='children-category' class='form-control' name='[children_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(childrenSelectHtml);
}
function appendGrandchidrenBox(insertHTML) {
let grandchildrenSelectHtml = '';
grandchildrenSelectHtml = `
<div id='grandchildren-wrapper'>
<select id='grandchildren-category' class='form-control' name='[grandchildren_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(grandchildrenSelectHtml);
}
$('#parent-category').on('change', function() {
let parentId = document.getElementById('parent-category').value;
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
.fail(function() {
alert('Échec de l'obtention du genre');
});
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
});
$('.category-form').on('change', '#children-category', function() {
let childrenId = $('#children-category option:selected').data('category');
if (childrenId != '---') {
$.ajax({
url: '/get_category/grandchildren',
type: 'GET',
data: {
children_id: childrenId,
},
dataType: 'json',
})
.done(function(grandchildren) {
if (grandchildren.length != 0) {
$('#grandchildren-wrapper').remove();
let insertHTML = '';
grandchildren.forEach(function(grandchildren) {
insertHTML += appendOption(grandchildren);
});
appendGrandchidrenBox(insertHTML);
}
})
.fail(function() {
alert('Échec de l'obtention du genre');
});
} else {
$('#grandchildren-wrapper').remove();
}
});
});
$(function() {
function appendOption(category) {
let html = `<option value='${category.id}' data-category='${category.id}'>${category.name}</option>`;
return html;
}
** ◎ Définissez la valeur à envoyer en tant que paramètre. ** **
<option value='${category.id}' data-category='${category.id}'>
** * Les points importants ** Il correspond au paramètre reçu par «①» de «3. Edit controller».
** ◎ Définissez la valeur à afficher dans la boîte de sélection. ** **
${category.name}
function appendChidrenBox(insertHTML) {
let childrenSelectHtml = '';
childrenSelectHtml = `
<div id='children-wrapper'>
<select id='children-category' class='form-control' name='[children_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(childrenSelectHtml);
}
** ◎ Définissez le nom du paramètre
du paramètre créé dans ①
. ** **
name='[children_id]
** ◎ Créez une boîte de sélection de catégorie enfant basée sur les options définies dans ①
. ** **
${insertHTML}
** ◎ Affichez la boîte de sélection de la catégorie enfant. ** **
$('.category-form').append(childrenSelectHtml);
function appendGrandchidrenBox(insertHTML) {
let grandchildrenSelectHtml = '';
grandchildrenSelectHtml = `
<div id='grandchildren-wrapper'>
<select id='grandchildren-category' class='form-control' name='[grandchildren_id]'>
<option value='---' data-category='---'>---</option>
${insertHTML}
</select>
<i class='fas fa-chevron-down'></i>
</div>
`;
$('.category-form').append(grandchildrenSelectHtml);
}
$('#parent-category').on('change', function() {
let parentId = document.getElementById('parent-category').value;
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
.fail(function() {
alert('Échec de l'obtention du genre');
});
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
});
** ◎ Se déclenche lorsque la catégorie parente est sélectionnée. ** **
$('#parent-category').on('change', function() {});
** ◎ Obtenez l'ID de la catégorie parent sélectionnée et attribuez-le à la variable. ** **
let parentId = document.getElementById('parent-category').value;
** ◎ Si la catégorie parente n'est pas la valeur par défaut
Définissez l'ID de la catégorie parent obtenue précédemment dans le paramètre (parent_id),
Exécutez l'action get_category_children
de manière asynchrone. ** **
if (parentId != '---') {
$.ajax({
url: '/get_category/children',
type: 'GET',
data: {
parent_id: parentId,
},
dataType: 'json',
})
** ◎ Si la communication Ajax réussit, créez une boîte de sélection pour la catégorie enfant. De plus, si la catégorie parente est modifiée alors que les cases de sélection sous la catégorie enfant sont déjà affichées, Supprimez les cases de sélection sous la catégorie enfant et recréez les cases de sélection pour les catégories enfants. ** **
.done(function(children) {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
let insertHTML = '';
children.forEach(function(children) {
insertHTML += appendOption(children);
});
appendChidrenBox(insertHTML);
})
** ◎ Si la communication asynchrone échoue, une alerte s'affiche. ** **
.fail(function() {
alert('Échec de l'obtention du genre');
});
** ◎ Si la catégorie parente est la valeur initiale, supprimez la catégorie enfant et ci-dessous. ** **
} else {
$('#children-wrapper').remove();
$('#grandchildren-wrapper').remove();
}
③
)$('.category-form').on('change', '#children-category', function() {
let childrenId = $('#children-category option:selected').data('category');
if (childrenId != '---') {
$.ajax({
url: '/get_category/grandchildren',
type: 'GET',
data: {
children_id: childrenId,
},
dataType: 'json',
})
.done(function(grandchildren) {
if (grandchildren.length != 0) {
$('#grandchildren-wrapper').remove();
let insertHTML = '';
grandchildren.forEach(function(grandchildren) {
insertHTML += appendOption(grandchildren);
});
appendGrandchidrenBox(insertHTML);
}
})
.fail(function() {
alert('Échec de l'obtention du genre');
});
} else {
$('#grandchildren-wrapper').remove();
}
});
** ◎ Certaines catégories n'ont pas de catégories de petits-enfants, des conditions sont donc données. (Ajoutez des conditions aux catégories enfants si nécessaire) **
if (grandchildren.length != 0)
Si vous ne désactivez pas turbolinks
, la boîte de sélection ne fonctionnera pas de manière asynchrone, alors assurez-vous de la désactiver.
Comment désactiver les turbolinks
Implémentation de la fonction de catégorie multicouche (formulaire d'édition)
Recommended Posts