[JAVA] [Rails] Affichage des données de structure à plusieurs niveaux à l'aide de la boîte de sélection

Contexte

Je suis étudiant dans une certaine école de programmation. Beaucoup d'entre vous le savent peut-être, car nous avons implémenté la catégorie exposition avec ajax lors de la création du "Furima Clone Site", je voudrais donc l'organiser et organiser mon propre esprit.

De plus, le paramètre de catégorie utilise une gemme appelée «ascendance». Pour cet article, il est supposé que la catégorie a été définie.

Image complète

category.gif

code

haml:Vue(items.new.html.haml)


.form-title
  =f.label "Catégorie"
  .form-title__required
    %étiquette requise
.form-input-select
  = f.select :category, @category_parent_array, {}, {class: 'listing-select-wrapper__box--select', id: 'parent_category'}
.listing-product-detail__category

«Cette fois, seules les trois dernières lignes sont importantes. D'autres sont gratuits.

Contrôleur (articles_controller.rb)


  def new
    @category_parent_array = ["---"]
    Category.where(ancestry: nil).each do |parent|
      @category_parent_array << parent.name
    end
  end

  def get_category_children
    @category_children = Category.find_by(name: "#{params[:parent_name]}", ancestry: nil).children
  end

  def get_category_grandchildren
    @category_grandchildren = Category.find("#{params[:child_id]}").children
  end

Si vous regardez la démo, vous pouvez voir que les catégories sont affichées en trois étapes. ・ Le premier affichage est nouveau ・ Le deuxième affichage est get_category_children ・ Le troisième écran est get_category_grandchildren Il est devenu.

La partie compliquée est-elle le nouveau code? Vous affectez un tableau ** qui contient uniquement ** "---" à @category_parent_array. Dans chaque instruction de la ligne suivante, chaque catégorie est affectée ** au ** tableau de @category_parent_array défini précédemment. Pour (ascendance: néant), veuillez vérifier les données enregistrées après avoir défini la catégorie avec «ascendance». Vous pouvez voir le sens.

** La description dans les deuxième et troisième paragraphes est traitée par ajax **, donc les actions sont séparées. params [: parent_name] et params [: child_id] sont les valeurs qui volent de JavaScript en ajax. N'oubliez pas que nous le configurerons plus tard.

routes.rb


 resources :items do
    collection do
      get 'get_category_children', defaults: { format: 'json' }
      get 'get_category_grandchildren', defaults: { format: 'json' }
    end
  end

J'ai défini les ** deux actions pour ajax ** qui sont sorties plus tôt sur le contrôleur. Il est imbriqué dans des éléments. Pour expliquer brièvement la collection, le membre ** a un ** id dans le routage, et la collection ** n'en a pas. Cette fois, c'est une collection ** car vous n'avez pas besoin de spécifier le ** "individual (id)".

Le contrôleur ** renvoie essentiellement le processus à la vue **, Si les valeurs par défaut: {format: 'json'} est défini, ** retourne le traitement au fichier json par défaut **. (Il n'est plus nécessaire d'utiliser respond_to sur le contrôleur pour distribuer le fichier json.)

ruby:get_category_children.json.jbuilder


json.array! @category_children do |child|
  json.id child.id
  json.name child.name
end

ruby:get_category_grandchildren.json.jbuilder


json.array! @category_grandchildren do |grandchild|
  json.id grandchild.id
  json.name grandchild.name
end

Ne vous méprenez pas sur l'emplacement du fichier! !! Stocker au même emplacement que la vue.

Si vous effectuez le traitement d'action des deuxième et troisième paragraphes avec le contrôleur, vous passerez à ce fichier json. (Vous l'avez défini plus tôt dans routes.rb.) Vous convertissez ici les variables définies dans le contrôleur en données pour ajax.

À propos, ** json.array! ** est défini lors de la réception de données au format tableau du contrôleur.

Le flux de traitement ajax est ** Affichage (sélection de catégorie) -> JavaScript (feu) -> Contrôleur (traitement) -> json.jbuilder (conversion de données) -> JavaScript (traitement) -> Affichage ** Répétez (je reconnais).

Enfin, JavaScript est là.

JS(items.js)


$(function)(){

  //Sélectionnez les choix de boîte pour les catégories enfants et petits-enfants
  function appendOption(category){
    //value="${category.name}"Pour, catégorie en fonction de la façon de prendre la valeur du paramètre fort.Je pense que c'est peut-être id.
    var html = `<option value="${category.name}" datacategory="${category.id}">${category.name}</option>`;
    return html;
  }

  //Créer une vue d'une catégorie enfant
  function appendChildrenBox(insertHTML){
    var childSelectHtml = '';
    childSelectHtml = `<div class='listing-select-wrapper__added' id= 'children_wrapper'>
                        <div class='listing-select-wrapper__box'>
                          <select class="listing-select-wrapper__box--select" id="child_category" name="category_id">
                            <option value="---" data-category="---">---</option>
                            ${insertHTML}
                          <select>
                        </div>
                      </div>`;
    $('.listing-product-detail__category').append(childSelectHtml);
  }

 //Créer une vue de la catégorie des petits-enfants
  function appendGrandchildrenBox(insertHTML){
    var grandchildSelectHtml = '';
    grandchildSelectHtml = `<div class='listing-select-wrapper__added' id= 'grandchildren_wrapper'>
                              <div class='listing-select-wrapper__box'>
                                <select class="listing-select-wrapper__box--select" id="grandchild_category" name="category_id">
                                  <option value="---" data-category="---">---</option>
                                  ${insertHTML}
                                </select>
                              </div>
                            </div>`;
    $('.listing-product-detail__category').append(grandchildSelectHtml);
  }

  //Traitement lorsque la catégorie parente est sélectionnée (affichage des catégories enfants)
  $("#parent_category").on('change', function(){
    //Obtenir la valeur de la catégorie parent sélectionnée
    var parentCategory = document.getElementById('parent_category').value;
    //La catégorie parent sélectionnée est"---"Faux si laissé (par défaut), vrai si changé
    if (parentCategory != "---"){
      $.ajax({
        url: 'get_category_children',
        type: 'GET',
        //Il s'agit de la valeur à envoyer au contrôleur.
        data: { parent_name: parentCategory },
        dataType: 'json'
      })
      .done(function(children){
        //Tout d'abord, supprimez les catégories enfants et petits-enfants déjà affichées
        $('#children_wrapper').remove();
        $('#grandchildren_wrapper').remove();
        //Insérez une option de boîte de sélection de catégorie dans une variable appelée insertHTML. (Variables fournies dans le tout premier paragraphe)
        var insertHTML = '';
        children.forEach(function(child){
          insertHTML += appendOption(child);
        });
        //Appel de la vue de la catégorie enfant définie dans le deuxième paragraphe
        appendChildrenBox(insertHTML);
      })
      .fail(function(){
        alert('Échec de l'obtention de la catégorie');
      })
    }else{
      $('#children_wrapper').remove();
      $('#grandchildren_wrapper').remove();
    }
  });
  
  //Traitement lorsqu'une catégorie enfant est sélectionnée (affichage de la catégorie petit-enfant)
  $('.listing-product-detail__category').on('change', '#child_category', function(){
    var childId = $('#child_category option:selected').data('category');
    if (childId != "---"){
      $.ajax({
        url: 'get_category_grandchildren',
        type: 'GET',
        data: { child_id: childId },
        dataType: 'json'
      })
      .done(function(grandchildren){
        if(grandchildren.length != 0) {
          $('#grandchildren_wrapper').remove();
          $('#size_wrapper').remove();
          $('#brand_wrapper').remove();
          var insertHTML = '';
          grandchildren.forEach(function(grandchild){
            insertHTML += appendOption(grandchild);
          });
          appendGrandchildrenBox(insertHTML);
        }
      })
      .fail(function(){
        alert('Échec de l'obtention de la catégorie');
      })
    }else{
      $('#grandchildren_wrapper').remove();
      $('#size_wrapper').remove();
      $('#brand_wrapper').remove();
    }
  });
});

Oui. Je comprends ce que je veux dire. Je suis Esper. Je voudrais vous envoyer les mots pratiques ** Faites de votre mieux **.

C'est trop long, alors ** commentez le code pour expliquer le processus **. Si ce n'est pas facile à comprendre, j'aimerais que vous le vérifiiez.

Merci d'avoir lu l'article long et bâclé jusqu'à la fin. LGTM est obligatoire pour les étudiants du camp XX.

Le site qui a servi de référence

https://qiita.com/ATORA1992/items/bd824f5097caeee09678 @ ATORA1992 (C'était un article très facile à comprendre. Merci !!)

Recommended Posts

[Rails] Affichage des données de structure à plusieurs niveaux à l'aide de la boîte de sélection
Rails6: saisissez les données initiales d'ActionText à l'aide de seed
[Enum] Utilisez des rails enum pour améliorer la lisibilité des données
[Ruby on Rails] Introduction des données initiales
[Rails] Conservation temporaire des données par session
[Rails] Implémentation de la fonction de recherche en utilisant le ransack de gem
[Order method] Définit l'ordre des données dans Rails
[Rails] Implémentation de la fonction d'agrandissement d'image à l'aide de lightbox2
[Rails] Comment utiliser les boîtes de sélection dans Ransack
[Rails] Mise en œuvre du classement des nombres PV à l'aide de l'impressionniste
[Rails] Implémentation du diaporama d'images à l'aide de Bootstrap 3
Afficher et publier les données de structure à plusieurs niveaux par ascendance !! ~ Ajax ~
[Ruby on Rails] Affichage individuel des messages d'erreur
[Rails] Comment afficher les prévisions météo de l'adresse enregistrée en japonais en utilisant OpenWeatherMap
[Rails] Ajout de colonnes / changement de type de données / nom de colonne
[Rails, JS] Comment implémenter l'affichage asynchrone des commentaires
Enregistrer les données d'un fichier Excel à l'aide de Rails Gem Roo
[Android] Affichage des candidats d'entrée à l'aide de la fenêtre contextuelle Liste
J'ai résumé le format d'affichage de la réponse JSON de Rails
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "Préparation"
[Rails] Lorsque vous utilisez ajax, faites attention aux "mesures CSRF".
[Rails] Implémentation de la fonction de catégorie multicouche à l'aide de l'ascendance "seed edition"
Construction d'un environnement d'analyse de données avec Docker (mémorandum personnel)
Essayez d'utiliser l'attribut de requête Ruby on Rails